1. 程式人生 > >Kubernetes1.6新特性:POD高階排程-親和性/反親和性特性

Kubernetes1.6新特性:POD高階排程-親和性/反親和性特性

(一)  核心概念

Pod是kubernetes中的核心概念,kubernetes對於Pod的管理也就是對Pod生命週期的管理以及對Pod進行排程管理。

Kubernetes早期版本使用系統預設排程器來對Pod進行統一排程管理,在1.2版本中增加了多個排程器特性,多個排程器可以並行排程不同的Pod,並且可以允許使用者自己定義新的排程器並以外掛的方式供kubernetes使用。

在1.6版本中對POD排程進行了增強,這裡稱之為“高階排程”,涉及到多個排程器配置變化、節點親和性/反親和性特性、Pod親和性/反親和性特性、汙點和容忍特性、報告節點問題特性。

在1.6版本這些“高階排程”特性中,多個排程器配置變化、節點親和性/反親和性特性、Pod親和性/反親和性特性、汙點和容忍特性,這四個特性屬於β特性,報告節點問題特性屬於α特性,所以大家在使用的時候應該注意。

(二)  親和性/反親和性介紹

我們先來看看1.6版本中Pod相關的幾個核心結構體:


在1.6版本中,PodSpec結構體中新增了四個屬性,分別是AutomountServiceAccountToken、Affinity、SchedulerName、Tolerations。其中Affinity屬性對應結構體Affinity,負責節點親和性/反親和性特性和Pod親和性/反親和性特性;Tolerations屬性對應結構體Toleration,負責汙點和容忍特性;SchedulerName屬性就是這篇文章要介紹的多個排程器配置變化。其中結構體Affinity和結構體Toleration在1.5版本中已經存在了,但是並不是通過PodSpec結構體中Affinity和Tolerations兩個屬性進行關聯的。

對於1.6中親和性/反親和性相關結構體,可以參考下圖:


其中結構體Affinity負責親和性/反親和性特性,其中有三個屬性,分別是NodeAffinity、PodAffinity和PodAntiAffinity,這三個屬性分別對應節點親和性排程、Pod親和性排程、Pod反親和性排程。從這張結構體圖可以發現,現在是不存在節點反親和性特性的。

我們先來看看1.5版本中,是如何配置親和性/反親和性的:

annotations:

  scheduler.alpha.kubernetes.io/affinity:……

我們在看看現在1.6版本中,是如何配置節點親和性/反親和性的:

spec:

  Affinity:……

通過上面兩個例子可以看出來,多個排程器這個特性從α版本變成β版本後,由原先使用annotations方式定義Pod變成了直接在spec中定義Pod。

1、 節點親和性介紹

節點親和性NodeAffinity在概念上同nodeSelector是一致的。當前有兩種節點親和性型別:

1)       requiredDuringSchedulingIgnoredDuringExecution

2)       preferredDuringSchedulingIgnoredDuringExecution

其中requiredDuringSchedulingIgnoredDuringExecution型別是一個強行要求,表示節點必須滿足條件才能夠部署Pod,而preferredDuringSchedulingIgnoredDuringExecution是一個非強行要求,排程器會嘗試去滿足這個節點親和性條件,但是如果沒有滿足節點親和性條件的節點,那麼就會將Pod部署在其他節點上。

對於“IgnoredDuringExecution”的意思是,當Pod在執行過程中,如果節點屬性改變了,原有正在執行的Pod不滿足NodeAffinity條件了,那麼這個時候Pod還會繼續執行,不會發生變化。以後kubernetes還會考慮增加“RequiredDuringExecution”相關型別,表示如果節點屬性改變了,原有正在執行的Pod不滿足NodeAffinity條件了,那麼這個時候Pod就會逃離到滿足NodeAffinity條件的節點上。

這裡需要注意的是Pod配置中可以配置nodeSelector,在1.6版本中nodeSelector和NodeAffinity特性是同時支援的,但是在kubernetes以後版本中逐漸會使用NodeAffinity特性來替代nodeSelector。

2、 Pod親和性/反親和性介紹

在kubernetes1.4版本中就已經有了Pod親和性和反親和性特性了,在1.6版本中Pod親和性有兩種型別,Pod反親和性也有兩種型別,這兩種型別都是相同的,分別是:

1)       requiredDuringSchedulingIgnoredDuringExecution

2)       preferredDuringSchedulingIgnoredDuringExecution

其中requiredDuringSchedulingIgnoredDuringExecution型別是一個強行要求,表示必須滿足才能夠部署Pod,而preferredDuringSchedulingIgnoredDuringExecution是一個非強行要求,這兩種型別同NodeAffinity中介紹的兩種型別作用是相同的。

這裡需要注意的是在1.6版本中如果明確將AffinityInAnnotations屬性設定成true,那麼還會繼續支援scheduler.alpha.kubernetes.io/affinity這種annotations方式的,但是在kubernetes以後版本中會取消這種使用方式。如果在1.6中沒有明確將AffinityInAnnotations屬性設定成true,那麼是不支援scheduler.alpha.kubernetes.io/affinity這種annotations方式的。在1.6版本中,如果啟用了scheduler.alpha.kubernetes.io/affinity這種annotations方式,那麼如果在Pod的spec中定義了affinity,就按照spec中的affinity定義執行Pod,其他pod按照annotations方式執行。

(三)  配置親和性反親和性使用示例

1)       定義一個Pod,配置使用節點親和性NodeAffinity條件

apiVersion: v1

kind: Pod

metadata:

 name: with-node-affinity

spec:

 affinity:

   nodeAffinity:

     requiredDuringSchedulingIgnoredDuringExecution:

       nodeSelectorTerms:

       - matchExpressions:

         - key: kubernetes.io/e2e-az-name

           operator: In

           values:

           - e2e-az1

           - e2e-az2

     preferredDuringSchedulingIgnoredDuringExecution:

     - weight: 1

       preference:

         matchExpressions:

         - key: another-node-label-key

           operator: In

           values:

           - test

 containers:

  -name: with-node-affinity

    image: gcr.io/google_containers/pause:2.0

在這個例子中,Pod只能部署在標識了kubernetes.io/e2e-az-name的節點上,並且取值要是“e2e-az1”或“e2e-az2”。同時,滿足上面條件的節點,最好也要滿足標識了another-node-label-key,並且取值是“test”。

其中operator的取值包括In、NotIn、Exists、DoesNotExist、Gt和Lt。雖然我們沒有看到節點反親和性,但是通過對operator配置NotIn或DoesNotExist,是可以實現節點反親和性需求的。

如果同時配置了nodeSelector和nodeAffinity,那麼Pod會被部署到同時滿足nodeSelector和nodeAffinity條件的節點上。

如果nodeAffinity配置了多個nodeSelectorTerms條件,那麼只要有一個nodeSelectorTerms條件被滿足就可以。

如果matchExpressions配置了多個條件,那麼所有條件都需要被滿足。

2)       定義一個Pod,配置使用pod親和性/非親和性條件

apiVersion: v1

kind: Pod

metadata:

 name: with-pod-affinity

spec:

 affinity:

   podAffinity:

     requiredDuringSchedulingIgnoredDuringExecution:

     - labelSelector:

         matchExpressions:

         - key: security

           operator: In

            values:

           - S1

       topologyKey: failure-domain.beta.kubernetes.io/zone

   podAntiAffinity:

     preferredDuringSchedulingIgnoredDuringExecution:

     - weight: 100

       podAffinityTerm:

         labelSelector:

           matchExpressions:

           - key: security

              operator: In

              values:

              - S2

         topologyKey: kubernetes.io/hostname

 containers:

  -name: with-pod-affinity

   image: gcr.io/google_containers/pause:2.0

在這個例子中,定義了一個Pod親和性和一個Pod反親和性規則。其中Pod親和性規則是一定要滿足的,Pod反親和性規則是參考滿足的。

Pod親和性規則的含義是:Pod必須部署在一個節點上,這個節點上至少有一個正在執行的Pod,這個Pod的security屬性取值是“S1”,並且要求部署的節點同正在執行的Pod所在節點都在相同的雲服務區域中,也就是“topologyKey:failure-domain.beta.kubernetes.io/zone”。換言之,一旦某個區域出了問題,我們希望這些 Pod 能夠再次遷移到同一個區域。

Pod反親和性規則的含義是,Pod不能部署在一個節點上,這個節點上正在執行的Pod中security屬性取值是“S2”,並且新部署的Pod不能同security屬性取值是“S2”的Pod在相同的主機上,也就是“topologyKey: kubernetes.io/hostname”。

matchExpressions中operator的取值包括In、NotIn、Exists、DoesNotExist、Gt和Lt。topologyKey的取值包括:

1)       kubernetes.io/hostname

2)       failure-domain.beta.kubernetes.io/zone

3)       failure-domain.beta.kubernetes.io/region