K8S調度之pod親和性


Pod Affinity

通過《K8S調度之節點親和性》,我們知道怎么在調度的時候讓pod靈活的選擇node,但有些時候我們希望調度能夠考慮pod之間的關系,而不只是pod與node的關系。於是在kubernetes 1.4的時候引入了pod affinity。

為什么有這樣的需求呢?舉個例子,我們系統服務 A 和服務 B 盡量部署在同個主機、機房、城市,因為它們網絡溝通比較多;再比如,我們系統數據服務 C 和數據服務 D 盡量分開,因為如果它們分配到一起,然后主機或者機房出了問題,會導致應用完全不可用,如果它們是分開的,應用雖然有影響,但還是可用的。

pod affinity 可以這樣理解:調度的時候選擇(或者不選擇)這樣的節點 N ,這些節點上已經運行了滿足條件 X。條件 X 是一組 label 選擇器,它必須指明作用的 namespace(也可以作用於所有的 namespace),因為 pod 是運行在某個 namespace 中的。

這里的X指的是集群中的節點、機架、區域等概念,通過kubernetes內置節點標簽中的key來進行聲明。這個key的名字為topologyKey,意為表達節點所屬的topology范圍:

  • kubernetes.io/hostname
  • failure-domain.beta.kubernetes.io/zone
  • failure-domain.beta.kubernetes.io/region

和 node affinity 相似,pod affinity 也有 requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution,意義也和之前一樣。如果有使用親和性,在 affinity 下面添加 podAffinity 字段,如果要使用互斥性,在 affinity 下面添加 podAntiAffinity 字段。

先定義一個參照目標pod:

apiVersion: v1
kind: Pod
metadata:
  name: pod-flag
  labels:
    security: "S1"
    app: "nginx"
spec:
  containers:
  - name: nginx
    image: nginx

Pod親和性調度

下面是一個親和性調度的示例

apiVersion: v1
kind: Pod
metadata:
  name: pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: kubernetes.io/hostname
  containers:
  - name: with-pod-affinity
    image: gcr.io/google_containers/pause:2.0

創建后可以看到這個pod與上面那個參照的pod位於同一個node上,另外,如果將這個node上的kubernetes.io/hostname標簽干掉,將會發現pod會一直處於pending狀態,這是因為找不到滿足條件的node了。

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與security=S1的pod為同一個zone,但是不與security=S2的pod為同一個node。

原則上,topologyKey可以使用任何合法的標簽Key賦值,但是出於性能和安全方面的考慮,對topologyKey有如下限制:

  • 在pod親和性和RequiredDuringScheduling的pod互斥性的定義中,不允許使用空的topologyKey
  • 如果admission controller包含了LimitPodHardAntiAffinityTopology,那么針對RequiredDuringScheduling的pod互斥性定義就被限制為kubernetes.io/hostname,要使用自定義的topologyKey,就要改寫或禁用該控制器
  • 在PerferredDuringScheduling類型的Pod互斥性定義中,空的topologyKey會被解釋為kubernetes.io/hostname、failure-domain.beta.kubernetes.io/zone及failure-domain.beta.kubernetes.io/region的組合

podAffinity規則設置的注意事項:

  • 在labelSelector和topologyKey同級,還可以定義namespaces列表,表示匹配哪些namespace里面的pod,默認情況下,會匹配定義的pod所在的namespace,如果定義了這個字段,但是它的值為空,則匹配所有的namespaces。
  • 所有關聯requiredDuringSchedulingIgnoredDuringExecution的matchExpressions全都滿足之后,系統才能將pod調度到某個node上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM