16.6.1 调度流程与调度器架构
调度流程与调度器架构是理解 Kubernetes 资源分配与运行稳定性的基础。本节从调度请求触发、内部阶段、插件化架构、HA 与性能等角度,结合安装查看、命令验证、排错与练习,帮助你掌握调度器如何为 Pod 选择节点并形成可控决策。
调度触发与核心概念#
调度器负责为未绑定节点(Pending)的 Pod 选择目标节点。常见触发场景:
- 新建 Pod 未指定 nodeName
- 节点故障导致 Pod 重新调度
- 控制器重建或扩缩容
关键对象:
- Pod:待调度对象
- Node:可供调度的计算资源
- Scheduler:调度器本体
- Binding:将 Pod 绑定到目标节点的操作
示例:触发调度与观察事件#
# 创建一个不指定 nodeName 的 Pod
cat > /tmp/pod-pending.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
containers:
- name: nginx
image: nginx:1.25
resources:
requests:
cpu: "100m"
memory: "128Mi"
EOF
kubectl apply -f /tmp/pod-pending.yaml
# 观察调度事件
kubectl describe pod demo-pod | sed -n '/Events/,$p'
预期效果:Events 中出现 Scheduled 事件,显示 default-scheduler 选择的节点。
调度器的整体架构#
Kubernetes 默认调度器(kube-scheduler)由以下核心组件构成:
- 调度队列:维护待调度 Pod 队列
- 调度循环:主循环,完成调度决策
- 调度框架(Scheduling Framework):插件化执行流程
- 绑定器:执行 Pod 与 Node 的绑定操作
- 可扩展插件:用户自定义调度逻辑
原理草图(调度器架构)#
安装与查看(kubeadm 集群)#
# kube-scheduler 在控制平面节点运行
kubectl -n kube-system get pods -l component=kube-scheduler -o wide
# 查看调度器配置文件(kubeadm 默认路径)
ls -l /etc/kubernetes/manifests/kube-scheduler.yaml
调度流程详解#
调度流程分为以下阶段:
-
预选(PreFilter)
- 预处理 Pod 与集群资源
- 计算 Pod 所需资源与约束 -
过滤(Filter)
- 筛除不满足条件的节点
- 例如资源不足、节点不可用、污点不容忍 -
预打分(PreScore)
- 准备评分所需数据
- 可计算拓扑、负载等信息 -
打分(Score)
- 对可选节点进行评分
- 常见评分因素:资源余量、负载均衡、亲和性等 -
选择(Reserve/Permit)
- 选择得分最高节点
- 可进行排队许可、预留资源 -
绑定(Bind/PostBind)
- 将 Pod 绑定到目标节点
- 更新 API Server 中的 Pod 资源
原理草图(阶段链路)#
调度框架与插件机制#
调度框架支持插件化扩展,插件可插入到以下阶段:
- QueueSort
- PreFilter
- Filter
- PostFilter
- PreScore
- Score
- Reserve
- Permit
- PreBind
- Bind
- PostBind
常见内置插件:
- NodeResourcesFit:资源匹配
- NodeAffinity:亲和性
- TaintToleration:污点容忍
- PodTopologySpread:拓扑分散
- DefaultPreemption:抢占策略
示例:查看调度器使用的插件配置#
# kube-scheduler 配置文件路径示例
SCHED_CFG=/etc/kubernetes/scheduler-config.yaml
# 查看是否存在插件配置
sudo sed -n '1,200p' $SCHED_CFG
# 如果配置在静态 Pod manifest 中,则查看参数
sudo sed -n '1,200p' /etc/kubernetes/manifests/kube-scheduler.yaml
示例配置(节选):
# /etc/kubernetes/scheduler-config.yaml
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
score:
enabled:
- name: NodeResourcesFit
- name: PodTopologySpread
filter:
enabled:
- name: NodeAffinity
- name: TaintToleration
预期效果:调度器根据插件配置执行对应阶段逻辑。
调度器的高可用与性能#
调度器通过 Leader Election 实现高可用,多实例部署时只允许一个生效:
- 失败自动切换
- 避免调度冲突
性能要点:
- 调度速率可配置
- 支持并发调度
- 调度缓存减少频繁访问 API Server
示例:查看调度器 Leader 选举配置#
# 在静态 Pod manifest 中查看 leader-elect 参数
grep -n "leader-elect" -n /etc/kubernetes/manifests/kube-scheduler.yaml
# 查看调度器日志,确认领导者信息(容器日志)
kubectl -n kube-system logs -l component=kube-scheduler --tail=50 | grep -i leader
自定义调度器与扩展场景#
自定义调度器适用于:
- 多租户隔离
- GPU/AI 资源优先
- 成本/能耗优化
- 业务优先级调度
实现方式:
- Fork kube-scheduler
- 利用调度框架编写插件
- 独立实现调度器并注册
示例:指定自定义调度器名称#
# /tmp/pod-custom-scheduler.yaml
apiVersion: v1
kind: Pod
metadata:
name: demo-custom-scheduler
spec:
schedulerName: my-scheduler
containers:
- name: nginx
image: nginx:1.25
kubectl apply -f /tmp/pod-custom-scheduler.yaml
kubectl get pod demo-custom-scheduler -o wide
预期效果:Pod 的 SCHEDULER 字段显示 my-scheduler,前提是自定义调度器已部署。
调度流程中的关键排障点#
- Pod 一直 Pending:检查资源是否满足、污点/亲和性限制
- 节点可用但未调度:检查调度插件限制或资源碎片化
- 调度慢:观察调度器日志与事件,关注过滤与评分耗时
排错命令清单(含说明)#
# 1) 查看 Pod Pending 原因
kubectl describe pod demo-pod | sed -n '/Events/,$p'
# 2) 查看节点资源与状态
kubectl get nodes -o wide
kubectl describe node <node-name> | sed -n '/Allocated resources/,$p'
# 3) 查看污点与容忍度
kubectl describe node <node-name> | grep -n "Taints"
kubectl get pod demo-pod -o yaml | grep -n "tolerations" -n
# 4) 查看调度器日志
kubectl -n kube-system logs -l component=kube-scheduler --tail=200
典型问题与修复示例#
# 示例:因污点导致无法调度,给 Pod 增加容忍度
cat > /tmp/pod-toleration.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: demo-toleration
spec:
tolerations:
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: nginx
image: nginx:1.25
EOF
kubectl apply -f /tmp/pod-toleration.yaml
预期效果:Pod 可以被调度到带有相应污点的节点。
练习与验证#
- 创建一个 CPU 资源请求过高的 Pod,观察 Pending 原因并调整请求使其可调度。
- 给节点打污点并创建不含容忍度的 Pod,验证调度失败;随后添加容忍度验证恢复。
- 观察默认调度器日志中
Filter与Score阶段的输出,记录一次成功调度的关键日志行。
练习示例:资源请求调整#
# 资源请求过高
cat > /tmp/pod-high-cpu.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: demo-high-cpu
spec:
containers:
- name: busybox
image: busybox:1.36
command: ["sh","-c","sleep 3600"]
resources:
requests:
cpu: "8"
memory: "256Mi"
EOF
kubectl apply -f /tmp/pod-high-cpu.yaml
kubectl describe pod demo-high-cpu | sed -n '/Events/,$p'
# 调整为可调度
kubectl patch pod demo-high-cpu --type='json' \
-p='[{"op":"replace","path":"/spec/containers/0/resources/requests/cpu","value":"200m"}]'
通过理解调度流程与架构并配合可执行示例、排错与练习,可以更有效地控制资源分配、提升集群稳定性,并为后续调度策略优化打下坚实基础。