概述
在 Kubernetes(K8s)中,Pod 調度親和性(Affinity)是一種高級調度策略,用于控制 Pod 與節點(Node)或其他 Pod 之間的關聯(親和)或反關聯(反親和)關系。通過親和性規則,管理員可以更精細地控制 Pod 的調度行為,滿足業務的拓撲約束、資源局部性、高可用等需求。
親和性主要有兩類
? 節點親和性
? Pod親和性
回到頂部
節點親和性
節點親和性是 Kubernetes 中控制 Pod 調度到特定節點的核心機制,它比傳統的 nodeSelector 更具靈活性,支持更復雜的匹配規則和優先級策略。
節點親和性通過nodeAffinity字段定義,包含requiredDuringSchedulingIgnoredDuringExecution(硬性)和preferredDuringSchedulingIgnoredDuringExecution(軟性)兩種規則。
節點親和性的作用
精準匹配節點標簽
節點親和性通過定義 標簽匹配規則(如節點必須包含 / 不包含某個標簽、標簽值在指定范圍內等),將 Pod 調度到符合條件的節點。
? 硬性規則(requiredDuringScheduling):強制 Pod 只能調度到滿足條件的節點,否則保持 Pending 狀態。
例:將數據庫 Pod 強制調度到標記為 role=database 且 storage=ssd 的節點。
? 軟性規則(preferredDuringScheduling):優先調度到滿足條件的節點,若不滿足則嘗試其他節點(通過權重配置優先級)。
例:優先將 Web 服務 Pod 調度到 region=east 的節點(權重 100),其次調度到 zone=az1 的節點(權重 70)。
精細化控制
替代簡單的 nodeSelector,支持復雜邏輯(如 “節點必須包含 A 標簽且不包含 B 標簽”)。
靈活容錯
軟性規則允許調度器在條件不滿足時 “退而求其次”,避免 Pod 長時間處于 Pending。
資源利用率優化
通過標簽分層(如環境、硬件、地域),實現集群資源的合理分配與負載均衡。
節點親和性實戰-硬性規則匹配
必須滿足條件才能調度,否則 Pod 將處于 Pending 狀態。調度成功后,即使節點標簽變更導致規則不再滿足,Pod 也不會被驅逐。
將 Pod 調度到同時滿足以下條件的節點:
? 標簽 env=prod
? 標簽 disk-type=ssd
? 標簽 cpu-cores > 2
示例:
給node01節點打上標簽
| | | | --- | --- | | | [root@master ~]# kubectl label node node01env=prod disk-type=ssd cpu-cores=3 | | | node/node01 labeled | | | | | |# 查看標簽 | | | [root@master ~]# kubectl describe node node01 | grep Labels -A 5 | | | Labels: beta.kubernetes.io/arch=amd64 | | | beta.kubernetes.io/os=linux | | | cpu-cores=3 | | | disk-type=ssd | | |env=prod | | | kubernetes.io/arch=amd64 |
創建Pod
| | | |---|---| | |[root@master~/affinity]# cat affinity-deploy.yaml | | |apiVersion:apps/v1| | |kind:Deployment| | |metadata:| | |name:nginx-affinity| | |spec:| | |replicas:5| | |selector:| | |matchLabels:| | |app:nginx| | |template:| | |metadata:| | |labels:| | |app:nginx| | |spec:| | |affinity:| | |# 節點親和性 | | |nodeAffinity:| | |# 指定硬性規則 | | |requiredDuringSchedulingIgnoredDuringExecution:| | |# 匹配規則 | | |nodeSelectorTerms:| | |-matchExpressions:| | |-key:env| | |operator:In| | |values:["prod"]| | |-key:disk-type| | |operator:In| | |values:["ssd"]| | |-key:cpu-cores| | |operator:Gt| | |values:["2"] # 注意:values 是字符串列表,內部會轉為數字比較 | | |containers:| | |-name:nginx| | |image:nginx| | |#創建 | | |[root@master~/affinity]# kubectl apply -f affinity-deploy.yaml | | |deployment.apps/nginx-affinitycreated|
查看Pod調度到哪個節點上了?
發現Pod全部調度到node01節點上
| | | |--- | --- | | |[root@master~/affinity]# kubectlgetpo-o wide| | |NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES| | |nginx-affinity-556d5d5987-5bnjm 1/1 Running 0 94s 100.117.144.175 node01| | |nginx-affinity-556d5d5987-bvmvh 1/1 Running 0 94s 100.117.144.173 node01 | | |nginx-affinity-556d5d5987-d7tkg 1/1 Running 0 94s 100.117.144.174 node01 | | |nginx-affinity-556d5d5987-frkkm 1/1 Running 0 94s 100.117.144.172 node01 | | |nginx-affinity-556d5d5987-ttlcr 1/1 Running 0 94s 100.117.144.176 node01 |
如果標簽不匹配,Pod會出現什么情況呢?
| | | | --- | --- | | |# 將node01節點上的標簽刪除一個 | | | [root@master ~/affinity]# kubectl label node node01 cpu-cores- | | | node/node01 unlabeled | | |# 查看標簽 | | | [root@master ~/affinity]# kubectl describe node node01 | grep Labels -A 5 | | | Labels: beta.kubernetes.io/arch=amd64 | | | beta.kubernetes.io/os=linux | | | disk-type=ssd | | |env=prod | | | kubernetes.io/arch=amd64 | | | kubernetes.io/hostname=node01 | | | | | |# 刪除Pod讓其重建 | | | [root@master ~/affinity]# kubectl get po | awk'{print $1}'| xargs kubectl delete po | | | pod"nginx-affinity-556d5d5987-5bnjm"deleted | | | pod"nginx-affinity-556d5d5987-bvmvh"deleted | | | pod"nginx-affinity-556d5d5987-d7tkg"deleted | | | pod"nginx-affinity-556d5d5987-frkkm"deleted | | | pod"nginx-affinity-556d5d5987-ttlcr"deleted |
查看Pod,發現狀態都是Pending狀態
| | | | --- | --- | | | [root@master ~/affinity]# kubectl get po | | | NAME READY STATUS RESTARTS AGE | | | nginx-affinity-556d5d5987-44qmc 0/1 Pending 0 27s | | | nginx-affinity-556d5d5987-4qtth 0/1 Pending 0 27s | | | nginx-affinity-556d5d5987-4tws5 0/1 Pending 0 27s | | | nginx-affinity-556d5d5987-bgm7n 0/1 Pending 0 27s | | | nginx-affinity-556d5d5987-kh555 0/1 Pending 0 27s |
查看一下詳細信息,發現是標簽不匹配
| | | | --- | --- | | | | | | [root@master ~/affinity]# kubectl describe po nginx-affinity-556d5d5987-44qmc | | | Name: nginx-affinity-556d5d5987-44qmc | | | | | | Events: | | | Type Reason Age From Message | | | ---- ------ ---- ---- ------- | | | Warning FailedScheduling 71s default-scheduler 0/3nodes are available:1node(s) had untolerated taint {node-role.kubernetes.io/control-plane: },2node(s) didn'tmatchPod'snode affinity/selector. preemption:0/3nodes are available:3Preemption is not helpfulforscheduling.. | | | Warning FailedScheduling 70s default-scheduler 0/3nodes are available:1node(s) had untolerated taint {node-role.kubernetes.io/control-plane: },2node(s) didn'tmatchPod'snode affinity/selector. preemption:0/3nodes are available:3Preemption is not helpfulforscheduling.. |
總結一下,節點親和性可以更加細膩指定Pod調度到某一個節點上,如果指定的標簽不匹配,那么Pod會處于Pending狀態
節點親和性實戰-軟性規則匹配
軟性規則匹配優先滿足條件,但不強制。調度器會為每個滿足條件的節點打分,選擇分數最高的節點。
評分機制
當存在多個滿足軟性規則的節點時,調度器會計算每個節點的得分:
? 基礎分:所有節點初始分為 0。
? 權重疊加:對每個 preferredDuringSchedulingIgnoredDuringExecution 規則:
? 若節點滿足規則,得分為 weight 值。
? 若不滿足,得分為 0。
? 總分計算:節點最終得分是所有匹配規則的 weight 之和。
示例:
優先調度到以下節點:
? 首選 region=east 的節點(權重 100)
? 其次 disk-type=ssd 的節點(權重 70)
給node01節點打上region=east標簽
| | | | --- | --- | | | [root@master ~/affinity]# kubectl label node node01 region=east | | | node/node01 labeled |
給node02節點打上disk-type=ssd標簽
| | | | --- | --- | | | [root@master ~/affinity]# kubectl label node node02 disk-type=ssd | | | node/node02 labeled |
創建deploy
| | | |---|---| | |[root@master~/affinity]# cat affinity-deploy.yaml | | |apiVersion:apps/v1| | |kind:Deployment| | |metadata:| | |name:nginx-affinity| | |spec:| | |replicas:10| | |selector:| | |matchLabels:| | |app:nginx| | |template:| | |metadata:| | |labels:| | |app:nginx| | |spec:| | |affinity:| | |# 節點親和性 | | |nodeAffinity:| | |# 指定軟性匹配規則 | | |preferredDuringSchedulingIgnoredDuringExecution:| | |# 權重范圍 1-100,值越高優先級越高 | | |-weight:100| | |preference:| | |matchExpressions:| | |-key:region| | |operator:In| | |values:["east"]| | |-weight:70| | |preference:| | |matchExpressions:| | |-key:disk-type| | |operator:In| | |values:["ssd"]| | |containers:| | |-name:nginx| | |image:nginx| | |[root@master~/affinity]# kubectl apply -f affinity-deploy.yaml | | |deployment.apps/nginx-affinitycreated|
查看Pod調度到哪一個節點上
發現調度到node01節點上的Pod居多,因為node01的權重是100,而node02節點上略少,權重為70
| | | | --- | --- | | |[root@master ~/affinity]# kubectl get po -o wide | | | NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES | | | nginx-affinity-65587946bd-84mv5 1/1 Running 0 30s 100.117.144.180 node01| | | nginx-affinity-65587946bd-8lfwl 1/1 Running 0 30s 100.117.144.183 node01 | | | nginx-affinity-65587946bd-9fnhb 1/1 Running 0 30s 100.117.144.179 node01 | | | nginx-affinity-65587946bd-9rqt9 1/1 Running 0 30s 100.117.144.177 node01 | | | nginx-affinity-65587946bd-gsq4c 1/1 Running 0 30s 100.117.144.182 node01 | | | nginx-affinity-65587946bd-pf845 1/1 Running 0 30s 100.95.185.238 node02 | | | nginx-affinity-65587946bd-pvwps 1/1 Running 0 30s 100.95.185.237 node02 | | | nginx-affinity-65587946bd-qhhh7 1/1 Running 0 30s 100.95.185.239 node02 | | | nginx-affinity-65587946bd-tn54h 1/1 Running 0 30s 100.117.144.178 node01 | | | nginx-affinity-65587946bd-x64qs 1/1 Running 0 30s 100.117.144.181 node01 |
節點親和性-混合使用硬性和軟性規則
示例:
| | | |---|---| | |apiVersion:v1| | |kind:Pod| | |metadata:| | |name:mixed-affinity-pod| | |spec:| | |affinity:| | |nodeAffinity:| | |# 硬性限制 | | |requiredDuringSchedulingIgnoredDuringExecution:| | |nodeSelectorTerms:| | |-matchExpressions:| | |-key:env| | |operator:In| | |values:["prod"]| | |# 軟性限制 | | |preferredDuringSchedulingIgnoredDuringExecution:| | |-weight:80| | |preference:| | |matchExpressions:| | |-key:gpu| | |operator:Exists| | |containers:| | |-name:nginx| | |image:nginx|
回到頂部
Pod親和性
Pod 親和性(Pod Affinity)是 Kubernetes 中控制 Pod 調度的重要機制,其核心作用是根據其他 Pod 的位置(如節點、命名空間等)來影響當前 Pod 的調度決策,實現 Pod 之間的協同部署或反親和(互斥部署)。這一機制通過標簽匹配規則,將相關 Pod 「吸引」到同一區域(如節點、機架、可用區等)或「排斥」到不同區域,從而優化資源利用、提升服務性能或增強系統穩定性。
Pod親和性的分類
Pod親和性分為間親和性和反親和性。
親和性是當第一個Pod調度到一個特定的拓撲域中時,后續的所有的Pod都會往該拓撲域調度。
拓撲域理解為親和性規則作用的「區域范圍」,通常為節點標簽(如 kubernetes.io/hostname 表示節點,kubernetes.io/zone 表示可用區)。
反親和性是保證一個拓撲域中最多只能有且僅有一個相同的pod,多余的pod處于pending狀態
Pod間親和性實戰
Pod 間親和性可以用于將相關 Pod 調度到同一拓撲層級(如同一節點或同一可用區),從而減少網絡延遲,提高性能。例如:
? 將前端和后端服務部署在同一節點或同一可用區:減少服務間通信的網絡延遲。
? 將依賴的服務部署在同一節點:提高服務間的通信效率。
Pod 間親和性也分為硬性限制和軟性限制,通過requiredDuringSchedulingIgnoredDuringExecution(硬性)和preferredDuringSchedulingIgnoredDuringExecution(軟性)來指定。
硬性限制實戰
示例:
| | | |---|---| | |# 定義deploy | | |[root@master~/affinity]# cat affinity-deploy.yaml | | |apiVersion:apps/v1| | |kind:Deployment| | |metadata:| | |name:nginx-affinity| | |spec:| | |replicas:10| | |selector:| | |matchLabels:| | |app:nginx| | |template:| | |metadata:| | |labels:| | |app:nginx| | |spec:| | |affinity:| | |# Pod親和性 | | |podAffinity:| | |# 指定硬性匹配規則 | | |requiredDuringSchedulingIgnoredDuringExecution:| | |-labelSelector:| | |# 這里指定Pod的標簽,而不是節點的標簽 | | |matchExpressions:| | |-key:app| | |operator:In| | |values:["nginx"]| | |# 添加 topologyKey,topologyKey 決定了 Pod 親和性或反親和性規則在集群中的作用范圍。 | | |# 這里指定節點標簽的key | | |topologyKey:"kubernetes.io/hostname"| | |containers:| | |-name:nginx| | |image:nginx| | | | | |[root@master~/affinity]# kubectl apply -f affinity-deploy.yaml | | |deployment.apps/nginx-affinitycreated|
配置說明:
labelSelector:標簽選擇器,在這里是選擇Pod的標簽,而不是選擇節點的標簽,因為Pod親和性是Pod級別的調度
topologyKey:該字段是Pod親和性中一個很重要的字段,它的作用是定義 Pod 親和性或反親和性規則的作用范圍,即在什么級別的拓撲結構中應用這些規則。這里指定的節點標簽的key
查看Pod的調度,發現Pod都在node02節點上
| | | | --- | --- | | |[root@master ~/affinity]# kubectl get po -o wide | | | NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES | | | nginx-affinity-7f74fbb7c-2r9lm 1/1 Running 0 76s 100.95.185.249 node02| | | nginx-affinity-7f74fbb7c-55bfw 1/1 Running 0 76s 100.95.185.241 node02 | | | nginx-affinity-7f74fbb7c-9h5qq 1/1 Running 0 76s 100.95.185.248 node02 | | | nginx-affinity-7f74fbb7c-bq9m9 1/1 Running 0 76s 100.95.185.245 node02 | | | nginx-affinity-7f74fbb7c-cdxpg 1/1 Running 0 76s 100.95.185.240 node02 | | | nginx-affinity-7f74fbb7c-j7vbf 1/1 Running 0 76s 100.95.185.242 node02 | | | nginx-affinity-7f74fbb7c-rnqfs 1/1 Running 0 76s 100.95.185.243 node02 | | | nginx-affinity-7f74fbb7c-sscsx 1/1 Running 0 76s 100.95.185.244 node02 | | | nginx-affinity-7f74fbb7c-v7jf2 1/1 Running 0 76s 100.95.185.246 node02 | | | nginx-affinity-7f74fbb7c-w249m 1/1 Running 0 76s 100.95.185.247 node02 |
軟性限制實戰(略,生產環境中使用的不多)
Pod反親和性
Pod 反親和性(podAntiAffinity)是 Kubernetes 中的一種調度策略,與 Pod 親和性(podAffinity)相對。它用于控制 Pod 的調度位置,確保滿足特定條件的 Pod 不會被調度到同一拓撲層級(如同一節點、同一可用區或同一區域)上。Pod 反親和性主要用于實現高可用性和資源隔離等目標。
Pod 反親和性也分為硬性限制和軟性限制,通過requiredDuringSchedulingIgnoredDuringExecution(硬性)和preferredDuringSchedulingIgnoredDuringExecution(軟性)來指定。
Pod反親和性作用
? 高可用性:
? 通過將多個副本 Pod 分布到不同的故障域(如不同的節點或可用區),確保系統的容錯能力。例如,將多個副本 Pod 調度到不同的節點或可用區,避免單點故障導致所有副本同時不可用。
? 資源隔離:
? 通過將某些 Pod 分布到不同的節點或可用區,避免它們相互競爭資源。例如,將不同租戶的 Pod 分布到不同的節點或可用區,實現資源隔離。
? 性能優化:
? 通過將 Pod 分布到不同的節點或可用區,減少單個節點的負載壓力,提高整體性能。
硬限制實戰
| | | |---|---| | |# 創建deploy | | |[root@master~/affinity]# cat affinity-deploy.yaml | | |apiVersion:apps/v1| | |kind:Deployment| | |metadata:| | |name:nginx-affinity| | |spec:| | |replicas:10| | |selector:| | |matchLabels:| | |app:nginx| | |template:| | |metadata:| | |labels:| | |app:nginx| | |spec:| | |affinity:| | |# Pod反親和性 | | |podAntiAffinity:| | |# 指定性匹配規則 | | |requiredDuringSchedulingIgnoredDuringExecution:| | |-labelSelector:| | |# 這里指定Pod的標簽,而不是節點的標簽 | | |matchExpressions:| | |-key:app| | |operator:In| | |values:["nginx"]| | |# # 添加 topologyKey | | |topologyKey:"kubernetes.io/hostname"| | |containers:| | |-name:nginx| | |image:nginx| | |[root@master~/affinity]# kubectl apply -f affinity-deploy.yaml | | |deployment.apps/nginx-affinitycreated|
查看一下Pod
發現只有兩個Pod處于Running狀態,為什么呢?
因為反親和性是在每個拓撲域中調度一個Pod,當Pod的數量多余拓撲域時,那么剩余的Pod則無法完成調度,所以處于了Pending狀態
| | | | --- | --- | | |[root@master ~/affinity]# kubectl get po -o wide | | | NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES | | | nginx-affinity-675c568f99-5brpf 1/1 Running 0 5s 100.117.144.184 node01| | | nginx-affinity-675c568f99-68z9q 0/1 Pending 0 5s | | | nginx-affinity-675c568f99-7vbqb 0/1 Pending 0 5s | | | nginx-affinity-675c568f99-8tqps 0/1 Pending 0 5s | | | nginx-affinity-675c568f99-96cs2 0/1 Pending 0 5s | | | nginx-affinity-675c568f99-prpg4 0/1 Pending 0 5s | | | nginx-affinity-675c568f99-qsp8b 1/1 Running 0 5s 100.95.185.250 node02 | | | nginx-affinity-675c568f99-tf9qv 0/1 Pending 0 5s | | | nginx-affinity-675c568f99-x7k8p 0/1 Pending 0 5s | | | nginx-affinity-675c568f99-xbfn2 0/1 Pending 0 5s |
回到頂部
Pod反親和性和DaemonSet的區別
Pod反親和性和DaemonSet感覺很類似,在不考慮污點的情況下,會在每一個節點上都會創建一個Pod,但是也有一些區別
DaemonSet可以閱讀這篇文章:K8s新手系列之DaemonSet資源
特性 | Pod 反親和性 | DaemonSet |
定義 | 調度策略,控制 Pod 的調度位置 | 控制器,確保每個節點上運行一個 Pod 的副本 |
用途 | 高可用性、資源隔離、性能優化 | 運行集群級別的守護進程,如日志收集、監控代理 |
調度方式 | 根據labelSelector和topologyKey調度 Pod | 自動在每個節點上運行一個 Pod 的副本 |
配置方式 | 在 Pod 的spec.affinity.podAntiAffinity中配置 | 使用 DaemonSet 資源對象配置 |
適用場景 | 多副本應用,需要跨節點或可用區分布 | 集群級別的守護進程,每個節點都需要運行一個副本 |
調度器角色 | 調度器根據規則調度 Pod | DaemonSet 控制器自動管理 Pod 的生命周期 |
Pod 數量 | 根據副本數和調度規則動態調整 | 每個節點上運行一個 Pod,數量與節點數量一致 |
鏈接:https://www.cnblogs.com/huangSir-devops/p/18859120
-
節點
+關注
關注
0文章
221瀏覽量
24837 -
kubernetes
+關注
關注
0文章
240瀏覽量
8974 -
字段
+關注
關注
0文章
15瀏覽量
1709
原文標題:5分鐘掌握Kubernetes Pod親和性(Affinity):核心概念與實戰配置指南
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
Kubernetes的Device Plugin設計解讀
Kubernetes Ingress 高可靠部署最佳實踐
阿里云容器Kubernetes監控(二) - 使用Grafana展現Pod監控數據
從零開始入門 K8s| 阿里技術專家詳解 K8s 核心概念
從零開始入門 K8s| 詳解 Pod 及容器設計模式
淺談Kubernetes集群的高可用方案

Kubernetes API詳解

深入研究Kubernetes調度
容器進程調度時是該優先考慮CPU資源還是內存資源
Kubernetes中的Pod簡易理解
Kubernetes Pod如何獨立工作

Kubernetes Pod如何獲取IP地址呢?

Linux之CPU調度策略和CPU親和性

評論