1. 调度亲和性(Affinity)是什么?
-
官方定义
调度亲和性是Kubernetes用于控制Pod如何分配到节点的策略,允许用户定义Pod与节点(或与其他Pod)之间的“吸引”或“排斥”规则。 -
通俗理解
就像给Pod贴上“喜好标签”,告诉Kubernetes:“我想和某些节点/Pod待在一起”或者“我不想和某些节点/Pod待在一起”。
例如:-
数据库Pod希望调度到高配节点(亲和性)。
-
同一服务的多个Pod避免部署在同一节点(反亲和性),提高容错性。
-
2. 硬亲和性 vs 软亲和性
类型 | 官方术语 | 通俗解释 | 调度失败处理 |
---|---|---|---|
硬亲和性 | requiredDuringSchedulingIgnoredDuringExecution | 必须满足的条件,不满足则Pod无法调度(Pending状态)。 | Pod无法运行,需人工干预。 |
软亲和性 | preferredDuringSchedulingIgnoredDuringExecution | 尽量满足的条件,不满足时仍会调度到其他节点,但优先匹配。 | Pod仍能运行,但可能非最优。 |
示例对比:
-
硬策略:必须将Pod调度到“GPU节点”,否则不运行。
-
软策略:优先调度到“SSD节点”,如果没有SSD节点,也可以用普通节点。
3. 节点亲和性(Node Affinity) vs 节点反亲和性
3.1 节点亲和性
-
官方定义
指定Pod应调度到具有特定标签的节点。 -
通俗场景
-
将计算密集型Pod调度到高配CPU节点。
-
将存储服务Pod调度到带有SSD的节点。
-
示例配置(硬策略):
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disk-type # 标签键
operator: In # 操作符
values: ["ssd"] # 标签值
3.2 节点反亲和性
-
官方定义
指定Pod应避免调度到具有特定标签的节点。 -
通俗场景
-
避免将Pod调度到维护中的节点。
-
避免敏感服务调度到公共网络区域的节点。
-
示例配置(硬策略):
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: maintenance # 标签键
operator: NotIn # 操作符
values: ["true"] # 标签值
4. Pod亲和性(Pod Affinity) vs Pod反亲和性
4.1 Pod亲和性
-
官方定义
指定Pod应与具有特定标签的其他Pod部署在同一拓扑域(如同一节点、区域)。
需定义topologyKey
(如kubernetes.io/hostname
表示同一节点)。 -
通俗场景
-
Web服务Pod与缓存服务Pod部署在同一节点,减少网络延迟。
-
微服务中紧密协作的组件就近部署。
-
示例配置(硬策略):
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values: ["cache"]
topologyKey: kubernetes.io/hostname # 同一节点
4.2 Pod反亲和性
-
官方定义
指定Pod应避免与具有特定标签的其他Pod部署在同一拓扑域。 -
通俗场景
-
同一服务的多个Pod分散在不同节点,避免单点故障。
-
避免竞争资源的Pod共存(如高内存消耗的服务)。
-
示例配置(软策略):
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100 # 优先级权重(1-100)
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values: ["web"]
topologyKey: kubernetes.io/hostname # 不同节点
5. 操作符(Operator)对比
操作符 | 作用 | 适用场景示例 |
---|---|---|
In | 标签值在指定列表中 | 节点需属于某个可用区(zone=A或zone=B) |
NotIn | 标签值不在指定列表中 | 避免调度到测试环境节点 |
Exists | 标签存在(不检查值) | 节点必须有GPU标签(无论型号) |
DoesNotExist | 标签不存在 | 避免调度到未验证的节点 |
Gt / Lt | 标签值为数值且大于/小于指定值 | 节点内存需大于32Gi |
6. 用户提供的示例解析
示例1:节点亲和性硬策略
# 必须不在node2上调度
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values: ["node2"]
效果:Pod不会调度到node2
,若所有节点都不可用则Pending。
示例2:节点亲和性软策略
# 优先调度到node3,若无则选择其他节点
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: kubernetes.io/hostname
operator: In
values: ["node3"]
效果:尽量选择node3
,但允许其他节点。
示例3:结合硬策略和软策略
# 硬策略:不在k8s-node2调度
# 软策略:优先选择有source=qikqiak标签的节点
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values: ["k8s-node2"]
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: source
operator: In
values: ["qikqiak"]
效果:首先排除k8s-node2
,然后优先选择有source=qikqiak
标签的节点。
7. 总结对比表
类型 | 目标对象 | 核心作用 | 典型场景 |
---|---|---|---|
节点亲和性 | 节点 | 吸引Pod到特定节点 | 硬件优化(如GPU、SSD) |
节点反亲和性 | 节点 | 避免Pod到特定节点 | 排除维护节点或低性能节点 |
Pod亲和性 | 其他Pod | 与特定Pod共存 | 减少延迟、服务依赖紧密 |
Pod反亲和性 | 其他Pod | 避免与特定Pod共存 | 容错、资源隔离 |
硬策略 | - | 必须满足,否则无法调度 | 关键业务强制要求 |
软策略 | - | 尽量满足,不强制 | 优化调度,但允许弹性 |
通过合理使用亲和性策略,可以实现更智能、更稳定的Pod调度,优化资源利用和系统可靠性。