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

调度流程详解#

调度流程分为以下阶段:

  1. 预选(PreFilter)
    - 预处理 Pod 与集群资源
    - 计算 Pod 所需资源与约束

  2. 过滤(Filter)
    - 筛除不满足条件的节点
    - 例如资源不足、节点不可用、污点不容忍

  3. 预打分(PreScore)
    - 准备评分所需数据
    - 可计算拓扑、负载等信息

  4. 打分(Score)
    - 对可选节点进行评分
    - 常见评分因素:资源余量、负载均衡、亲和性等

  5. 选择(Reserve/Permit)
    - 选择得分最高节点
    - 可进行排队许可、预留资源

  6. 绑定(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 可以被调度到带有相应污点的节点。

练习与验证#

  1. 创建一个 CPU 资源请求过高的 Pod,观察 Pending 原因并调整请求使其可调度。
  2. 给节点打污点并创建不含容忍度的 Pod,验证调度失败;随后添加容忍度验证恢复。
  3. 观察默认调度器日志中 FilterScore 阶段的输出,记录一次成功调度的关键日志行。

练习示例:资源请求调整#

# 资源请求过高
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"}]'

通过理解调度流程与架构并配合可执行示例、排错与练习,可以更有效地控制资源分配、提升集群稳定性,并为后续调度策略优化打下坚实基础。