這應(yīng)該是最全的K8s-Pod調(diào)度策略了
API Server接受客戶端提交Pod對象創(chuàng)建請求后的操作過程中,有一個重要的步驟就是由調(diào)度器程序kube-scheduler從當(dāng)前集群中選擇一個可用的最佳節(jié)點來接收并運行它,通常是默認的調(diào)度器kube-scheduler負責(zé)執(zhí)行此類任務(wù)。
對于每個待創(chuàng)建的Pod對象來說,調(diào)度過程通常分為兩個階段—》過濾—》打分,過濾階段用來過濾掉不符合調(diào)度規(guī)則的Node,打分階段建立在過濾階段之上,為每個符合調(diào)度的Node進行打分,分值越高則被調(diào)度到該Node的機率越大。
Pod調(diào)度策略除了系統(tǒng)默認的kube-scheduler調(diào)度器外還有以下幾種實現(xiàn)方式:
1.nodeName(直接指定Node主機名)
2.nodeSelector (節(jié)點選擇器,為Node打上標(biāo)簽,然后Pod中通過nodeSelector選擇打上標(biāo)簽的Node)
3.污點taint與容忍度tolerations
4.NodeAffinity 節(jié)點親和性
5.PodAffinity Pod親和性
6.PodAntAffinity Pod反親和性
以下幾章節(jié)內(nèi)容主要講解上面幾種調(diào)度策略以及kube-scheduler調(diào)度器的調(diào)度原理。
Pod調(diào)度之kube-scheduler
官方文檔:
https://kubernetes.io/zh/docs/concepts/scheduling-eviction/kube-scheduler/
kube-scheduler調(diào)度介紹
kube-scheduler是Kubernetes 集群的默認調(diào)度器,并且是集群控制面(master)的一部分。對每一個新創(chuàng)建的Pod或者是未被調(diào)度的Pod,kube-scheduler會選擇一個最優(yōu)的Node去運行這個Pod。
然而,Pod內(nèi)的每一個容器對資源都有不同的需求,而且Pod本身也有不同的資源需求。因此,Pod在被調(diào)度到Node上之前,根據(jù)這些特定的資源調(diào)度需求,需要對集群中的Node進行一次過濾。
在一個集群中,滿足一個Pod調(diào)度請求的所有Node稱之為可調(diào)度節(jié)點。如果沒有任何一個Node能滿足Pod的資源請求,那么這個Pod將一直停留在未調(diào)度狀態(tài)直到調(diào)度器能夠找到合適的Node。
調(diào)度器先在集群中找到一個Pod的所有可調(diào)度節(jié)點,然后根據(jù)一系列函數(shù)對這些可調(diào)度節(jié)點打分,然后選出其中得分最高的Node來運行Pod。之后,調(diào)度器將這個調(diào)度決定通知給kube-apiserver,這個過程叫做綁定。
在做調(diào)度決定是需要考慮的因素包括:單獨和整體的資源請求、硬件/軟件/策略限制、親和以及反親和要求、數(shù)據(jù)局域性、負載間的干擾等等。
kube-scheduler 調(diào)度流程
kube-scheduler 給一個 pod 做調(diào)度選擇包含兩個步驟:
1.過濾(Predicates 預(yù)選策略)2.打分(Priorities 優(yōu)選策略)
過濾階段:過濾階段會將所有滿足 Pod 調(diào)度需求的 Node 選出來。例如,PodFitsResources 過濾函數(shù)會檢查候選 Node 的可用資源能否滿足 Pod 的資源請求。在過濾之后,得出一個 Node 列表,里面包含了所有可調(diào)度節(jié)點;通常情況下,這個 Node 列表包含不止一個 Node。如果這個列表是空的,代表這個 Pod 不可調(diào)度。
打分階段:在過濾階段后調(diào)度器會為 Pod 從所有可調(diào)度節(jié)點中選取一個最合適的 Node。根據(jù)當(dāng)前啟用的打分規(guī)則,調(diào)度器會給每一個可調(diào)度節(jié)點進行打分。最后,kube-scheduler 會將 Pod 調(diào)度到得分最高的 Node 上。如果存在多個得分最高的 Node,kube-scheduler 會從中隨機選取一個。
整體流程如下圖所示:

過濾階段
官方文檔:
https://kubernetes.io/docs/reference/scheduling/policies/
在調(diào)度時的過濾階段到底時通過什么規(guī)則來對Node進行過濾的呢?就是通過以下規(guī)則!
1.PodFitsHostPorts:檢查Node上是否不存在當(dāng)前被調(diào)度Pod的端口(如果被調(diào)度Pod用的端口已被占用,則此Node被Pass)。
2.PodFitsHost:檢查Pod是否通過主機名指定了特性的Node (是否在Pod中定義了nodeName)
3.PodFitsResources:檢查Node是否有空閑資源(如CPU和內(nèi)存)以滿足Pod的需求。
4.PodMatchNodeSelector:檢查Pod是否通過節(jié)點選擇器選擇了特定的Node (是否在Pod中定義了nodeSelector)。
5.NoVolumeZoneConflict:檢查Pod請求的卷在Node上是否可用 (不可用的Node被Pass)。
6.NoDiskConflict:根據(jù)Pod請求的卷和已掛載的卷,檢查Pod是否合適于某個Node (例如Pod要掛載/data到容器中,Node上/data/已經(jīng)被其它Pod掛載,那么此Pod則不適合此Node)
7.MaxCSIVolumeCount::決定應(yīng)該附加多少CSI卷,以及是否超過了配置的限制。
8.CheckNodeMemoryPressure:對于內(nèi)存有壓力的Node,則不會被調(diào)度Pod。
9.CheckNodePIDPressure:對于進程ID不足的Node,則不會調(diào)度Pod
10.CheckNodeDiskPressure:對于磁盤存儲已滿或者接近滿的Node,則不會調(diào)度Pod。
11.CheckNodeCondition:Node報告給API Server說自己文件系統(tǒng)不足,網(wǎng)絡(luò)有寫問題或者kubelet還沒有準(zhǔn)備好運行Pods等問題,則不會調(diào)度Pod。
12.PodToleratesNodeTaints:檢查Pod的容忍度是否能承受被打上污點的Node。
13.CheckVolumeBinding:根據(jù)一個Pod并發(fā)流量來評估它是否合適(這適用于結(jié)合型和非結(jié)合型PVCs)。
打分階段
官方文檔:
https://kubernetes.io/docs/reference/scheduling/policies/ 當(dāng)過濾階段執(zhí)行后滿足過濾條件的Node,將進行打分階段。
1.SelectorSpreadPriority:優(yōu)先減少節(jié)點上屬于同一個 Service 或 Replication Controller 的 Pod 數(shù)量
2.InterPodAffinityPriority:優(yōu)先將 Pod 調(diào)度到相同的拓撲上(如同一個節(jié)點、Rack、Zone 等)
3.LeastRequestedPriority:節(jié)點上放置的Pod越多,這些Pod使用的資源越多,這個Node給出的打分就越低,所以優(yōu)先調(diào)度到Pod少及資源使用少的節(jié)點上。
4.MostRequestedPriority:盡量調(diào)度到已經(jīng)使用過的 Node 上,將把計劃的Pods放到運行整個工作負載所需的最小節(jié)點數(shù)量上。
5.RequestedToCapacityRatioPriority:使用默認資源評分函數(shù)形狀創(chuàng)建基于requestedToCapacity的
ResourceAllocationPriority。
6.BalancedResourceAllocation:優(yōu)先平衡各節(jié)點的資源使用。
7.NodePreferAvoidPodsPriority:根據(jù)節(jié)點注釋對節(jié)點進行優(yōu)先級排序,以使用它來提示兩個不同的 Pod 不應(yīng)在同一節(jié)點上運行。
scheduler.alpha.kubernetes.io/preferAvoidPods。
8.NodeAffinityPriority:優(yōu)先調(diào)度到匹配 NodeAffinity (Node親和性調(diào)度)的節(jié)點上。
9.TaintTolerationPriority:優(yōu)先調(diào)度到匹配 TaintToleration (污點) 的節(jié)點上
10.ImageLocalityPriority:盡量將使用大鏡像的容器調(diào)度到已經(jīng)下拉了該鏡像的節(jié)點上。
11.ServiceSpreadingPriority:盡量將同一個 service 的 Pod 分布到不同節(jié)點上,服務(wù)對單個節(jié)點故障更具彈性。
12.EqualPriority:將所有節(jié)點的權(quán)重設(shè)置為 1。
13.EvenPodsSpreadPriority:實現(xiàn)首選pod拓撲擴展約束。
kube-scheduler 調(diào)度示例
默認配置使用的就是kube-scheduler調(diào)度組件,我們下面例子啟動三個Pod,看分別被分配到哪個Node。
1.創(chuàng)建資源配置清單
cat scheduler-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: scheduler-deploy
spec:
replicas: 3
selector:
matchLabels:
app: scheduler-pod
template:
metadata:
labels:
app: scheduler-pod
spec:
containers:
- image: busybox:latest
name: scheduler-pod
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
2.使用kubectl創(chuàng)建資源對象
kubectl apply -f scheduler-pod.yaml
3.查看被kube-scheduler自動調(diào)度的Pod 兩個Pod在Node03上,一個在Node02上
kubectl get pods -o wide | grep scheduler
scheduler-deploy-65d8f9c98-cqdm9 1/1 Running 0 111s 10.244.5.59 k8s-node03 <none> <none>
scheduler-deploy-65d8f9c98-d4t9p 1/1 Running 0 111s 10.244.5.58 k8s-node03 <none> <none>
scheduler-deploy-65d8f9c98-f8xxc 1/1 Running 0 111s 10.244.2.45 k8s-node02 <none> <none>
4.我們查看一下Node資源的使用情況 Node01,可用內(nèi)存2.7G

Node02,可用內(nèi)存5.8G

Node03,可用內(nèi)存5.6G

所以默認的kube-scheduler調(diào)度策略經(jīng)過了過濾和打分后,將以上三個Pod分布在Node2和Node3上。
Pod調(diào)度之nodeName
nodeNamed這種調(diào)度方式比較簡單,我們可以指定Pod在哪臺Node上進行運行,通過spec.nodeName參數(shù)來指定Node主機名稱即可。
1、創(chuàng)建資源配置清單
cat nodeName-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nodename-pod
spec:
#指定該Pod運行在k8s-node02節(jié)點上
nodeName: k8s-node02
containers:
- image: busybox:latest
name: nodename-containers
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
2、創(chuàng)建Pod資源對象
kubectl apply -f nodeName-pod.yaml
3、查看Pod調(diào)度節(jié)點
如下,nodename-pod被綁定在了k8s-node02上
kubectl get pods -o wide | grep name
nodename-pod 1/1 Running 0 25s 10.244.2.46 k8s-node02 <none> <none>
Pod調(diào)度之nodeSelector
nodeSelector用于將Pod調(diào)度到匹配Label的Node上,所以要先給node打上標(biāo)簽,然后在Pod配置清單中選擇指定Node的標(biāo)簽。先給規(guī)劃node用途,然后打標(biāo)簽,例如將兩臺node劃分給不同團隊使用:
為Node添加標(biāo)簽
k8s-node02給開發(fā)團隊用,k8s-node03給大數(shù)據(jù)團隊用
1.添加標(biāo)簽
kubectl get nodes -o wide --show-labels
2.查看標(biāo)簽
kubectl apply -f nodeSelector-pod.yaml
創(chuàng)建資源配置清單
cat nodeSelector-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nodeselector-pod
spec:
nodeSelector: #指定標(biāo)簽選擇器
team: development #label指定開發(fā)團隊的label
containers:
- image: busybox:latest
name: nodeselector-containers
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
創(chuàng)建Pod對象
kubectl apply -f nodeSelector-pod.yaml
查看pod被分配的Node
kubectl get pods -o wide | grep nodeselect
nodeselector-pod 1/1 Running 0 49s 10.244.2.47 k8s-node02 <none> <none>
刪除標(biāo)簽
kubectl label nodes k8s-node02 team-
kubectl label nodes k8s-node03 team-
刪除標(biāo)簽后pod還在正常運行
kubectl get pods -o wide | grep nodeselect
nodeselector-pod 1/1 Running 0 11m 10.244.2.47 k8s-node02 <none> <none>
把Pod刪除然后再次創(chuàng)建Pod
kubectl get pods -o wide | grep nodeselectnodeselector-pod 0/1 Pending 0 55s <none> <none> <none> <none>
會發(fā)現(xiàn)該pod一直在等待中,找不到清單中配置標(biāo)簽的Node
kubectl describe pods/nodeselector-pod | grep -A 10 EventsEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling <unknown> default-scheduler 0/6 nodes are available: 6 node(s) didn't match node selector. Warning FailedScheduling <unknown> default-scheduler 0/6 nodes are available: 6 node(s) didn't match node selector.
事件:6個節(jié)點都不匹配 node selector
kubectl describe pods/nodeselector-pod | grep -A 10 Events
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling <unknown> default-scheduler 0/6 nodes are available: 6 node(s) didn't match node selector.
Warning FailedScheduling <unknown> default-scheduler 0/6 nodes are available: 6 node(s) didn't match node selector.
Pod調(diào)度之污點與容忍
官方文檔:
https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/#example-use-cases
污點(taint)是定義在Node之上的鍵值型的數(shù)據(jù),用于讓節(jié)點拒絕將Pod調(diào)度運行于其上,除非該Pod對象具有接納Node污點的容忍度。而容忍度(tolerations)是定義在Pod對象的鍵值型屬性數(shù)據(jù),用于·配置其可容忍的Node污點,而且調(diào)度器僅能將Pod對象調(diào)度至其能夠容忍該Node污點的Node之上。
如下圖所示:

?Pod-A具備k8s-node01污點的容忍度,所以能夠被調(diào)度器調(diào)度至k8s-node01上。?Pod-A不完全具備k8s-node02污點的容忍度,所以不能被調(diào)度至k8s-node02。?Pod-A雖然具備容忍度,但同樣可以調(diào)度至沒有污點的k8s-node03節(jié)點上。?Pod-B自身沒有容忍度,所以只能被調(diào)度至沒有污點的k8s-node03節(jié)點上。
污點介紹及定義
1.污點類型介紹 污點定義在nodeSpec中,容忍度定義在PodSpec中,他們都是鍵值型數(shù)據(jù),但又都額外支持一個效果(effect)標(biāo)記,語法格式為 “key=value:effect” ,其中key和value的用法及格式與資源注解信息相似,而effect則用于定義對Pod對象的排斥等級,它主要包含以下三種排斥類型。
?NoSchedule :為Node添加污點等級為NoSchedule,除容忍此污點的Pod以外的其它Pod將不再被調(diào)度到本機。
?PreferNoSchedule:為Node添加污點等級為PreferNoSchedule,不能容忍此污點的Pod對象盡量不要調(diào)度到當(dāng)前節(jié)點,如果沒有其它節(jié)點可以供Pod選擇時,也會接受沒有容忍此污點的Pod對象。
?NoExecute:為Node添加污點等級為NoExecute,能容忍此污點的Pod將被調(diào)度到此節(jié)點,而且節(jié)點上現(xiàn)存的Pod對象因節(jié)點使用了NoExceute等級的污點,則現(xiàn)存的Pod將被驅(qū)趕至其它滿足條件的Node(除非現(xiàn)存Pod容忍了當(dāng)前節(jié)點的污點)。
2.Master污點介紹 以kubeadm部署的kubernetes集群,其Master節(jié)點將自動添加污點信息以阻止不能容忍此污點的Pod對象調(diào)度至此節(jié)點,因此用戶可以手動創(chuàng)建Pod來容忍Master的污點。
查看kubernetes集群中master節(jié)點的污點:
kubectl get pods -o wide | grep nodeselectnodeselector-pod 1/1 Running 0 49s 10.244.2.47 k8s-node02 <none> <none>
不過,有些系統(tǒng)級別應(yīng)用,如kube-proxy或者kube-flannel等也是以Pod形式運行在集群上,這些資源在創(chuàng)建時就添加上了相應(yīng)的容忍度以確保他們被 DaemonSet 控制器創(chuàng)建時能夠調(diào)度至 Master 節(jié)點運行一個實例。
查看系統(tǒng)級別Pod的容忍度
kubectl describe pods/etcd-k8s-master01 pods/etcd-k8s-master01 pods/kube-flannel-ds-amd64-2smzp pods/kube-flannel-ds-amd64-2smzp -n kube-system | grep Tolerations
Tolerations: :NoExecute
Tolerations: :NoExecute
Tolerations: :NoSchedule
Tolerations: :NoSchedule
另外,這類Pod是構(gòu)成Kubernetes系統(tǒng)的基礎(chǔ)且關(guān)鍵的組件,它們甚至還定義了更大的容忍度,從下面某kube-flannel實例的容忍度定義來看,它還能容忍那些報告了磁盤壓力或內(nèi)存壓力的節(jié)點,以及未就緒的節(jié)點和不可達的節(jié)點,以確保它們能在任何狀態(tài)下正常調(diào)度至集群節(jié)點上運行。
kubectl describe pods kube-flannel-ds-amd64-2smzp -n kube-system
Tolerations: :NoSchedule
node.kubernetes.io/disk-pressure:NoSchedule
node.kubernetes.io/memory-pressure:NoSchedule
node.kubernetes.io/network-unavailable:NoSchedule
node.kubernetes.io/not-ready:NoExecute
node.kubernetes.io/pid-pressure:NoSchedule
node.kubernetes.io/unreachable:NoExecute
node.kubernetes.io/unschedulable:NoSchedule
Events: <none>
3.定義污點
定義污點語法 kubectl taint nodes <node-name> <key>=<value>:<effect>
node-name:指定需要打污點的Node主機名 key=value:指定污點的鍵值型數(shù)據(jù) effect:為污點的等級
key名稱長度上線為253個字符,可以使用字母或者數(shù)字開頭,支持字母、數(shù)字、連接符、點號、下劃線作為key或者value。value最長是 63個字符。污點通常用于描述具體的部署規(guī)劃,它們的鍵名形式如 node-type、node-role、node-project、node-geo等。
1.添加污點 為k8s-node02添加污點,污點程度為NoSchedule,type=calculate為標(biāo)簽
kubectl taint node k8s-node02 type=calculate:NoSchedule
2.查看污點
kubectl describe nodes k8s-node02 | grep Taints
這樣的話我們創(chuàng)建Pod就不會被調(diào)度到我們打上污點的k8s-node02的節(jié)點上
3.創(chuàng)建Pod資源配置清單 我們創(chuàng)建3個Pod,看看其是否會將Pod調(diào)度到我們打污點Node上
cat taint-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: taint-deploy
spec:
replicas: 3
selector:
matchLabels:
app: taint-pod
template:
metadata:
labels:
app: taint-pod
spec:
containers:
- image: busybox:latest
name: taint-pod
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
2.查看Pod被調(diào)度的Node 下面三個Pod都被調(diào)度到了Node03上,效果可能不是很明顯,我們?yōu)镹ode02打了污點,還有Node01沒有體現(xiàn)出來
kubectl apply -f taint-pod.yaml
kubectl get pods -o wide | grep taint
taint-deploy-748989f6d4-f7rbq 1/1 Running 0 41s 10.244.5.62 k8s-node03 <none> <none>
taint-deploy-748989f6d4-nzwjg 1/1 Running 0 41s 10.244.5.61 k8s-node03 <none> <none>
taint-deploy-748989f6d4-vzzdx 1/1 Running 0 41s 10.244.5.60 k8s-node03 <none> <none>
4.擴容Pod 我們將Pod擴容至9臺,讓Pod分配到Node01節(jié)點,可以直觀的展現(xiàn)污點
kubectl scale --replicas=9 deploy/taint-deploy -n default
kubectl get pods -o wide | grep taint
taint-deploy-748989f6d4-4ls9d 1/1 Running 0 54s 10.244.5.65 k8s-node03 <none> <none>
taint-deploy-748989f6d4-794lh 1/1 Running 0 68s 10.244.5.63 k8s-node03 <none> <none>
taint-deploy-748989f6d4-bwh5p 1/1 Running 0 54s 10.244.5.66 k8s-node03 <none> <none>
taint-deploy-748989f6d4-ctknr 1/1 Running 0 68s 10.244.5.64 k8s-node03 <none> <none>
taint-deploy-748989f6d4-f7rbq 1/1 Running 0 2m27s 10.244.5.62 k8s-node03 <none> <none>
taint-deploy-748989f6d4-hf9sf 1/1 Running 0 68s 10.244.3.51 k8s-node01 <none> <none>
taint-deploy-748989f6d4-nzwjg 1/1 Running 0 2m27s 10.244.5.61 k8s-node03 <none> <none>
taint-deploy-748989f6d4-prg2f 1/1 Running 0 54s 10.244.3.52 k8s-node01 <none> <none>
taint-deploy-748989f6d4-vzzdx 1/1 Running 0 2m27s 10.244.5.60 k8s-node03 <none> <none>
以上調(diào)度了兩臺Pod到Node02,目前Node03和Node01都可以分配到Pod,而被打了污點的Node02無法分配Pod
5.刪除污點 刪除污點之需要指定標(biāo)簽的 key 及污點程度
kubectl taint node k8s-node02 type:NoSchedule-
容忍度介紹及定義
Pod對象的容忍度可以通過其spec.tolerations字段進行添加,根據(jù)使用的操作符不同,主要有兩種可用的形式:
1.容忍度與污點信息完全匹配的等值關(guān)系,使用Equal操作符。2.判斷污點是否存在的匹配方式,使用Exists操作富。
容忍度所用到的參數(shù)tolerations,tolerations參數(shù)下的還有以下幾個二級參數(shù):
?operator:此值被稱為運算符,值可以為[Equal|Exists],Equal表示污點的key是否等于value(默認參數(shù)),Exists只判斷污點的key是否存在,使用該參數(shù)時,不需要定義value。
?effect:指定匹配的污點程度,為空表示匹配所有等級的污點,值可以為 [NoSchedule|PreferNoSchedule|NoExecut]。
?key:指定Node上污點的鍵key。
?value:指定Node上污點的值value。
?tolerationSeconds:用于定于延遲驅(qū)趕當(dāng)前Pod對象的時長,如果設(shè)置為0或者負值系統(tǒng)將立即驅(qū)趕當(dāng)前Pod。(單位為秒)
1. 為Node打上不同的等級污點
kubectl taint nodes k8s-node01 nodes=gpu:NoSchedule
kubectl taint nodes k8s-node02 data=ssd:PreferNoSchedule
kubectl taint nodes k8s-node03 traffic=proxy:NoExecute
2.查看三個Node被打上的污點
kubectl describe nodes k8s-node01 k8s-node02 k8s-node03 | grep Taint
Taints: nodes=gpu:NoSchedule
Taints: data=ssd:PreferNoSchedule
Taints: traffic=proxy:NoExecute
3.創(chuàng)建容忍NoSchedule級別污點的Pod并查看Pod調(diào)度結(jié)果
cat pod-tolerations.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-noschedule
spec:
containers:
- name: gpu-container
image: busybox:latest
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
tolerations:
- key: "nodes" #指定污點的key
operator: "Equal" #Equal值表示我們指定的key必須要等于value
value: "gpu" #指定value
effect: "NoSchedule" #指定污點級別
#調(diào)度結(jié)果如我們期望所致在node01上
kubectl get pods -o wide | grep pod-noschedule
pod-noschedule 1/1 Running 0 58s 10.244.3.62 k8s-node01 <none> <none>
4.創(chuàng)建容忍PreferNoSchedule級別污點的Pod并查看Pod調(diào)度結(jié)果
cat pod-tolerations.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-prefernoschedule
spec:
containers:
- name: ssd-container
image: busybox:latest
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
tolerations:
- key: "data"
operator: "Exists" #Exists參數(shù),只判斷key等于data是否存在,不需要關(guān)心value是什么
effect: "PreferNoSchedule
#調(diào)度結(jié)果如我們期望所致在node02上
kubectl get pods -o wide | grep pod-prefer
pod-prefernoschedule 1/1 Running 0 45s 10.244.2.82 k8s-node02 <none> <none>
5.創(chuàng)建容忍NoExecute級別污點的Pod并查看調(diào)度結(jié)果
apiVersion: v1
kind: Pod
metadata:
name: pod-noexecute
spec:
containers:
- name: proxy-container
image: busybox:latest
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
tolerations:
- key: "traffic"
operator: "Equal"
value: "proxy"
effect: "NoExecute" #指定污點級別
tolerationSeconds: 300 #指定驅(qū)趕當(dāng)前Node上Pod的延遲時間
#調(diào)度結(jié)果在Node03上
kubectl get pods -o wide | grep pod-noexecute
pod-noexecute 1/1 Running 0 24s 10.244.5.89 k8s-node03 <none> <none>
6.創(chuàng)建沒有容忍度的Pod并查看調(diào)度結(jié)果 PreferNoSchedule污點級別為盡量不接受沒有容忍此污點的Pod,如果沒有其它節(jié)點可以供Pod選擇時,也會接受沒有容忍此污點的Pod對象。所以創(chuàng)建一個沒有容忍度的Pod看其調(diào)度結(jié)果。
cat pod-tolerations.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-notolerations
spec:
containers:
- name: notolerations-container
image: busybox:latest
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
#如下,調(diào)度結(jié)果與我們料想一致
kubectl get pods -o wide | grep pod-notolerations
pod-notolerations 1/1 Running 0 29s 10.244.2.83 k8s-node02 <none> <none>
實踐中,若集群中的一組機器專用于為運行非生產(chǎn)典型的容器應(yīng)用而備置,而且它們可能隨時按需上下線,那么就應(yīng)該為其添加污點信息,以確保僅那些能夠容忍此污點的非生產(chǎn)型Pod對象可以調(diào)度到其上,另外,某些有種特殊硬件的節(jié)點需要專用于運行一類有著SSD、或者GPU的設(shè)備,也應(yīng)該為其添加污點信息以排除其它Pod對象。
Pod調(diào)度之節(jié)點親和性調(diào)度
官方文檔:
https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
節(jié)點親和性調(diào)度程序是用來確定Pod對象調(diào)度位置的一組規(guī)則,這些規(guī)則基于節(jié)點上的自定義標(biāo)簽和Pod對象上指定的標(biāo)簽選擇器進行定義。
節(jié)點親和性允許Pod對象定義針對一組可以調(diào)度于其上的節(jié)點的親和性或反親和性,不過,它無法具體到某個特定的節(jié)點。例如將Pod調(diào)度至有著CPU的節(jié)點或者一個可用區(qū)域內(nèi)的節(jié)點之上。定義節(jié)點親和性規(guī)則時有兩種類型的節(jié)點親和性規(guī)則:
1.硬親和性(required):硬親和性實現(xiàn)的是強制性規(guī)則,它是Pod調(diào)度時必須要滿足的規(guī)則,而在不存在滿足規(guī)則的Node時,Pod對象會被置為Pending狀態(tài)。
2.軟親和性(preferred):軟親和性規(guī)則實現(xiàn)的是一種柔性調(diào)度限制,它傾向于將Pod對象運行于某類特定節(jié)點之上,而調(diào)度器也將盡量滿足此需求,但在無法滿足需求時它將退而求其次地選擇一個不匹配規(guī)則的節(jié)點之上。
定義節(jié)點親和性規(guī)則的關(guān)鍵點有兩個:
1.為節(jié)點配置合乎需求的標(biāo)簽。
2.為Pod對象定義合理的標(biāo)簽選擇器,從而能夠基于標(biāo)簽選擇器選擇出符合需求的標(biāo)簽。
不過,如
requiredDuringSchedulingIgnoredDuringExecution和
preferredDuringSchedulingIgnoredDuringExecution名字中的后半段字符串IgnoredDuringExecution隱藏的意義所指,在Pod資源基于節(jié)點親和性規(guī)則調(diào)度至某節(jié)點之后,節(jié)點標(biāo)簽發(fā)生了改變而不在符合此類節(jié)點親和性規(guī)則時,調(diào)度器不會將Pod對象從此節(jié)點移除,因為它僅對新建的Pod對象生效。

幫助文檔:kubectl explain
pods.spec.affinity.nodeAffinity

節(jié)點硬親和性
節(jié)點硬親和性類似于Pod對象使用nodeSelector屬性可以基于節(jié)點標(biāo)簽匹配的方式將Pod對象調(diào)度至某一個節(jié)點之上。不過它僅能基于簡單的等值關(guān)系定義標(biāo)簽選擇器,而nodeAffinity中支持使用matchExpressions屬性構(gòu)建更為復(fù)雜的標(biāo)簽選擇機制。

節(jié)點硬親和性參數(shù)解析:
?nodeSelectorTerms:節(jié)點選擇列表(比nodeSelector高級一點)。
?matchExpressions:按照節(jié)點label列出節(jié)點選擇器列表。(與matchFields是兩種方式,不過結(jié)果是一至)
?matchFields:按照節(jié)點字段列出節(jié)點選擇器列表。(與matchExpressions是兩種方式,不過結(jié)果是一至)
?key:指定要選擇節(jié)點label的key。
?values:指定要選擇節(jié)點label的value,值必須為數(shù)組 ["value"] ,如果操作符為In或者 Notin,value則不能為空,如果操作符為Exists或者DoesNotExist ,value則必須為空[],如果操作符為Gt或Lt,則value必須有單個元素,該元素將被解釋為整數(shù)。
?operator:操作符,指定key與value的關(guān)系。
?In:key與value同時存在,一個key多個value的情況下,value之間就成了邏輯或效果。
?NotIn:label 的值不在某個列表中。
?Exists:只判斷是否存在key,不用關(guān)心value值是什么。
?DoesNotExist:某個 label 不存在。
?Gt:label 的值大于某個值。
?Lt:label 的值小于某個值
1.為Node打上標(biāo)簽
#node01打兩個標(biāo)簽ssd=true及zone=foo
kubectl label node k8s-node01 ssd=true zone=foo
#node02打一個標(biāo)簽zone=foo
kubectl label node k8s-node02 zone=foo
#node03打兩個標(biāo)簽ssd=true zone=bar
kubectl label node k8s-node03 ssd=true zone=bar
2.創(chuàng)建Pod資源配置清單 下面Pod資源清單中,該Pod將被綁定到標(biāo)簽key為zone,value為foo的Node上,符合該規(guī)則有兩個Node,分別是Node01和Node02,下面資源配置清單中只創(chuàng)建了一個Pod,可以來觀察下該Pod會被調(diào)度至Node01還是Node02。
apiVersion: apps/v1
kind: Deployment
metadata:
name: required-nodeaffinity-deploy
labels:
type: required-deploy
spec:
replicas: 3
selector:
matchLabels:
app: required-nodeaffinity-pod
template:
metadata:
labels:
app: required-nodeaffinity-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- { key: zone, operator: In, values: ["foo"] }
containers:
- name: myapp
image: busybox:latest
command: ["/bin/sh", "-c", "tail -f /etc/passwd"]
3.查看Pod被調(diào)度至哪臺Node 如下結(jié)果可以看到三個Pod都被調(diào)度到了Node01上
kubectl apply -f required-nodeAffinity-pod.yaml
kubectl get pods -o wide | grep requ
required-nodeaffinity-deploy-55448998fd-hm9ww 0/1 ContainerCreating 0 7s <none> k8s-node01 <none> <none>
required-nodeaffinity-deploy-55448998fd-pkwph 0/1 ContainerCreating 0 7s <none> k8s-node01 <none> <none>
required-nodeaffinity-deploy-55448998fd-z94v2 0/1 ContainerCreating 0 7s <none> k8s-node01 <none> <none>
4.創(chuàng)建Pod資源清單2 如下value有兩個值,兩個值之間是或關(guān)系,可以調(diào)度到key為zone,values為foo或者bar標(biāo)簽的Node上, 下面配置清單中有兩個key,兩個key之間是與關(guān)系,第二個key在第一個key的基礎(chǔ)上,Node還有有標(biāo)簽key為ssd,values無需關(guān)心,因為使用操作符Exists。下面的配置清單中,只能調(diào)度到標(biāo)簽key為zone,values為foo或者bar以及key為ssd的Node上,滿足此需求的Node有Node01和Node03。
cat required-nodeAffinity-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: required-nodeaffinity-deploy
labels:
type: required-deploy
spec:
replicas: 3
selector:
matchLabels:
app: required-nodeaffinity-pod
template:
metadata:
labels:
app: required-nodeaffinity-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- { key: zone, operator: In, values: ["foo","bar"] } #foo和bar之間是或關(guān)系
- { key: ssd, operator: Exists, values: [] } #兩個matchExpressions之間是與關(guān)系
containers:
- name: myapp
image: busybox:latest
command: ["/bin/sh", "-c", "tail -f /etc/passwd"]
5.查看Pod調(diào)度結(jié)果 如下三個Pod都被調(diào)度在Node03節(jié)點
kubectl apply -f required-nodeAffinity-pod.yaml
kubectl get pods -o wide | grep required-nodeaffinity
required-nodeaffinity-deploy-566678b9d8-c84nd 1/1 Running 0 65s 10.244.5.97 k8s-node03 <none> <none>
required-nodeaffinity-deploy-566678b9d8-pn27p 1/1 Running 0 65s 10.244.5.95 k8s-node03 <none> <none>
required-nodeaffinity-deploy-566678b9d8-x8ttf 1/1 Running 0 65s 10.244.5.96 k8s-node03 <none> <none>
節(jié)點軟親和性
節(jié)點軟親和性為節(jié)點選擇機制提供了一種柔性控邏輯,當(dāng)調(diào)度的Pod對象不再是"必須",而是“應(yīng)該”放置于某些特性節(jié)點之上,當(dāng)條件不滿足時,它也能夠接受編排于其它不符合條件的節(jié)點之上,另外,它還為每種傾向性提供了weight屬性以便用戶定義其優(yōu)先級,取值范圍是1-100,數(shù)字越大優(yōu)先級越高。

節(jié)點軟親和性參數(shù)解析:
?preference:節(jié)點選擇器,與相應(yīng)的權(quán)重相關(guān)聯(lián)。
?weight:在1-100范圍內(nèi),與匹配相應(yīng)的節(jié)點選項相關(guān)聯(lián)的權(quán)重。
?matchExpressions:按照節(jié)點label列出節(jié)點選擇器列表。(與matchFields是兩種方式,不過結(jié)果是一至)
?matchFields:按照節(jié)點字段列出節(jié)點選擇器列表。(與matchExpressions是兩種方式,不過結(jié)果是一至)
?key:指定要選擇節(jié)點label的key。
?values:指定要選擇節(jié)點label的value,值必須為數(shù)組 ["value"] ,如果操作符為In或者 Notin,value則不能為空,如果操作符為Exists或者DoesNotExist ,value則必須為空[""],如果操作符為Gt或Lt,則value必須有單個元素,該元素將被解釋為整數(shù)。
?operator:操作符,指定key與value的關(guān)系。
?In:key與value同時存在,一個key多個value的情況下,value之間就成了邏輯或效果。
?NotIn:label 的值不在某個列表中。
?Exists:只判斷是否存在key,不用關(guān)心value值是什么。
?DoesNotExist:某個 label 不存在。
?Gt:label 的值大于某個值。
?Lt:label 的值小于某個值
1.創(chuàng)建Pod資源配置清單 如下示例中,Pod模版定義了Node軟親和性運行在標(biāo)簽key為zone和values為foo或bar上,以及key為ssd(值無需擔(dān)心是什么)的Node之上,符合以下需求的是Node01和Node03,但是如下第一個條件key為zoo的權(quán)重為60,而key為ssd的為30,所以第一個條件的權(quán)重要比第二個條件的權(quán)重高一倍,我們下面運行了3個Pod,調(diào)度器應(yīng)該會在Node01上分配兩個Pod,Node03上分配1個Pod。
cat preferred-nodeAffinitt-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: preferred-nodeaffinity-deploy
labels:
type: preferred-deploy
spec:
replicas: 3
selector:
matchLabels:
app: preferred-nodeaffinity-pod
template:
metadata:
labels:
app: preferred-nodeaffinity-pod
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 60
preference:
matchExpressions:
- { key: zone, operator: In, values: ["foo","bar"] }
- weight: 30
preference:
matchExpressions:
- { key: ssd, operator: Exists, values: [] }
containers:
- name: myapp
image: busybox:latest
command: ["/bin/sh", "-c", "tail -f /etc/passwd"]
2.查看調(diào)度結(jié)果
kubectl get pods -o wide | grep preferred
preferred-nodeaffinity-deploy-5bf4699fd9-pcxvz 1/1 Running 0 5m32s 10.244.5.98 k8s-node03 <none> <none>
preferred-nodeaffinity-deploy-5bf4699fd9-phm8b 1/1 Running 0 5m32s 10.244.3.106 k8s-node01 <none> <none>
preferred-nodeaffinity-deploy-5bf4699fd9-xf87j 1/1 Running 0 5m32s 10.244.3.105 k8s-node01 <none> <none>
3.創(chuàng)建標(biāo)簽key為app,值為proxy或者web的Pod
cat app_proxy.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-proxy-pod
labels:
app: proxy
spec:
containers:
- name: app-proxy
image: busybox:latest
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
4.查看調(diào)度結(jié)果
kubectl apply -f app_proxy.yaml
#具備標(biāo)簽key為app,values的Pod被調(diào)度到了node03上
kubectl get pods -owide | grep app-proxy
app-proxy-pod 1/1 Running 0 42s 10.244.5.102 k8s-node03 <none> <none>
#如下podAffinity硬親和性調(diào)度也被調(diào)度到此Node
kubectl get pods -owide | grep podaff
podaffinity-required-pod 1/1 Running 0 2m30s 10.244.5.103 k8s-node03 <none> <none>
Pod調(diào)度之Pod親和性調(diào)度
podAffinity介紹
出于高效通信的需求,我們要把幾個Pod對象運行在比較近的位置,例如APP Pod與DB Pod,我們的APP Pod需要連接DB Pod,這個時候就需要把這兩個Pod運行在較近的位置以便于網(wǎng)絡(luò)通信,一般可以按照區(qū)域、機房、地區(qū)等來劃分。像這種類型就屬于Pod的親和性調(diào)度。但是有時候出于安全或者分布式考慮,也有可能將Pod運行在不同區(qū)域、不同機房,這個時候Pod的關(guān)系就是為反親和性。
podAffinity也被分為硬親和性和軟親和性,其原理與Node中的硬親和性及軟親和性一致。
硬親和性(required):硬親和性實現(xiàn)的是強制性規(guī)則,它是Pod調(diào)度時必須要滿足的規(guī)則,而在不存在滿足規(guī)則的Node時,Pod對象會被置為Pending狀態(tài)。
軟親和性(preferred):軟親和性規(guī)則實現(xiàn)的是一種柔性調(diào)度限制,它傾向于將Pod對象運行于某類特定節(jié)點之上,而調(diào)度器也將盡量滿足此需求,但在無法滿足需求時它將退而求其次地選擇一個不匹配規(guī)則的節(jié)點之上。
定義Pod親和性規(guī)則的關(guān)鍵點有兩個:
1.為節(jié)點配置合乎需求的標(biāo)簽。
2.為Pod對象定義合理的標(biāo)簽選擇器labelSelector,從而能夠基于標(biāo)簽選擇器選擇出符合需求的標(biāo)簽。

Pod反親和硬親和性
Pod硬親和性調(diào)度使用
requiredDuringSchedulingIgnoredDuringExecution屬性進行定義,Pod硬親和性使用topologyKey參數(shù)來指定要運行在具備什么樣標(biāo)簽key的Node上,然后再通過labelSelector選擇你想關(guān)聯(lián)Pod的標(biāo)簽,可能有點繞,下面看示例應(yīng)該就明白了。

Pod硬親和性參數(shù)解析:
?labelSelector:標(biāo)簽選擇器?。
?topologyKey:指定要將當(dāng)前創(chuàng)建Pod運行在具備什么樣的Node標(biāo)簽上,通常指定Node標(biāo)簽的Key。
?namespaces:指定labelSelector應(yīng)用于哪個名稱空間,null或空列表表示“此pod的名稱空間”。
?matchExpressions:按照Pod label列出節(jié)點選擇器列表。(與matchLabels是兩種方式,不過結(jié)果是一至)。
?matchLabels:按照節(jié)點字段列出節(jié)點選擇器列表。(與matchExpressions是兩種方式,不過結(jié)果是一至)。
?key:指定要選擇節(jié)點label的key。
?values:指定要選擇節(jié)點label的value,值必須為數(shù)組 ["value"] ,如果操作符為In或者 Notin,value則不能為空,如果操作符為Exists或者DoesNotExist ,value則必須為空[],如果操作符為Gt或Lt,則value必須有單個元素,該元素將被解釋為整數(shù)。
?operator:操作符,指定key與value的關(guān)系。
?In:key與value同時存在,一個key多個value的情況下,value之間就成了邏輯或效果。
?NotIn:label 的值不在某個列表中。
?Exists:只判斷是否存在key,不用關(guān)心value值是什么。
?DoesNotExist:某個 label 不存在。
?Gt:label 的值大于某個值。
?Lt:label 的值小于某個值
1.為Node打上不同地區(qū)的標(biāo)簽 node01標(biāo)簽為beijing node02標(biāo)簽為shanghai node03標(biāo)簽為shenzhen
kubectl label node k8s-node01 zone=beijing
kubectl label node k8s-node02 zone=shanghai
kubectl label node k8s-node03 zone=shenzhen
2.創(chuàng)建資源配置清單 下面清單中,Pod首先會選擇標(biāo)簽key為zone的Node,我們上面做了三個Node標(biāo)簽key都為zone,匹配之后,開始在標(biāo)簽key為zone的Node上尋找標(biāo)簽key為app,values為proxy或者web的Pod,然后與其運行在那臺Node之上。
cat podaffinity-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: podaffinity-required-pod
spec:
containers:
- name: nginx-containers
image: nginx:latest
affinity:
podAffinity:
#硬親和性
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
#選擇標(biāo)簽key為app,values為proxy或者web的Pod,然后與其運行在同一個Node上
- { key: app, operator: In, values: ["proxy","web"] }
#選擇key為zone的Node
topologyKey: zone
3.查看調(diào)度結(jié)果 如下可以看到,三臺Node上沒有標(biāo)簽key為app,values為proxy或者web的Pod,我們采用的是硬親和性,所以該Pod一直為Pending狀態(tài)。
kubectl apply -f podaffinity-pod.yaml
kubectl get pods -o wide | grep podaffinity
podaffinity-required-pod 0/1 Pending 0 3m43s <none> <none> <none> <none>
4.創(chuàng)建標(biāo)簽key為app,值為proxy或者web的Pod
cat app_proxy.yaml
apiVersion: v1
kind: Pod
metadata:
name: app-proxy-pod
labels:
app: proxy
spec:
containers:
- name: app-proxy
image: busybox:latest
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
5.查看調(diào)度結(jié)果
kubectl apply -f app_proxy.yaml
#具備標(biāo)簽key為app,values的Pod被調(diào)度到了node03上
kubectl get pods -owide | grep app-proxy
app-proxy-pod 1/1 Running 0 42s 10.244.5.102 k8s-node03 <none> <none>
#如下podAffinity硬親和性調(diào)度也被調(diào)度到此Node
kubectl get pods -owide | grep podaff
podaffinity-required-pod 1/1 Running 0 2m30s 10.244.5.103 k8s-node03 <none> <none>
Pod軟親和性
Pod軟親和性使用
preferredDuringSchedulingIgnoredDuringExecution屬性進行定義,Pod軟親和性使用podAffinityTerm屬性來挑選Pod標(biāo)簽,當(dāng)調(diào)度的Pod對象不再是”必須”,而是“應(yīng)該”放置于某些特性節(jié)點之上,當(dāng)條件不滿足時,它也能夠接受編排于其它不符合條件的節(jié)點之上,另外,它還為每種傾向性提供了weight屬性以便用戶定義其優(yōu)先級,取值范圍是1-100,數(shù)字越大優(yōu)先級越高。

?Pod軟親和性參數(shù)解析:
?podAffinityTerm:Pod親和性選擇器。
?weight:在1-100范圍內(nèi),與匹配相應(yīng)的節(jié)點選項相關(guān)聯(lián)的權(quán)重。
?labelSelector:標(biāo)簽選擇器。
?matchExpressions:按照Pod label列出節(jié)點選擇器列表。(與matchLabels是兩種方式,不過結(jié)果是一至)。
?matchLabels:按照節(jié)點字段列出節(jié)點選擇器列表。(與matchExpressions是兩種方式,不過結(jié)果是一至)。
?key:指定要選擇節(jié)點label的key。
?values:指定要選擇節(jié)點label的value,值必須為數(shù)組 ["value"] ,如果操作符為In或者 Notin,value則不能為空,如果操作符為Exists或者DoesNotExist ,value則必須為空[],如果操作符為Gt或Lt,則value必須有單個元素,該元素將被解釋為整數(shù)。
?operator:操作符,指定key與value的關(guān)系。
?In:key與value同時存在,一個key多個value的情況下,value之間就成了邏輯或效果
?NotIn:label 的值不在某個列表中。
?Exists:只判斷是否存在key,不用關(guān)心value值是什么。
?DoesNotExist:某個 label 不存在。
?Gt:label 的值大于某個值。
?Lt:label 的值小于某個值
1.創(chuàng)建資源配置清單
下面創(chuàng)建一個Pod軟親和性資源配置清單,定義了兩組親和性判斷機制,一個是選擇cache Pod所在節(jié)點的zone標(biāo)簽,并賦予權(quán)重為80,另一個是選擇db Pod所在的zone標(biāo)簽,權(quán)重為20,調(diào)度器首先會將Pod調(diào)度到具有zone標(biāo)簽key的Node上,然后將多數(shù)Pod調(diào)度到具備標(biāo)簽為app=cache的Pod同節(jié)點,其次調(diào)度到具備標(biāo)簽app=db的Pod同節(jié)點。
如果Node上的Pod都具備app=cache和app=db,那么根據(jù)Pod軟親和性策略,調(diào)度器將退而求其次的將Pod調(diào)度到其它Node,如果甚至連Node都具備標(biāo)簽zone鍵,那么根據(jù)軟親和策略,調(diào)度器還是會退而求其次的將Pod調(diào)度到不存在zone鍵的Node上。
cat podaffinity-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: podaffinity-perferred-pod
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
name: myapp
labels:
app: myapp
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
podAffinityTerm:
labelSelector:
matchExpressions:
- { key: app, operator: In, values: ["cache"] }
topologyKey: zone
- weight: 20
podAffinityTerm:
labelSelector:
matchExpressions:
- { key: app, operator: In, values: ["db"] }
topologyKey: zone
containers:
- name: myapp
image: busybox:latest
command: ["/bin/sh", "-c", "tail -f /etc/passwd" ]
2.查看調(diào)度結(jié)果
#Pod調(diào)度結(jié)果為node01兩個,node03一個
kubectl get pods -o wide | grep podaffinity-perferred-pod
podaffinity-perferred-pod-7cddc8c964-5tfr2 1/1 Running 0 12m 10.244.5.106 k8s-node03 <none> <none>
podaffinity-perferred-pod-7cddc8c964-kqsmk 1/1 Running 0 12m 10.244.3.109 k8s-node01 <none> <none>
podaffinity-perferred-pod-7cddc8c964-wpqqw 1/1 Running 0 12m 10.244.3.110 k8s-node01 <none> <none>
#以下三個Node都具備標(biāo)簽鍵為zone,但是這三個Node上沒有Pod標(biāo)簽為app=cache及app=db,所以上面的調(diào)度策略在選擇Pod標(biāo)簽的時候進行退步才得以將Pod調(diào)度到Node01和Node03
k8sops@k8s-master01:~/manifests/pod$ kubectl get nodes -l zone -L zone
NAME STATUS ROLES AGE VERSION ZONE
k8s-node01 Ready <none> 28d v1.18.2 beijing
k8s-node02 Ready <none> 28d v1.18.2 shanghai
k8s-node03 Ready <none> 29d v1.18.2 shenzhen
Pod調(diào)度之Pod反親和性調(diào)度
podAntiAffinity介紹
Pod反親和性podAntiAffinity用于定義Pod對象的親和約束,Pod反親和性與Pod親和性相反,Pod親和性是將有密切關(guān)聯(lián)的Pod運行到同一平面、同一個區(qū)域或者同一臺機器上,而反親和性是將Pod運行在不同區(qū)域、不同機器上,Pod反親和性調(diào)度一般用于分散同一類應(yīng)用的Pod對象等。
podAntiAffinity也被分為硬親和性和軟親和性,其原理與Node中的硬親和性及軟親和性一致。
硬親和性(required):硬親和性實現(xiàn)的是強制性規(guī)則,它是Pod調(diào)度時必須要滿足的規(guī)則,而在不存在滿足規(guī)則的Node時,Pod對象會被置為Pending狀態(tài)。
軟親和性(preferred):軟親和性規(guī)則實現(xiàn)的是一種柔性調(diào)度限制,它傾向于將Pod對象運行于某類特定節(jié)點之上,而調(diào)度器也將盡量滿足此需求,但在無法滿足需求時它將退而求其次地選擇一個不匹配規(guī)則的節(jié)點之上。
幫助文檔:kubectl explain
pods.spec.affinity.podAntiAffinity

podAntiAffinity示例
1.創(chuàng)建資源配置清單
以下創(chuàng)建了4個Pod,自身標(biāo)簽為app=myapp,使用Pod反親和的硬親和性,需要運行在具備標(biāo)簽key為zone的Node上,然后不運行在具備標(biāo)簽為app=myapp的Pod同臺Node上,我們下面啟動了4個Pod,一共有三個Node,前三個Pod都會被分別調(diào)度到不同的三臺Node上(因為采用的是反親和性,還是硬性,所以相同標(biāo)簽的Pod不會調(diào)度到同一臺Node),最后一個Pod將無家可歸,最后無法調(diào)度。
cat podAntiAffinity-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: podantiaffinity-perferred-pod
spec:
replicas: 4
selector:
matchLabels:
app: myapp
template:
metadata:
name: myapp
labels:
app: myapp
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- { key: app, operator: In, values: ["myapp"] }
topologyKey: zone
containers:
- name: myapp
image: busybox:latest
command: ["/bin/sh", "-c", "tail -f /etc/passwd" ]
2.創(chuàng)建Pod對象
kubectl apply -f podAntiAffinity-deploy.yaml
3.查看調(diào)度結(jié)果
kubectl get pods -L app -l app=myapp -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES APP
podantiaffinity-perferred-pod-6576cf75c8-5bw9f 0/1 Pending 0 80s <none> <none> <none> <none> myapp
podantiaffinity-perferred-pod-6576cf75c8-bxp4k 1/1 Running 0 80s 10.244.2.88 k8s-node02 <none> <none> myapp
podantiaffinity-perferred-pod-6576cf75c8-d2fcm 1/1 Running 0 80s 10.244.5.107 k8s-node03 <none> <none> myapp
podantiaffinity-perferred-pod-6576cf75c8-dghr9 1/1 Running 0 80s 10.244.3.111 k8s-node01 <none> <none> myapp
4.查看Node標(biāo)簽
kubectl get nodes -L zone -l zone
NAME STATUS ROLES AGE VERSION ZONE
k8s-node01 Ready <none> 28d v1.18.2 beijing
k8s-node02 Ready <none> 28d v1.18.2 shanghai
k8s-node03 Ready <none> 29d v1.18.2 shenzhen
文章來源于網(wǎng)絡(luò),侵刪!