Kubernetes Pod 调度详解
掌握节点调度的核心机制:nodeSelector、nodeName、Affinity 和 Tolerations
Kubernetes Pod 调度概述
在 Kubernetes 中,Pod 调度是一个至关重要的功能,它决定了 Pod 在集群中的哪个节点上运行。合理的调度策略能够优化资源利用率、提高应用性能并确保系统稳定性。
Kubernetes 调度器负责根据资源需求、策略和约束条件,自动将 Pod 分配到合适的节点上。当需要更精细的控制时,可以使用以下四种主要调度机制:
调度流程
1. 创建 Pod 时,用户可以通过各种机制指定调度偏好
2. 调度器过滤掉不满足条件的节点
3. 调度器对剩余节点进行评分
4. 选择得分最高的节点运行 Pod
nodeSelector:基础节点选择器
nodeSelector
是 Kubernetes 中最简单的节点调度方式,它允许您通过节点标签来选择特定的节点。
使用方式
pod-nodeSelector.yaml复制代码
apiVersion: v1 kind: Pod metadata:name: nginx-pod spec:containers:- name: nginximage: nginx:1.14.2nodeSelector:disktype: ssdenvironment: production
工作原理
- 为节点添加标签:
kubectl label nodes <node-name> disktype=ssd
- Pod 只会被调度到具有匹配标签的节点上
- 如果没有任何节点拥有匹配的标签,Pod 将保持 Pending 状态
注意: nodeSelector 提供的是"硬性"要求,必须完全匹配所有指定的标签。
nodeName:直接指定节点
nodeName
是更为直接的调度方式,它明确指定 Pod 应该运行在哪个节点上。
使用方式
pod-nodeName.yaml复制代码
apiVersion: v1 kind: Pod metadata:name: nginx-pod spec:containers:- name: nginximage: nginx:1.14.2nodeName: k8s-node-1
注意事项
- 绕过正常的调度器,直接指定目标节点
- 如果指定的节点不存在或资源不足,Pod 将无法运行
- 通常用于测试或特定场景,生产环境中应谨慎使用
注意: 使用 nodeName 会绕过调度器的所有过滤和评分逻辑,可能导致资源利用不均衡。
Affinity:高级亲和性调度
节点亲和性(Affinity)提供了比 nodeSelector
更强大的调度能力,支持更复杂的调度规则。
节点亲和性类型
硬亲和性(Required)
pod-affinity-required.yaml复制代码
apiVersion: v1 kind: Pod metadata:name: nginx-pod spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: disktypeoperator: Invalues:- ssd- nvmecontainers:- name: nginximage: nginx:1.14.2
软亲和性(Preferred)
pod-affinity-preferred.yaml复制代码
apiVersion: v1 kind: Pod metadata:name: nginx-pod spec:affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 1preference:matchExpressions:- key: environmentoperator: Invalues:- productioncontainers:- name: nginximage: nginx:1.14.2
操作符类型
In
:标签值在列表中NotIn
:标签值不在列表中Exists
:标签存在DoesNotExist
:标签不存在Gt
:标签值大于指定值(用于数值)Lt
:标签值小于指定值(用于数值)
提示: 亲和性规则还支持 Pod 间亲和性和反亲和性,用于控制 Pod 之间的部署关系。
Tolerations:容忍度机制
容忍度(Tolerations)允许 Pod 调度到带有污点(Taints)的节点上,与节点的污点机制配合使用。
污点和容忍度的工作机制
首先为节点添加污点:
命令复制代码
kubectl taint nodes node1 key=value:NoSchedule
然后在 Pod 中配置容忍度:
pod-tolerations.yaml复制代码
apiVersion: v1 kind: Pod metadata:name: nginx-pod spec:containers:- name: nginximage: nginx:1.14.2tolerations:- key: "key"operator: "Equal"value: "value"effect: "NoSchedule"
污点效果类型
NoSchedule
:不会调度新 Pod(已运行的不受影响)PreferNoSchedule
:尽量避免调度NoExecute
:不会调度新 Pod,且会驱逐已运行的 Pod
高级容忍度配置
pod-tolerations-advanced.yaml复制代码
tolerations: - key: "node.kubernetes.io/unreachable"operator: "Exists"effect: "NoExecute"tolerationSeconds: 6000 - key: "dedicated"operator: "Equal"value: "gpu"effect: "NoSchedule"
注意: 容忍度不会保证 Pod 一定会被调度到有污点的节点上,只是允许这种可能性。
调度机制对比
机制 | 使用场景 | 优点 | 缺点 |
---|---|---|---|
nodeSelector | 简单的标签匹配 | 简单易用,配置直观 | 功能有限,只支持硬性要求 |
nodeName | 直接指定节点 | 完全控制 Pod 位置 | 绕过调度器,可能导致资源不均 |
Affinity | 复杂的调度需求 | 功能强大,支持软硬规则 | 配置相对复杂 |
Tolerations | 专用节点或故障隔离 | 与污点配合实现节点专用 | 需要与污点配合使用 |