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定向的調度到某些的節點上了。


免責聲明!

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



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