k8s中topologyKey的作用及说明
作者:容器云
spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: rcs-prod operator: In values: - 'true' podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: {} topologyKey: rcs-prod podAntiAffinity: {}
topologyKey的作用
一、topologyKey的核心作用
topologyKey
通过 节点的标签(Label) 划分逻辑上的“拓扑域”,用于实现:
1.Pod 亲和性(PodAffinity)
将 Pod 调度到与目标 Pod 相同的拓扑域(例如同一机架、可用区或自定义分组)。
2.Pod 反亲和性(PodAntiAffinity)
阻止 Pod 调度到与目标 Pod 相同的拓扑域(例如避免单节点或单可用区部署)。
二、topologyKey的值来源
topologyKey
的值是 节点标签的键(Key),可以是:
Kubernetes 内置标签
kubernetes.io/hostname
(节点主机名,粒度最细)topology.kubernetes.io/zone
(可用区,如 AWS 的us-east-1a
)topology.kubernetes.io/region
(地域,如us-east-1
)
topologyKey
是 Pod 亲和性/反亲和性规则中用于定义"拓扑域"的节点标签键。它决定了如何将节点分组以实现 Pod 的共置或隔离:
- 当两个 Pod 在具有相同
topologyKey
值的节点上时,它们被视为在同一拓扑域中 - 对于 podAffinity,Kubernetes 会尝试将 Pod 调度到与指定 Pod 在同一拓扑域的节点上
- 对于 podAntiAffinity,Kubernetes 会确保 Pod 不会被调度到与指定 Pod 在同一拓扑域的节点上
调度器如何工作
当调度器决定pod调度到哪里时,它首先检查pod的podAffinity配置,找 出那些符合标签选择器的pod, 接着查询这些pod运行在哪些节点上。
特别的是, 它会寻找标签能匹配podAffinity配置中topologyKey的节点。接着,它会优 先选择所有的标签匹配pod的值的节点。
配置详细解释
nodeAffinity 部分
nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: rcs-prod operator: In values: - 'true'
- 含义:Pod 必须被调度到带有标签
rcs-prod=true
的节点上 requiredDuringSchedulingIgnoredDuringExecution
表示这是硬性要求,调度时必须满足
podAffinity 部分
podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: {} topologyKey: rcs-prod
含义:Pod 必须与集群中所有其他 Pod 部署在相同拓扑域(即具有相同 rcs-prod
标签值的节点上)
labelSelector: {}
匹配所有 Pod,因为没有指定具体标签topologyKey: rcs-prod
表示使用节点的rcs-prod
标签作为拓扑域
podAntiAffinity 部分
podAntiAffinity: {}
这是一个空配置,表示没有 Pod 反亲和性规则
综合理解
这个配置的整体效果是:
- Pod 只能被调度到带有
rcs-prod=true
标签的节点上 - Pod 必须与所有其他 Pod 部署在相同拓扑域(即所有 Pod 都在具有相同
rcs-prod
标签值的节点上)
注意:这里的 podAffinity 配置有些特殊,因为它使用了空标签选择器匹配所有 Pod,这可能导致调度困难,除非集群中所有节点都有相同的 rcs-prod
标签值。
当前的设置并不能避免相同的 Pod 调度到同一个节点上。以下是详细分析:
为什么当前配置不能防止相同 Pod 调度到同一节点?
1.缺少 podAntiAffinity
规则
- 您当前的
podAntiAffinity: {}
是空的,没有定义任何反亲和性规则。 - 要阻止相同 Pod 调度到同一节点,必须明确配置反亲和性。
2.podAffinity
的作用是共置(co-location),而非隔离
- 当前的
podAffinity
只是强制 Pod 必须调度到具有相同rcs-prod
标签值的节点,但不会阻止相同 Pod 部署到同一节点。
3.topologyKey
在 podAffinity
中的用途
- 它仅定义“拓扑域”(如节点、机架、区域等),而不是 Pod 之间的排斥规则。
- 当前的
topologyKey: rcs-prod
仅确保 Pod 调度到具有相同rcs-prod
标签值的节点,但不会限制同一节点上的副本数量。
如何修改配置以避免相同 Pod 调度到同一节点?
如果希望 相同的 Pod 不被调度到同一个节点(例如避免单点故障),需要配置 podAntiAffinity
,例如:
方案 1:硬性反亲和性(不允许同一节点调度)
affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 硬性要求 - labelSelector: matchLabels: app: your-pod-label # 替换为您的 Pod 标签 topologyKey: kubernetes.io/hostname # 以节点主机名为拓扑域
方案 2:软性反亲和性(尽量不调度到同一节点)
affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: # 软性偏好 - weight: 100 podAffinityTerm: labelSelector: matchLabels: app: your-pod-label topologyKey: kubernetes.io/hostname
关键点说明
1.topologyKey
的选择
- 如果使用
kubernetes.io/hostname
,则反亲和性针对单个节点(最严格)。 - 如果使用其他标签(如
zone
),则反亲和性会作用于更广的拓扑域(如整个可用区)。
2.labelSelector
必须匹配 Pod 标签
- 您需要确保
matchLabels
中的标签与您的 Pod 模板中定义的标签一致,例如:
metadata: labels: app: your-pod-label # 需与反亲和性规则匹配
3.nodeAffinity
和 podAntiAffinity
可以共存
- 您的原有
nodeAffinity
可以保留,只需补充podAntiAffinity
即可。
最终建议配置
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: rcs-prod operator: In values: - "true" podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: your-pod-label # 替换为您的实际 Pod 标签 topologyKey: kubernetes.io/hostname # 确保不调度到同一节点
这样既能满足节点亲和性要求,又能避免相同 Pod 调度到同一节点。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。