目录

前言

一、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 的创建是调度机制的完整体现,整个生命周期需多组件协同完成,核心流程如下:

  1. 组件启动监听:Controller Manager、Scheduler、kubelet 启动后,通过 HTTPS 6443 端口监听 APIServer 的资源事件变化(Controller Manager 监听副本控制对象、Scheduler 监听未调度 Pod、kubelet 监听本节点 Pod)。
  2. 用户发起创建请求:通过kubectl apply -f pod.yaml提交 Pod 创建请求,APIServer 校验请求合法性后,将 Pod 元数据写入 etcd。
  3. 事件触发与副本保障:etcd 写入成功后触发 Create 事件,Controller Manager 监听到事件后,通过 RC/ReplicaSet 确保 Pod 副本数符合预期(不足则创建新副本)。
  4. 调度器分配节点:Scheduler 监听到处于 Pending 状态(未绑定节点)的 Pod 后,通过调度算法筛选出合适节点,将节点信息写入 APIServer,etcd 更新 Pod 的 Node 绑定关系。
  5. 节点创建容器:kubelet 监听到分配给本节点的 Pod 后,调用容器运行时(Docker/containerd)拉取镜像、创建并启动容器,随后将 Pod 状态(Running/Failed)上报 APIServer。
  6. 状态同步完成:APIServer 将 Pod 状态更新至 etcd,集群状态同步完成,Pod 正式进入 Running 状态。

关键补充

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 调度的关键。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐