在 Kubernetes 中,若需要将 Pod 调度到特定节点,最推荐的方式是使用节点亲和性(Node Affinity),它比 nodeSelector 更灵活,支持软硬规则;若仅需简单匹配,也可使用 nodeSelector。
先说结论:通过给节点打标签并在 Pod 配置中声明亲和性规则,可控制调度位置。
- 适合:需要精细控制 Pod 分布或满足硬件/区域要求的场景
- 先准备:确认目标节点名称,并规划好标签键值对
- 验收:部署后检查 Pod 状态及所在节点是否符合预期
命令速用版
给节点打标签:
kubectl label nodes <节点名称> <键>=<值>
Pod 配置片段(nodeAffinity):
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: <键>
operator: In
values:
- <值>为什么会这样
Kubernetes 调度器默认会自动分配节点,但有时我们需要干预。节点亲和性允许通过节点标签来选择目标,比 nodeSelector 表达能力更强,支持“必须满足”或“优先满足”的逻辑。如果标签匹配不到,Pod 会处于 Pending 状态。亲和性分为节点亲和性、Pod 亲和性和 Pod 反亲和性,其中节点亲和性主要用于控制 Pod 调度到哪些具有特定标签的节点上。
分步处理
1. 查看节点并打标签
执行命令获取集群节点名称,然后为目标节点添加标签。例如将标签 mykey4pod=asmgateway 添加到节点:
kubectl get nodes kubectl label nodes <node-name> mykey4pod=asmgateway
2. 编写 Pod YAML 添加 affinity
在 Pod 或工作负载的 spec 字段下增加 affinity 配置。若需强制调度,使用 requiredDuringSchedulingIgnoredDuringExecution;若为偏好,可使用 preferredDuringSchedulingIgnoredDuringExecution。
3. 应用配置
提交 YAML 文件后,调度器会根据规则寻找匹配标签的节点。若节点还设置了污点(Taint),Pod 还需配置相应的容忍度(Toleration)才能被调度。
怎么验证是否生效
部署后查看 Pod 所在节点:
kubectl get pod -o wide
检查输出中的 NODE 列是否为目标节点。也可使用 describe 查看事件:
kubectl describe pod <pod-name>
若调度失败,Events 中通常会显示匹配不到的原因。
常见坑
1. 标签拼写错误:节点标签与 Pod 配置中的 key 或 value 不一致,会导致 Pod 一直处于 Pending 状态。
2. 混淆污点与亲和性:污点是节点拒绝 Pod,亲和性是 Pod 选择节点。若节点有污点,Pod 必须配置容忍度才能调度上去,即使亲和性匹配。
3. 硬规则风险:使用 required 规则时,若集群中没有满足条件的节点,Pod 将无法调度,需确保资源充足。
参考来源
- Kubernetes 节点亲和性分配 Pod
- 在 K8S 中,Pod 亲和性概念是什么?
- 从 NodeSelector 到 NodeAffinity:探索 Kubernetes 节点亲和性的进化之路
- kubernetes 中 pod 的调度亲和性 affinity 详解
- 官网:http://kubernetes.p2hp.com/docs/concepts/scheduling-eviction/assign-pod-node.html