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