一、前言
??在上一篇文章里,我們了解了 Pod 中的nodeName和nodeSelector這兩個屬性,通過它們能夠指定 Pod 調度到哪個 Node 上。今天,我們將進一步深入探索 Pod 相關知識。這部分內容不僅信息量較大,理解起來也有一定難度,如果在學習過程中感覺吃力,建議大家反復研讀,以便更好地掌握。
二、親和性
??在 Kubernetes 的 Pod 調度場景中,盡管我們可以借助nodeName和nodeSelector指定 Pod 的調度節點,但它們存在明顯的局限性。nodeName依賴節點名稱進行調度,nodeSelector則基于節點標簽來確定調度目標,二者都不夠靈活,擴展性也欠佳。那么,是否存在其他更豐富的屬性能夠助力 Pod 調度呢?例如,能否依據 CPU、內存等資源屬性來決定 Pod 的部署節點?作為強大的容器編排工具,Kubernetes 顯然考慮到了這一需求,接下來我們將深入學習的 “親和性”,便是解決這一問題的關鍵。
??親和性同樣用于 Pod 的節點調度,與nodeSelector有一定相似之處,但親和性的優勢更為顯著。它支持定義多個調度規則,還能為這些規則設定優先級,從而實現更精細的調度控制。親和性主要分為節點親和性和 Pod 親和性。簡單來講,親和性就是一組預先設定的規則,其作用是明確告知 Kubernetes 該如何調度 Pod。
??其中,節點親和性又細分為軟親和性和硬親和性。軟親和性是一種較為靈活的調度策略,當多個節點都滿足設定條件時,它會優先選擇優先級更高的節點;若所有節點都無法完全滿足條件,Pod 依然可以被調度到其他相對合適的節點。打個比方,這就像是你向 Kubernetes 提出請求:“請幫我把 Pod 調度到某個節點上,這個節點最好能滿足條件 1 和條件 2,如果實在沒有完全符合的,那就找一個最接近要求的節點部署吧。”
??而硬親和性則截然不同,它是一種嚴格的調度策略。只有當節點完全滿足設定的所有條件時,Pod 才會被調度到該節點;若不存在任何滿足條件的節點,Pod 將無法運行,這正如成語 “寧缺毋濫” 所表達的含義。
軟親和性例子:
女生A和媒婆說:我要找個男朋友,條件1:身高1米8;條件2:有車有房,如果兩者都不滿足那么性格好就行了。
硬親和性例子:我要個男朋友條件1:身高1米8;條件2:有車有房,這兩個條件缺一不可,否則我寧可單身!
1、先查看一下描述
kubectl explain pods.spec.affinity
親和性總共有3個字段:節點親和性、pod親和性、pod反親和性
- nodeAffinity(節點親和性):通過標簽選擇器和表達式來約束Pod
- podAffinity(pod親和性):用于指定Pod應該被部署到符合某些條件的Pod所在的Node:例如我們將多個業務關聯性高的Pod部署在同一個節點。
- podAntiAffinity(Pod反親和性):用于指定Pod應該避免部署到符合某些條件的Pod所在的Node,場景:例如避免把相似的Pod都部署到同一個Node,從而可能產生單點故障。
三、節點親和性(nodeAffinity)
1、解釋
kubectl explain pods.spec.affinity
這里有兩個字段
- preferredDuringSchedulingIgnoredDuringExecution :軟親和性
它是一種建議性的規則,Kubernetes 調度器會盡量依據此規則來調度 Pod 到符合條件的節點上,但并非強制要求。若不存在滿足規則的節點,Pod 依然可以被調度到其他節點。此規則在調度階段起作用,調度器會優先考慮將 Pod 調度到滿足軟親和性規則的節點上。而在 Pod 運行期間,一旦節點的標簽發生變化,導致不再符合軟親和性規則,Pod 不會被驅逐。
- requiredDuringSchedulingIgnoredDuringExecution:硬親和性
和軟親和性不同,硬親和性是一種強制的規則,要求調度器在調度的時候必須滿足一定的規則,否則將不會進行調度,pod會一直處于pending狀態。同時運行期間如果節點的標簽發生變化導致不符合規則,Pod會被驅逐。
2、實操
我們現在有兩個節點,分別是node2和node3,其中node2包含標簽cpu=high ,而node3包含標簽cpu=low,我們用這個標簽來測試節點親和性。
1、軟親和性
(1)我們先測試軟親和性,即期望pod會被調度到cpu=high的節點,資源清單如下
apiVersion: v1
kind: Pod
metadata:name: buybox-pod
spec:containers:- name: buybox-containerimage: buybox:1.28imagePullPolicy: IfNotPresentaffinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100preference:matchExpressions:- key: cpuoperator: Invalues:- high
接下來我們使用命令 apply -f busybox.yaml 來創建這個pod,預期的效果是會被調度到node2節點,結果如下
可以看到和我們的預期一樣,Pod被調度到了node2節點上。
(2)我們修改一下資源清單,寫一個不存在的標簽值看是否能夠調度。預期結果:也能正常調度只不過會在node2和node3中隨機選擇。
apiVersion: v1
kind: Pod
metadata:name: buybox-pod
spec:containers:- name: buybox-containerimage: buybox:1.28imagePullPolicy: IfNotPresentaffinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100preference:matchExpressions:- key: cpuoperator: Invalues:- best
調度結果:node3 (不用管這里的狀態是 ErrImagePull,這個是筆者網絡問題導致拉取鏡像有問題,但是和調度沒關系)
(3)小結
案例1 | 預期結果 | 實際結果 |
---|---|---|
正常情況,標簽cpu=high | 節點2 | 節點2 |
都不滿足,標簽cpu=best | 節點2或者節點3 | 節點3 |
小結:軟親和性是一種建議,即如果滿足要求就選擇某個節點,若不存在滿足規則的節點,Pod 依然可以被調度到其他節點。
1、硬親和性
還是剛才的案例,我們把軟親和性換成硬親和性
(1)cpu=high 我們預期是調度到node2
apiVersion: v1
kind: Pod
metadata:name: buybox-pod
spec:containers:- name: buybox-containerimage: buyboxports:- containerPort: 80affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: cpuoperator: Invalues:- high
結果調度了node2,符合預期
(2)我們修改規則,將values改成不存的值,預期無法調度到任何一個節點
apiVersion: v1
kind: Pod
metadata:name: buybox-pod
spec:containers:- name: buybox-containerimage: buyboxports:- containerPort: 80affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: cpuoperator: Invalues:- best
結果如下
可以看到狀態一直處于Pending狀態,查看一下pod詳細信息,使用命令 kubectl describe pods buybox-pod
錯誤信息:
Warning FailedScheduling 12s (x3 over 89s) default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn’t tolerate, 2 node(s) didn’t match Pod’s node affinity.
調度失敗了,因為3個節點都不滿足親和性條件。
小結:
案例1 | 預期結果 | 實際結果 |
---|---|---|
正常情況,標簽cpu=high | 節點2 | 節點2 |
都不滿足,標簽cpu=best | 無法調度 | 無法調度 |
四、總結
本文聚焦 Kubernetes 的節點親和性。在 Pod 調度中,以往的 nodeName 和 nodeSelector 存在局限,親和性則更為強大,其中節點親和性包含軟、硬親和性。
軟親和性是建議性規則。測試時,期望調度到cpu=high的節點,Pod 成功被調度到 node2;設置不存在的標簽值,Pod 也能在現有節點隨機調度,如被調度到 node3,說明無滿足節點時 Pod 仍可調度。硬親和性requiredDuringSchedulingIgnoredDuringExecution是強制規則。同樣的測試場景下,要求調度到cpu=high的節點,Pod 被調度到 node2;設置不存在的標簽值,Pod 處于 Pending 狀態,調度失敗,表明不滿足條件時 Pod 無法調度。
學習節點親和性的軟、硬親和性,有助于精準控制 Pod 部署,提升集群資源利用率和應用穩定性,為 Kubernetes 復雜應用部署管理筑牢基礎。下一篇我們將繼續學習親和性,希望對你有所幫助