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