kubernetes提供了一種親和性調(diào)度(Affinity)。它在NodeSelector的基礎(chǔ)之上的進(jìn)行了擴(kuò)展烂琴,可以通過(guò)配置的形式误堡,實(shí)現(xiàn)優(yōu)先選擇滿(mǎn)足條件的Node進(jìn)行調(diào)度铆农,如果沒(méi)有,也可以調(diào)度到不滿(mǎn)足條件的節(jié)點(diǎn)上顶掉,使調(diào)度更加靈活草娜。
Affinity主要分為三類(lèi):
- nodeAffinity(node親和性): 以node為目標(biāo),解決pod可以調(diào)度到哪些node的問(wèn)題
- podAffinity(pod親和性) : 以pod為目標(biāo)痒筒,解決pod可以和哪些已存在的pod部署在同一個(gè)拓?fù)溆蛑械膯?wèn)題
- podAntiAffinity(pod反親和性) : 以pod為目標(biāo)驱还,解決pod不能和哪些已存在pod部署在同一個(gè)拓?fù)溆蛑械膯?wèn)題
首先我們先看下nodeAffinity,同樣我們舉個(gè)例子凸克,方便理解
nodeAffinity
首先創(chuàng)建pod.yaml
這里使用的是 requiredDuringSchedulingIgnoredDuringExecution
硬相關(guān),沒(méi)有匹配到闷沥,則返回失敗
apiVersion: v1
kind: Pod
metadata:
name: nodeaffinity #pod名稱(chēng)
namespace: dev
spec:
containers:
- name: nginx
image: nginx: latest
affinity: #親和性設(shè)置
nodeAffinity: #設(shè)置node親和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
nodeSelectorTerms:
- matchExpressions: # 匹配env的值在["aa","bb"]中的標(biāo)簽
- key: nodeenv
operator: In
values: ["aa","bb"]
生成yaml對(duì)應(yīng)的pod
# 創(chuàng)建pod
[root@k8s-master01 ~]# kubectl create -f pod.yaml
pod/nodeaffinity created
# 查看pod狀態(tài) (運(yùn)行失斘健)
[root@k8s-master01 ~]# kubectl get pods nodeaffinity -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE ......
nodeaffinity 0/1 Pending 0 6s <none> <none> ......
# 查看Pod的詳情
# 發(fā)現(xiàn)調(diào)度失敗,提示node選擇失敗
[root@k8s-master01 ~]# kubectl describe pod nodeaffinity -n dev
......
#接下來(lái)舆逃,停止pod
[root@k8s-master01 ~]# kubectl delete -f pod.yaml
pod "nodeaffinity" deleted
# 修改文件蚂维,將values: ["aa","bb"]------> ["pro","pod"]
[root@k8s-master01 ~]# vim pod.yaml
# 再次啟動(dòng)
[root@k8s-master01 ~]# kubectl create -f pod.yaml
pod/nodeaffinity created
# 此時(shí)查看,發(fā)現(xiàn)調(diào)度成功路狮,已經(jīng)將pod調(diào)度到了node1上
[root@k8s-master01 ~]# kubectl get pods nodeaffinity -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE ......
nodeaffinity 1/1 Running 0 11s 10.200.1.9 node1 ......
接下來(lái)再演示一下requiredDuringSchedulingIgnoredDuringExecution
同樣先創(chuàng)建pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nodeaffinity
namespace: dev
spec:
containers:
- name: nginx
image: nginx:latest
affinity: #親和性設(shè)置
nodeAffinity: #設(shè)置node親和性
preferredDuringSchedulingIgnoredDuringExecution: # 軟限制 優(yōu)先匹配設(shè)定的規(guī)則虫啥,沒(méi)有匹配也可以運(yùn)行
- weight: 1
preference:
matchExpressions: # 匹配env的值在["dev","test"]中的標(biāo)簽(當(dāng)前環(huán)境沒(méi)有)
- key: nodeenv
operator: In
values: ["dev","test"]
# 創(chuàng)建pod
[root@k8s-master01 ~]# kubectl create -f pod.yaml
pod/nodeaffinity created
# 查看pod狀態(tài) (運(yùn)行成功),即使沒(méi)有這樣標(biāo)簽的node
[root@k8s-master01 ~]# kubectl get pod nodeaffinity -n dev
NAME READY STATUS RESTARTS AGE
nodeaffinity 1/1 Running 0 40s
NodeAffinity規(guī)則設(shè)置的注意事項(xiàng):
1 如果同時(shí)定義了nodeSelector和nodeAffinity奄妨,那么必須兩個(gè)條件都得到滿(mǎn)足涂籽,Pod才能運(yùn)行在指定的Node上
2 如果nodeAffinity指定了多個(gè)nodeSelectorTerms,那么只需要其中一個(gè)能夠匹配成功即可
3 如果一個(gè)nodeSelectorTerms中有多個(gè)matchExpressions 砸抛,則一個(gè)節(jié)點(diǎn)必須滿(mǎn)足所有的才能匹配成功
4 如果一個(gè)pod所在的Node在Pod運(yùn)行期間其標(biāo)簽發(fā)生了改變评雌,不再符合該P(yáng)od的節(jié)點(diǎn)親和性需求,則系統(tǒng)將忽略此變化
PodAffinity
PodAffinity主要實(shí)現(xiàn)以運(yùn)行的Pod為參照直焙,實(shí)現(xiàn)讓新創(chuàng)建的Pod跟參照pod在一個(gè)區(qū)域的功能,前面是以Node為參照景东。
同樣首先創(chuàng)建一個(gè)參照Pod yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-target
namespace: dev
labels:
podenv: pro #設(shè)置標(biāo)簽
spec:
containers:
- name: nginx
image: nginx: latest
nodeName: node1 # 將目標(biāo)pod名確指定到node1上
# 啟動(dòng)目標(biāo)pod
[root@k8s-master01 ~]# kubectl create -f pod-target.yaml
pod/pod-target created
# 查看pod狀況
[root@k8s-master01 ~]# kubectl get pods pod-target -n dev
NAME READY STATUS RESTARTS AGE
pod-target 1/1 Running 0 4s
2)創(chuàng)建pod-podaffinity-required.yaml,內(nèi)容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-required
namespace: dev
spec:
containers:
- name: nginx
image: nginx: latest
affinity: #親和性設(shè)置
podAffinity: #設(shè)置pod親和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬限制 同樣還有軟連接效果類(lèi)似奔誓,只是即使未匹配依然可以運(yùn)行
- labelSelector:
matchExpressions: # 匹配env的值在["aa","bb"]中的標(biāo)簽
- key: podenv
operator: In
values: ["aa","bb"]
topologyKey: kubernetes.io/hostname
# 啟動(dòng)pod
[root@k8s-master01 ~]# kubectl create -f pod-podaffinity-required.yaml
pod/pod-podaffinity-required created
# 查看pod狀態(tài)斤吐,發(fā)現(xiàn)未運(yùn)行
[root@k8s-master01 ~]# kubectl get pods pod-podaffinity-required -n dev
NAME READY STATUS RESTARTS AGE
pod-podaffinity-required 0/1 Pending 0 9s
# 查看詳細(xì)信息
[root@k8s-master01 ~]# kubectl describe pods pod-podaffinity-required -n dev
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling <unknown> default-scheduler 0/3 nodes are available: 2 node(s) didn't match pod affinity rules, 1 node(s) had taints that the pod didn't tolerate.
# 接下來(lái)修改 values: ["aa","bb"]----->values:["pro","pod"]
[root@k8s-master01 ~]# vim pod-podaffinity-required.yaml
# 然后重新創(chuàng)建pod,查看效果
[root@k8s-master01 ~]# kubectl delete -f pod-podaffinity-required.yaml
pod "pod-podaffinity-required" deleted
[root@k8s-master01 ~]# kubectl create -f pod-podaffinity-required.yaml
pod/pod-podaffinity-required created
# 發(fā)現(xiàn)此時(shí)Pod運(yùn)行正常
[root@k8s-master01 ~]# kubectl get pods pod-podaffinity-required -n dev
NAME READY STATUS RESTARTS AGE LABELS
pod-podaffinity-required 1/1 Running 0 6s <none>
podAntiAffinity
這個(gè)與podAAffinity 使用方式完全一致厨喂,只是效果相反和措,不再贅述。