podAffinity 是什么
podAffinity 让新 Pod 调度到「已经存在某个标签 Pod」的拓扑域里,拓扑域由 topologyKey 定义:填 kubernetes.io/hostname 表示同一节点,填可用区标签表示同一可用区。它的判定依据是集群里已经调度好的 Pod,而不是节点标签。反之 podAntiAffinity 用来分散,让同类 Pod 尽量落在不同节点或不同可用区,是可用区级高可用与缓存就近的两种典型用法。
基本信息
| 字段位置 | spec.affinity 下的 podAffinity 与 podAntiAffinity |
|---|---|
| 两种强度 | required 必须满足,否则不调度;preferred 按权重尽量满足 |
| 关键参数 | labelSelector 选参照 Pod,topologyKey 定义拓扑域 |
| 可跨命名空间 | 通过 namespaces 或 namespaceSelector 指定参照 Pod 所在命名空间 |
| 判定时机 | 只在调度阶段评估,运行期间不会因为参照 Pod 变化而重算 |
| 性能提示 | 集群规模大时装配性规则会明显增加调度计算量 |
同节点就近写法
同节点就近写法
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
template:
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: cache
topologyKey: kubernetes.io/hostname # 与缓存 Pod 落在同一节点分散部署与更柔和的写法
分散部署与更柔和的写法
affinity:
podAntiAffinity:
# 硬分散:同一拓扑域内不允许出现第二个同类 Pod
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: web
topologyKey: topology.kubernetes.io/zone
# 软分散:尽量分散,资源不足时也允许同域
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname四种组合
| 组合 | 效果 | 风险 |
|---|---|---|
| podAffinity 加 required | 必须与参照 Pod 同域 | 参照 Pod 不在任何节点时新 Pod 无法调度 |
| podAffinity 加 preferred | 倾向于同域,尽量满足 | 同域不可得时会落到更远的节点 |
| podAntiAffinity 加 required | 同域内不允许出现同类 Pod | 节点或域不足时新副本全部 Pending |
| podAntiAffinity 加 preferred | 尽量分散,允许同域 | 高峰期仍可能出现同域叠放 |
典型使用场景
- 缓存就近:业务 Pod 与缓存 Pod 调度到同一节点,减少跨节点流量与延迟
- 可用区高可用:同类副本用反亲和分散到不同可用区,单域故障不至于全挂
- 干扰隔离:把互相抢资源的服务用反亲和排到不同节点
- 参照已有组件:新服务需要和某个已有组件贴近部署时,用参照 Pod 的标签作为锚点
- 渐进式约束:先用软策略观察分布,确认容量足够再改成硬策略
亲和规则按「已调度的 Pod」判断,所以首次部署时若参照 Pod 还没起来,硬亲和会导致新 Pod 一直等。这时候更适合用软策略,或先确保锚点组件已经稳定运行。topologyKey 还必须是非空标签,且该标签在不同节点上的取值要能区分拓扑域。
硬反亲和与节点数量直接挂钩:三个可用区部署六副本并要求每域最多两个,一旦某个域节点不够,新副本会一直 Pending 且不会降级。上硬策略前先确认容量与故障域边界,必要时补充拓扑分布约束。