Kubernetes中Pod的调度由默认调度器kube-scheduler完成,核心目标是将Pod分配到满足资源需求且符合策略的节点上。整个过程分为过滤(Predicates) 和打分(Priorities) 两个阶段,最终通过绑定(Binding)完成调度。让我们一图看懂整个流程。
1. 调度触发与初始阶段
- 创建请求提交:用户通过
kubectl
或API创建Pod,请求由API Server接收并写入etcd1。 - 未调度Pod监听:调度器通过
list-watch
机制监听API Server,筛选出spec.nodeName
为空的Pod23。
2. 过滤阶段(Predicates)
调度器根据以下条件过滤不满足要求的节点:
- 资源需求:检查节点的CPU、内存、GPU等资源是否满足Pod请求23。
- 节点标签匹配:若Pod配置了
nodeSelector
,需确保节点标签匹配45。 - 端口冲突:节点上无端口冲突3。
- 污点与容忍度:节点污点(Taints)需与Pod的容忍度(Tolerations)匹配5。
- 亲和性规则:验证节点是否满足Pod的亲和性(Affinity)或反亲和性(Anti-Affinity)要求35。
3. 打分阶段(Priorities)
通过过滤的节点进入评分阶段,调度器基于以下因素计算得分:
- 资源均衡:优先选择资源利用率较低的节点23。
- 数据局部性:若Pod需访问特定存储卷,优先选择存储所在的节点3。
- 亲和性权重:满足亲和性规则的节点获得更高分数5。
- 拓扑约束:如跨机架/可用区分布需求3。
4. 绑定与执行
- 节点选择:得分最高的节点被选中,调度器将
spec.nodeName
写入Pod并通知API Server更新etcd23。 - kubelet接管:目标节点的kubelet监听到调度结果后,拉取Pod镜像并启动容器14。
特殊调度方式
- 强制指定节点:通过
nodeName
字段直接绑定Pod到指定节点(绕过调度器)24。 - 污点容忍:节点可标记为“不可调度”,但Pod通过
tolerations
声明容忍后仍可运行5。