目录
前言
一、K8s 集群调度核心组件与协作机制
核心协作逻辑
二、Pod 创建全流程:List-Watch 模型实战
关键补充
三、Scheduler 调度器:如何为 Pod 选 “家”?
1. 调度目标
2. 调度流程
(1)过滤阶段(Predicate):筛选合格节点
(2)优选阶段(Priorities):为节点打分排序
四、指定调度节点:两种常用方式
1. nodeName:强制绑定节点
验证命令:
应用YAML文件创建资源
查看Pod详细信息(包括节点分配)
2. nodeSelector:基于标签匹配节点
1.为节点添加标签:
2.配置 Pod 的 nodeSelector(myapp1.yaml):
3.应用配置并验证:
管理 Node 标签命令:
总结
前言
在 Kubernetes(简称 K8s)集群中,调度是连接应用部署与资源分配的关键环节。它负责将 Pod 合理分配到集群节点上,确保资源高效利用、应用稳定运行。本文将从组件协作、Pod 创建流程、调度器工作原理、调度策略到故障排查,全面拆解 K8s 集群调度的核心内容,帮助你从理论到实践掌握调度机制。
一、K8s 集群调度核心组件与协作机制
K8s 通过List-Watch 机制实现各组件的解耦与实时数据同步,整个调度体系依赖以下核心组件的协同工作:
| kubectl / API 客户端 | 向 APIServer 发起 Pod 创建、更新等资源操作请求 |
| APIServer | 作为集群控制入口,处理权限校验、API 调用以及与 etcd 的数据交互 |
| etcd | 分布式键值存储系统,持久化保存集群所有状态信息(包括 Pod 配置、节点状态等) |
| Controller Manager | 负责维护副本数量,执行自愈逻辑(如自动扩容、重建故障 Pod) |
| Scheduler | 核心调度模块,为未分配节点的 Pod 选择最优运行节点 |
| kubelet | 节点代理组件,管理 Pod 生命周期(包括容器创建、状态监控与上报) |
核心协作逻辑
用户通过 kubectl 发送的所有操作请求,最终都会经由 APIServer 写入 etcd;etcd 状态变化会触发事件通知,APIServer 将事件广播给监听的组件(Controller Manager、Scheduler、kubelet);各组件根据事件类型执行对应逻辑,确保集群状态与期望一致。
二、Pod 创建全流程:List-Watch 模型实战
Pod 的创建是调度机制的完整体现,整个生命周期需多组件协同完成,核心流程如下:
关键补充
kubelet 会持续监听 Pod 事件,即便 Pod 创建完成后,也能响应副本数调整、镜像更新等动态操作,确保应用始终符合预期配置。
三、Scheduler 调度器:如何为 Pod 选 “家”?
Scheduler 的核心任务是为spec.nodeName == ""(未绑定节点)的 Pod 分配最优节点,其调度过程遵循 “过滤 – 优选” 两步法,同时兼顾公平性、高效性与灵活性。
1. 调度目标
- 公平性:节点间资源分配均衡,避免单点负载过高;
- 高效性:最大化集群资源利用率,减少资源浪费;
- 高性能:快速完成大批量 Pod 调度,不影响集群响应速度;
- 灵活性:支持自定义调度策略与插件。
2. 调度流程
(1)过滤阶段(Predicate):筛选合格节点
过滤阶段会排除不满足 Pod 运行条件的节点,常见过滤算法如下:
| PodFitsResources | 验证节点剩余 CPU 和内存资源是否能够满足 Pod 的资源需求 |
| PodFitsHost | 检查 Pod 指定的 nodeName 是否与当前节点名称匹配 |
| PodFitsHostPorts | 确保 Pod 请求的端口未被节点上其他服务占用,避免端口冲突 |
| PodSelectorMatches | 校验节点标签是否符合 Pod 定义的 label 选择器条件 |
| NoDiskConflict | 检测 Pod 需要挂载的存储卷是否与节点现有挂载存在冲突 |
若无节点通过过滤,Pod 将一直处于 Pending 状态,直至有节点满足条件。
(2)优选阶段(Priorities):为节点打分排序
对过滤后的合格节点,按优先级算法打分(权重越高越优先),常见算法如下:
以下为 Kubernetes 调度器优先级策略的表格整理:
| LeastRequestedPriority | 节点资源使用率越低,得分越高 | 优先分配空闲节点,提高资源利用率 |
| BalancedResourceAllocation | CPU 与内存使用率越接近(平衡),得分越高 | 避免单一资源过载,均衡节点负载 |
| ImageLocalityPriority | 节点已存在 Pod 所需镜像时得分更高(镜像层匹配越多得分越高) | 减少镜像拉取时间,加速 Pod 启动过程 |
最终,Scheduler 选择得分最高的节点完成 Pod 调度。
四、指定调度节点:两种常用方式
除了 Scheduler 自动调度,K8s 支持手动指定 Pod 调度节点,满足特殊场景需求(如特定硬件依赖、数据本地化)。
1. nodeName:强制绑定节点
直接在 Pod 配置中指定spec.nodeName,跳过 Scheduler 调度策略,强制将 Pod 部署到目标节点。
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
nodeName: node01 # 强制调度到node01
containers:
– name: myapp
image: soscscs/myapp:v1
ports:
– containerPort: 80
验证命令:
应用YAML文件创建资源
kubectl apply -f myapp.yaml
查看Pod详细信息(包括节点分配)
kubectl get pods -o wide
2. nodeSelector:基于标签匹配节点
通过节点标签(Label)与 Pod 的nodeSelector匹配,由 Scheduler 完成调度,属于强制约束。
操作步骤:
1.为节点添加标签:
kubectl label nodes node01 yjs=a
kubectl label nodes node02 yjs=b
2.配置 Pod 的 nodeSelector(myapp1.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp1
spec:
replicas: 3
selector:
matchLabels:
app: myapp1
template:
metadata:
labels:
app: myapp1
spec:
nodeSelector:
yjs: a # 节点选择器,确保Pod只调度到带有yjs=a标签的节点
containers:
– name: myapp1
image: soscscs/myapp:v1
ports:
– containerPort: 80
3.应用配置并验证:
kubectl apply -f myapp1.yaml
kubectl get pods -o wide
管理 Node 标签命令:
# 为节点 node01 添加标签 yjs=a
kubectl label nodes node01 yjs=a
# 查看所有节点及其标签(显示标签列)
kubectl get nodes –show-labels
# 通过标签选择器查询特定节点(yjs=a)
kubectl get node -l yjs=a
# 强制覆盖修改节点 node02 的标签值(yjs=b)
kubectl label nodes node02 yjs=b –overwrite
# 删除节点 node02 的 yjs 标签
kubectl label nodes node02 yjs-
总结
K8s 调度机制的核心价值的是通过标准化流程与可配置策略,平衡 “自动化分配” 与 “个性化需求”,确保集群资源高效利用与应用稳定运行。理解组件协作、调度算法与指定调度方式,是掌握 K8s 调度的关键。



