引言:从“随机分配”到“智能调度”
想象你的Kubernetes集群是一个繁忙的物流中心,节点(Node)是仓库,Pod是货物。
- 默认调度器 就像一名普通分拣员,简单地将货物塞进最近的仓库,可能导致某些仓库爆满,而其他仓库闲置。
- 高级调度策略 则像一名经验丰富的调度员,根据货物类型、仓库容量和交通规则,精准分配资源。
本文将揭秘Kubernetes调度器的核心机制,教你如何用 节点亲和性、污点与容忍 等策略,让Pod像“智能包裹”一样精准落位!
一、调度器基础:Pod如何选择节点?
1.1 默认调度流程
当创建一个Pod时,调度器会经过两阶段筛选:
- 过滤(Filtering):排除不满足条件的节点(如资源不足、标签不匹配)。
- 打分(Scoring):对剩余节点评分,选择最优节点(如资源最空闲的节点)。
1.2 查看调度详情
通过kubectl describe pod
可查看调度决策过程:
kubectl describe pod my-pod
输出示例:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10s default-scheduler Successfully assigned default/my-pod to node-02
二、节点亲和性(Node Affinity):Pod的“偏好清单”
2.1 什么是节点亲和性?
- 作用:让Pod优先调度到特定节点(如GPU节点、高IO性能节点)。
- 匹配规则:基于节点标签(Labels)进行筛选。
2.2 实战:强制Pod运行在特定节点
步骤1:为节点添加标签
# 标记节点node-01为“高速存储”类型
kubectl label nodes node-01 disk-type=ssd
步骤2:配置节点亲和性规则
# pod-with-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
name: fast-storage-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬性要求
nodeSelectorTerms:
- matchExpressions:
- key: disk-type
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx:latest
2.3 高级用法:软性偏好与权重
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 软性偏好
- weight: 60 # 权重(0-100)
preference:
matchExpressions:
- key: zone
operator: In
values:
- east
- weight: 40
preference:
matchExpressions:
- key: zone
operator: In
values:
- west
三、污点与容忍(Taint & Toleration):节点的“禁区”与Pod的“通行证”
3.1 核心概念
- 污点(Taint):标记节点,阻止未授权的Pod调度。
- 容忍(Toleration):Pod携带的“通行证”,允许调度到有污点的节点。
典型场景:
- 保留节点给特定任务(如GPU机器学习任务)。
- 驱逐节点上的普通Pod(通过
NoExecute
污点)。
3.2 实战:限制Pod调度到专用节点
步骤1:为节点添加污点
# 标记node-01为GPU专用节点
kubectl taint nodes node-01 gpu=true:NoSchedule # 格式:key=value:effect
步骤2:为Pod配置容忍
# gpu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: ai-training-pod
spec:
tolerations:
- key: "gpu" # 匹配污点的key
operator: "Equal" # 匹配方式(Equal/Exists)
value: "true" # 匹配污点的value
effect: "NoSchedule" # 匹配污点的effect
containers:
- name: tensorflow
image: tensorflow/tensorflow:latest-gpu
3.3 污点效果(Effect)详解
- NoSchedule:禁止新Pod调度(除非有匹配容忍)。
- PreferNoSchedule:尽量不调度,非强制。
- NoExecute:驱逐现有Pod(需设置
tolerationSeconds
容忍时间)。
四、高级调度技巧
4.1 Pod亲和性与反亲和性
- Pod亲和性:让Pod与特定Pod部署在同一节点/区域(如前端与后端靠近)。
- Pod反亲和性:避免Pod与特定Pod共存(如避免同一服务的多个副本在同一节点)。
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- my-web
topologyKey: kubernetes.io/hostname # 按节点隔离
4.2 跨AZ调度:实现高可用
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: NotIn
values:
- us-east-1a # 避免所有Pod集中在同一个可用区
五、常见问题与解决
-
Pod一直处于Pending状态
- 原因:无节点满足调度条件(资源不足、亲和性/污点规则冲突)。
- 排查命令:
kubectl describe pod <pod-name> # 查看Events日志 kubectl get nodes --show-labels # 检查节点标签
-
节点资源充足但Pod无法调度
- 检查节点污点与Pod容忍是否匹配。
- 确认节点亲和性/反亲和性规则是否过于严格。
-
如何快速驱逐节点上的所有Pod?
kubectl taint nodes <node-name> emergency=stop:NoExecute
六、总结与下一步
通过本文,我们学会了:
- 节点亲和性:让Pod“偏爱”特定节点。
- 污点与容忍:定义节点的“禁区”与Pod的“通行权”。
- 高级策略:跨AZ调度、Pod反亲和性等企业级技巧。
动手实验
- 模拟节点故障演练
- 为节点添加
NoExecute
污点,观察Pod是否自动迁移到其他节点。
kubectl taint nodes node-01 outage=true:NoExecute
- 为节点添加
资源推荐
现在,我们已经掌握了Kubernetes调度的“交通规则”!🚦 无论是精细化调度还是高可用部署,这些策略都能让你的集群运行得更智能、更高效。