1. 程式人生 > 其它 >k8s中,什麼是pod親和性、反親和性,以及如何在k8s中進行應用?

k8s中,什麼是pod親和性、反親和性,以及如何在k8s中進行應用?

1、概述

我們在現實的環境中,會有這些的場景,比如,需要根據節點上執行的pod來決定,這個pod是否要被排程到該節點上。

這,就涉及到了k8s中的一個概念,pod親和性、pod反親和性,這個和節點親和性很相似,就是根據節點上執行的標籤,而部是節點的標籤進行判斷和排程。

更重要的是,pod親和性,主要是在排程的時候的一個作用。

同時,也實現了一個功能:就是通過另外的一種方式來限制pod所能執行的節點。

接下來,我們通過一個實際的例子,看下,如何在k8s中使用pod親和性、反親和性,這個特性。

2、pod親和性排程策略

那,我們知道,所謂的親和也好、互斥也好,都是針對於某個目標來說的,那,我們就先建立一個參照的pod

  • 建立一個參照的pod

通過以下的yaml配置檔案,建立參考pod

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-flag
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        security: S1
        app: nginx
    spec:
      containers:
      - image: 172.20.58.152/middleware/nginx:1.21.4
        name: nginx

檢視建立好的pod

[root@nccztsjb-node-23 ~]# kubectl get pod -o wide --show-labels
NAME                        READY   STATUS    RESTARTS   AGE     IP               NODE               NOMINATED NODE   READINESS GATES   LABELS
pod-flag-7d4d89f9c9-whf22   1/1     Running   0          3m19s   172.39.157.244   nccztsjb-node-24   <none>           <none>            app=nginx,pod-template-hash=7d4d89f9c9,security=S1
[root@nccztsjb-node-23 ~]# 

已經建立好了這個pod,執行在節點nccztsjb-node-24上,並且都帶上了對應的標籤。

OK,我們已經建立好了這個參照pod,後續的例子,將使用這個pod作為親和與互斥的目標pod.

  • pod的親和性排程

現在建立第2個pod,通過親和性標籤,security=S1來定位之前的參考pod

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-affinity
spec:
  selector:
    matchLabels:
      app: pod-affinity
  replicas: 1
  template:
    metadata:
      labels:
        app: pod-affinity
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: security
                operator: In
                values:
                - S1
            topologyKey: kubernetes.io/hostname        
      containers:
      - image: 172.20.58.152/middleware/nginx:1.21.4
        name: pod-affinity
EOF

檢視建立的pod

[root@nccztsjb-node-23 ~]# kubectl get pod -o wide 
NAME                            READY   STATUS    RESTARTS   AGE   IP               NODE               NOMINATED NODE   READINESS GATES
pod-affinity-64b7774db8-vjgs5   1/1     Running   0          8s    172.39.157.247   nccztsjb-node-24   <none>           <none>
pod-flag-7d4d89f9c9-whf22       1/1     Running   0          22h   172.39.157.244   nccztsjb-node-24   <none>           <none>
[root@nccztsjb-node-23 ~]# 

發現,這次發的pod已經和參考pod在一個節點上了。

這裡面有個引數:topologyKey。這個引數主要是用來選擇節點的,通過節點上的key來表示,也就是說,在節點上有這個標籤,然後這個在包含這個key的節點上,有pod包含security=S1這樣的標籤的時候,是要將pod排程到這個節點上來的。

OK,這樣就達到了一個限制pod執行節點上的一個效果。

  • 刪除掉節點的kubernetes.io/hostname,看排程情況

[root@nccztsjb-node-23 ~]# kubectl label node nccztsjb-node-24 kubernetes.io/hostname-
node/nccztsjb-node-24 unlabeled

再次進行pod釋出

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-affinity
spec:
  selector:
    matchLabels:
      app: pod-affinity
  replicas: 1
  template:
    metadata:
      labels:
        app: pod-affinity
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: security
                operator: In
                values:
                - S1
            topologyKey: kubernetes.io/hostname        
      containers:
      - image: 172.20.58.152/middleware/nginx:1.21.4
        name: pod-affinity
EOF
[root@nccztsjb-node-23 ~]# kubectl get pod -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP               NODE               NOMINATED NODE   READINESS GATES
pod-affinity-7d8598689d-2cg5z   0/1     Pending   0          3s    <none>           <none>             <none>           <none>
pod-flag-7d4d89f9c9-whf22       1/1     Running   0          23h   172.39.157.244   nccztsjb-node-24   <none>           <none>
[root@nccztsjb-node-23 ~]# 

發現,pod是處於pending狀態,也就是說,不滿足topologykey中指定的節點的條件。

即親和性、反親和性,首先是找到滿足key的節點,然後再是上面的符合標籤的pod.

3、pod反親和性(互斥性)排程策略

接下來,我們要建立的這個pod,我們不希望它與參考pod執行在同一個主機上。

通過以下的pod建立pod,指定podAntiAffinity

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-antiaffinity
spec:
  selector:
    matchLabels:
      app: pod-antiaffinity
  replicas: 1
  template:
    metadata:
      labels:
        app: pod-antiaffinity
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: security
                operator: In
                values:
                - S1
            topologyKey: kubernetes.io/hostname        
      containers:
      - image: 172.20.58.152/middleware/nginx:1.21.4
        name: pod-antiaffinity

檢視建立的pod

[root@nccztsjb-node-23 ~]# kubectl get pod -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP               NODE               NOMINATED NODE   READINESS GATES
pod-antiaffinity-d57996c54-w67tx   1/1     Running   0          84s   172.39.21.69     nccztsjb-node-25   <none>           <none>
pod-flag-7d4d89f9c9-whf22          1/1     Running   0          26h   172.39.157.244   nccztsjb-node-24   <none>           <none>
[root@nccztsjb-node-23 ~]# 

發現先建的pod沒有和參考pod在一個節點上。

那麼,我們多建立些例項(副本數改成5),看看結果:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pod-antiaffinity
spec:
  selector:
    matchLabels:
      app: pod-antiaffinity
  replicas: 5
  template:
    metadata:
      labels:
        app: pod-antiaffinity
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: security
                operator: In
                values:
                - S1
            topologyKey: kubernetes.io/hostname        
      containers:
      - image: 172.20.58.152/middleware/nginx:1.21.4
        name: pod-antiaffinity

發現,5個副本,沒有一個副本和參考pod在一個節點上的。

OK,這樣通過pod的反親和性設定,就將pod定向的排程到某些的節點上了。