Kubernetes 集群调度
Kubernetes 调度是一个多层次、可扩展的决策过程,涵盖了从基础资源匹配到高级调度策略的完整链路。通过:基础调度机制(如 nodeName、nodeSelector)实现简单绑定;亲和性与反亲和性 实现 Pod 与节点、Pod 与 Pod 之间的精细化调度;污点与容忍 控制节点与 Pod 的互斥与兼容关系;节点维护操作(cordon / drain / uncordon)保障集群运维过程中的
前言
Kubernetes 作为现代容器编排系统的核心,其调度机制是集群资源管理与应用高可用的基石。调度器(Scheduler)负责将 Pod 合理、高效地分配到集群中的节点上,不仅影响资源利用率,也直接关系到服务的稳定性和性能。
本文系统梳理了 Kubernetes 调度器的核心工作机制、调度策略、节点亲和与反亲和、污点与容忍等关键概念,并提供了节点维护与常见故障排查的实用命令,旨在帮助开发者和运维人员深入理解并灵活运用调度策略,构建稳定、高效的 Kubernetes 集群环境。
1 Kubernetes 组件协作机制
Kubernetes 通过 List-Watch 机制使各个组件协作、数据同步,从而实现解耦与实时一致性。
关键组件关系
| 组件 | 职责 |
|---|---|
| kubectl / API 客户端 | 向 APIServer 发起资源创建或管理请求 |
| APIServer | 负责 API 调用、权限校验、存储交互,是集群控制的核心入口 |
| etcd | 存储集群所有状态信息 |
| Controller Manager | 维持副本数、执行自愈逻辑(扩容、重建等) |
| Scheduler | 调度器,将未分配节点的 Pod 分配到合适的 Node |
| kubelet | 节点代理,负责 Pod 生命周期管理和容器运行状态上报 |
2 Scheduler工作过程
2.1 核心任务
将 未绑定 Node 的 Pod 分配到合适的节点
2.2 调度特性
- 公平性:节点间资源分配均衡
- 高效性:集群所有资源最大化被使用
- 效 率:调度的性能要好,能够尽快地对大批量的 pod 完成调度工作
- 灵活性:允许自定义策略(调度策略、插件)
2.3 调度流程
2.3.1 过滤阶段(Predicate)
常见过滤算法:
| 算法名 | 功能描述 |
|---|---|
| PodFitsResources | 检查节点剩余资源是否满足 Pod 需求 |
| PodFitsHost | 检查 NodeName 是否匹配 |
| PodFitsHostPorts | 检查端口冲突 |
| PodSelectorMatches | label 匹配 |
| NoDiskConflict | Volume 挂载冲突检测 |
2.3.2 优选阶段(Priorities)
常见算法:
| 优先级项 | 描述 |
|---|---|
| LeastRequestedPriority | 资源使用率越低,权重越高 |
| BalancedResourceAllocation | CPU 与内存使用率越接近越好(这个一般和上面的一起使用,不单独使用) |
| ImageLocalityPriority | 优先节点上已有目标镜像的节点 |
3 调度节点的方式
3.1 强制绑定与标签匹配
3.1.1 nodeName(强制绑定)
将 Pod 直接调度到指定的 Node 节点上,会跳过 Scheduler 的调度策略,该匹配规则是强制匹配
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
nodeName: node01 # 将 pod 强制绑定到 node01 上
containers:
- name: myapp
image: soscscs/myapp:v1
ports:
- containerPort: 80
3.1.2 nodeSelector(标签匹配)
通过 kubernetes 的 label-selector 机制选择节点,由调度器调度策略匹配 label,然后调度 Pod 到目标节点,该匹配规则属于强制约束
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp1
spec:
replicas: 3
selector:
matchLabels:
app: myapp1
template:
metadata:
labels:
app: myapp1
spec:
nodeSelector:
yjs: a # 节点标签键值对,用于筛选符合条件的节点
containers:
- name: myapp1
image: soscscs/myapp:v1
ports:
- containerPort: 80
3.1.3 管理 Node 标签的命令
kubectl label nodes node01 yjs=a
kubectl get nodes --show-labels
# 指定标签查询 node 节点
kubectl get node -l yjs=a
# 修改一个 label 的值,需要加上 --overwrite 参数
kubectl label nodes node02 yjs=b --overwrite
# 删除一个 label,只需在命令行最后指定 label 的 key 名并与一个减号相连即可
kubectl label nodes node02 yjs-
3.2 亲和性策略
| 调度策略 | 匹配标签 | 操作符 | 拓扑域支持 | 调度目标 |
|---|---|---|---|---|
| nodeAffinity(节点亲和性) | 主机 | In, NotIn, Exists,DoesNotExist, Gt, Lt | ❌ | 指定主机 |
| podAffinity(pod 亲和性) | Pod | In, NotIn, Exists,DoesNotExist | ✅ | 与指定 Pod 同域 |
| podAntiAffinity(pod 反亲和性) | Pod | In, NotIn, Exists,DoesNotExist | ✅ | 与指定 Pod 不同域 |
3.2.1 节点亲和性(NodeAffinity)
核心概念:将具有 pod 的值添加到具有 label 的 node 节点上
3.2.1.1 操作符含义
| 操作符 | 含义 | 示例 |
|---|---|---|
| In | label 的值在列表中 | env In (dev, test) → 选出 env=dev 或 env=test 的 Pod |
| NotIn | label 的值不在列表中 | env NotIn (prod) → 除了生产环境都选上 |
| Gt | label 的值大于某个数 | version Gt 3 → 选出 version=4,5,6… 的 Pod |
| Lt | label 的值小于某个数 | version Lt 3 → 选出 version=1,2 的 Pod |
| Exists | label 存在即可 | Exists zone → 只要有 zone 这个标签 |
| DoesNotExist | label 不存在 | DoesNotExist debug → 没有 debug 标签的 Pod |
简单理解
In / NotIn 看“名单”,
Gt / Lt 看“数值”,
Exists / DoesNotExist 看“有没有”。
3.2.1.2 硬策略
- 硬策略(强制性策略):必须满足的条件。如果不满足,Pod 会一直处于
Pending状态,不会被调度。规则是“硬性”的
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
affinity: # 亲和性配置
nodeAffinity: # 节点亲和性配置
requiredDuringSchedulingIgnoredDuringExecution: # 硬策略:调度期间必须满足,运行期间忽略
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname # 指定node的标签
operator: NotIn # 不在指定的值列表中
values:: # 即不选择node02节点
- node02
3.2.1.3 软策略
- 软策略(偏好性策略):应该满足的条件。调度器会尝试寻找满足这些条件的节点,但如果实在找不到,也会选择一个不满足条件的节点将 Pod 调度上去。规则是“软性”的,带有权重,weight 数值越小,优先级越高
apiVersion: v1
kind: Pod
metadata:
name: affinity
labels:
app: node-affinity-pod
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1 #如果有多个软策略选项的话,数值越小,优先级越高
preference:
matchExpressions:
- key: kubernetes.io/hostname
operator: In # 偏好的值列表
values: # 即优先选择node02
- node02
3.2.2 pod的亲和性与反亲和性
定义了 Pod 之间的**“吸引”和“排斥”**关系
- Pod 亲和性: “ 将我调度到有 ‘朋友’ Pod 的节点(或区域)上 ”
- Pod 反亲和性: “ 不要将我调度到有 ‘敌人’ Pod 的节点(或区域)上 ”
3.2.2.1 pod 的亲和性
apiVersion: v1
kind: Pod
metadata:
name: myapp02 # Pod名称
labels:
app: myapp02 # 给Pod打上标签 app=myapp02
spec:
containers:
- name: myapp02 # 容器名称
image: soscscs/myapp:v1 # 容器镜像
affinity: # 亲和性配置
podAffinity: # Pod亲和性 - 表示这个Pod希望和某些Pod部署在一起
requiredDuringSchedulingIgnoredDuringExecution: # 硬策略:调度期间必须满足,运行期间忽略
- labelSelector: # 标签选择器,用于选择目标Pod
matchExpressions: # 匹配表达式
- key: app # 要匹配的标签键
operator: In # 操作符:在指定的值列表中
values: # 要匹配的标签值列表
- myapp05 # 具体值:app=myapp01
topologyKey: yjs # 拓扑域键:使用自定义标签 "yjs"
------------------------------------------------------------------------------------------------------------
# 这是一个硬策略,必须将 myapp02 放到有运行 myapp05 且带有 yjs 标签的节点上
3.2.2.2 pod 的反亲和性
apiVersion: v1
kind: Pod
metadata:
name: myapp10 # Pod名称
labels:
app: myapp10 # 给Pod打上标签 app=myapp10
spec:
containers:
- name: myapp10 # 容器名称
image: soscscs/myapp:v1 # 容器镜像
affinity: # 亲和性配置
podAntiAffinity: # Pod反亲和性 - 表示这个Pod希望避开某些Pod
preferredDuringSchedulingIgnoredDuringExecution: # 软策略:调度期间优先考虑,运行期间忽略
- weight: 100 # 权重值(1-100),在有多个偏好规则时决定优先级
podAffinityTerm: # 反亲和性规则的具体定义
labelSelector: # 标签选择器,用于选择要避开的Pod
matchExpressions: # 匹配表达式
- key: app # 要匹配的标签键
operator: In # 操作符:在指定的值列表中
values: # 要匹配的标签值列表
- myapp02 # 具体值:app=myapp01
topologyKey: kubernetes.io/hostname # 拓扑域键:节点主机名
------------------------------------------------------------------------------------------------------------
# 这是一个软策略,尽量避免将 myapp10 放到有运行 myapp02 的节点上
3.2 污点和容忍
3.2.1 核心概念
- 污点:应用于节点上的一个标记。它表示该节点只允许带有**“容忍”**配置的 Pod 被调度上来
- 容忍:应用于 Pod 上的一个配置。它表示这个 Pod 能够**“容忍”某些污点**,从而可以被调度到拥有对应污点的节点上。
3.2.2 污点 (Taint)
污点是一个三元组,格式为:key=value:effect
-
key:污点的键(可选值,但通常都会设置)
-
value:污点的值(可以为空)
-
effect:污点的效果(必须)。有以下三种效果:
类型 描述 NoSchedule 不调度到此节点 PreferNoSchedule 尽量避免调度具有该污点的 Node 上 NoExecute 不调度 + 驱逐已存在 Pod
#设置污点
kubectl taint node node01 key1=value1:NoSchedule
#节点说明中,查找 Taints 字段
kubectl describe node node-name | grep -i taints
#去除污点
kubectl taint node node01 key1:NoSchedule-
3.2.3 容忍 (Tolerations)
3.2.3.1 完全匹配(Equal)
tolerations:
- key: "gpu"
operator: "Equal" # 操作符,Equal 表示完全匹配
value: "true" # 必须匹配 value
effect: "NoSchedule"
这个 Pod 能容忍键为 gpu、值为 true、效果为 NoSchedule 的污点
3.2.3.2 存在即匹配(Exists)
tolerations:
- key: "gpu" # 只要存在 key 为 “gpu” 的污点...
operator: "Exists" # ...就容忍,不关心 value 是什么
effect: "NoSchedule"
tolerationSeconds: 60 # 当污点被添加后,还能在此节点上运行 60 秒
这个 Pod 能容忍任何效果为 NoSchedule 且键为 gpu 的污点,无论其值是什么
3.2.3.3 容忍 NoExecute 并设置容忍时间
tolerations:
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 60 # 当污点被添加后,还能在此节点上运行 60 秒
Pod 可以容忍一段时间,给节点一个恢复的机会,超过 tolerationSeconds 后才会被驱逐。
4 节点维护操作***
🧱 cordon & drain
| 命令 | 功能 |
|---|---|
kubectl cordon <node> |
标记为不可调度 |
kubectl drain <node> --ignore-daemonsets --delete-local-data --force |
驱逐 Pod |
kubectl uncordon <node> |
恢复可调度状态 |
drain 等价于 “cordon + 驱逐”。
在 Kubernetes 中,驱逐(Eviction)是指将运行中的 Pod 从一个节点上迁移到另一个节点的过程,同时释放原节点上的资源以供其他使用。驱逐通常发生在以下情况:
- 需要将 Pod 迁移到其他节点以维护节点或进行软硬件升级。
- 某个节点的资源不足以容纳新的 Pod,需要将旧的 Pod 驱逐以释放资源。
Kubernetes 可以使用自动驱逐机制来管理 Pod 的迁移。它可以基于节点负载、Pod 优先级等条件来自动选择需要驱逐的 Pod,并将它们迁移到其他节点上。在执行驱逐时,Kubernetes 会首先将 SIGTERM 信号发送给 Pod,然后等待一段时间,让 Pod 自行终止。如果自我终止未成功,则 Kubernetes 会强制终止 Pod 并进行清理工作。
驱逐是 Kubernetes 集群中必不可少的机制之一,它可以确保系统的高冗余性和高可用性,并优化集群中的资源利用率。
5 故障排查命令
| 操作 | 命令 |
|---|---|
| 查看事件 | kubectl describe pod <POD> |
| 查看日志 | kubectl logs <POD> [-c 容器名] |
| 进入容器 | kubectl exec -it <POD> bash |
| 查看集群状态 | kubectl cluster-info |
| 查看节点状态 | kubectl get nodes |
| 查看 kubelet 日志 | journalctl -xefu kubelet |
6 总结
Kubernetes 调度是一个多层次、可扩展的决策过程,涵盖了从基础资源匹配到高级调度策略的完整链路。通过:
-
基础调度机制(如 nodeName、nodeSelector)实现简单绑定;
-
亲和性与反亲和性 实现 Pod 与节点、Pod 与 Pod 之间的精细化调度;
-
污点与容忍 控制节点与 Pod 的互斥与兼容关系;
-
节点维护操作(cordon / drain / uncordon)保障集群运维过程中的服务连续性;
-
完备的故障排查命令 帮助快速定位调度与运行问题。
掌握这些调度机制与操作,能够显著提升集群的资源利用率、服务质量与运维效率,为构建生产级 Kubernetes 平台奠定坚实基础。
更多推荐

所有评论(0)