引言:你真的掌控了Pod调度吗?
很多开发者在部署应用时,往往只关注副本数量、资源限制、Service 暴露方式,却忽略了一个至关重要的问题:
Pod 到底被调度到哪台 Node 上?
Kubernetes 的调度器虽然强大,但默认的调度策略有时候并不满足业务需求,比如:
- 多个副本集中在一台节点,影响高可用性;
- 关键服务和日志采集服务部署在同一个节点,资源冲突;
- 希望将某类应用部署到特定标签的节点上。
这时,我们就需要用到 Kubernetes 的调度利器 ——
节点亲和性(Node Affinity)与Pod亲和性(Pod Affinity / Anti-Affinity) 。
一、什么是 Affinity 和 Anti-Affinity?
Kubernetes 提供三种调度约束方式:
| 类型 | 作用 |
|---|---|
| Node Affinity | 控制 Pod 应该调度到哪些类型的 Node 上 |
| Pod Affinity | 控制 Pod 应该与哪些其他 Pod 放在同一节点上(亲密) |
| Pod AntiAffinity | 控制 Pod 应该避免与哪些 Pod 放在一起(排斥) |
这种机制给了开发者更强的调度控制权,尤其适合分布式服务、微服务架构场景。
二、Node Affinity:绑定到特定节点类型
1. 应用场景举例:
- 只部署在 GPU 节点上
- 绑定在 SSD 存储的节点
- 根据地理区域(如北京/上海)调度
2. 配置示例
为 Node 添加标签:
kubectl label nodes node-1 disktype=ssd
Deployment 中配置 Affinity:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
3. 精讲:强 vs 弱 亲和性
- requiredDuringSchedulingIgnoredDuringExecution: 必须匹配,否则调度失败;
- preferredDuringSchedulingIgnoredDuringExecution: 尽量匹配,调度器优先考虑但不强制。
三、Pod Affinity 与 Anti-Affinity:Pod 与 Pod 的关系控制
1. 应用场景举例:
- 多个微服务希望部署在一起(减少网络延迟)—— Pod Affinity;
- 同一个应用的多个副本希望分布在不同节点上(防止单点故障)—— Pod Anti-Affinity。
2. Pod Anti-Affinity 示例(避免副本在同节点)
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp
topologyKey: "kubernetes.io/hostname"
这段配置的含义是:
当前 Pod 不应该调度到已经运行有 app=myapp 的 Pod 的节点上。
如果你在 Deployment 中用了副本数 replicas: 3,调度器会尽量把它们分到不同节点。
3. Pod Affinity 示例(调度在一起)
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: frontend
topologyKey: "kubernetes.io/hostname"
表示新 Pod 只会被调度到已有 app=frontend 的节点上。
适合如下情况:
- Web 前端与缓存服务共节点部署
- Agent/Sidecar 与主应用绑定部署
四、实战经验总结与避坑指南
✅ 实战建议一:合理使用 topologyKey
常见值包括:
- kubernetes.io/hostname:按 Node 控制
- topology.kubernetes.io/zone:按可用区(云厂商场景)
如果 key 写错,会导致调度器根本找不到合适节点,Pod 卡住 Pending。
✅ 实战建议二:Pod AntiAffinity + 副本数 控制高可用
如果你设置了 podAntiAffinity,但集群中 Node 数量不足以容纳副本,会导致部分 Pod 无法调度。
解决方案:
- 确保集群节点数量 >= 副本数;
- 或使用 preferredDuringSchedulingIgnoredDuringExecution 软约束。
✅ 实战建议三:搭配 taints/tolerations 精准调度
Affinity 是 “想要去哪里”,而 taints/tolerations 是 “禁止谁来”。
结合使用可以做出非常精细的调度控制策略!
五、总结:从默认调度到策略调度的跃迁
掌握 Affinity 系列调度机制,是从普通使用者向架构控制者迈进的重要一步。
用好 Node Affinity + Pod AntiAffinity:
✅ 可以保障高可用部署;
✅ 减少同类服务间资源抢占;
✅ 帮助你为服务性能和故障隔离提供强有力保障。