这是K8s最基础的调度模式,由kube-scheduler组件负责,无需用户额外配置。
kube-scheduler监听未调度的Pod(即spec.nodeName为空),通过预选(Filtering)和优选(Scoring)两个阶段选择最优节点:
用户直接指定Pod运行的节点,绕过kube-scheduler。
nodeName字段在Pod的spec.nodeName中直接填写目标节点的名称,Pod会被直接调度到该节点(即使节点不满足资源需求,也会强制调度)。
示例:
apiVersion: v1
kind: Pod
metadata:
name: manual-scheduled-pod
spec:
nodeName: node-01 # 直接指定节点
containers:
- name: nginx
image: nginx通过节点标签定义Pod与节点的亲和关系,比nodeSelector更灵活(支持条件表达式、软/硬约束)。
必须满足的条件,否则Pod无法调度(类似nodeSelector但更强大)。
优先满足的条件,不满足时仍可调度到其他节点。
示例(硬亲和:Pod必须运行在zone=us-east的节点):
apiVersion: v1
kind: Pod
metadata:
name: node-affinity-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: zone
operator: In
values:
- us-east
containers:
- name: nginx
image: nginx基于其他Pod的标签定义调度规则,控制Pod之间的位置关系(同节点/不同节点)。
让Pod与特定Pod运行在同一拓扑域(如节点、可用区)。
让Pod与特定Pod运行在不同拓扑域,实现高可用(如避免同一服务的Pod集中在单个节点)。
示例(Pod反亲和:同一Deployment的Pod不运行在同一节点):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: nginx
topologyKey: kubernetes.io/hostname # 拓扑域为节点(hostname唯一)
containers:
- name: nginx
image: nginx节点通过污点拒绝不合适的Pod,Pod通过容忍声明自己可以接受特定污点,从而被调度到该节点。
key=value:effect,effect有三种:NoSchedule:Pod不容忍则无法调度到该节点。PreferNoSchedule:尽量不调度,但不是强制。NoExecute:不仅不调度,还会驱逐节点上已存在的、不容忍该污点的Pod。示例(节点打污点,Pod通过容忍调度):
# 给node-01打污点:key=dedicated, value=GPU, effect=NoSchedule
kubectl taint nodes node-01 dedicated=GPU:NoSchedule# Pod声明容忍该污点
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "GPU"
effect: "NoSchedule"
containers:
- name: cuda
image: nvidia/cuda:11.0-basenode-role.kubernetes.io/master:NoSchedule污点,普通Pod无法调度。当K8s默认调度器无法满足需求时,可开发自定义调度器,并通过Pod的schedulerName字段指定使用它。
自定义调度器需实现kube-scheduler的接口,监听未调度的Pod,执行预选/优选逻辑,最终将Pod绑定到节点。
示例(Pod指定自定义调度器):
apiVersion: v1
kind: Pod
metadata:
name: custom-scheduled-pod
spec:
schedulerName: my-custom-scheduler # 指定自定义调度器名称
containers:
- name: nginx
image: nginx通过优先级(Priority)控制Pod的调度顺序,高优先级Pod会优先被调度,甚至在资源不足时驱逐低优先级Pod。
spec.priorityClassName指定。示例(定义高优先级,Pod优先调度):
# 定义PriorityClass
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false # 不设为默认优先级
description: "High priority for critical pods"# Pod引用该PriorityClass
apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
spec:
priorityClassName: high-priority
containers:
- name: nginx
image: nginx由kubelet直接管理,不经过API Server,也不由kube-scheduler调度。通常存放在节点的/etc/kubernetes/manifests目录下,用于部署控制平面组件(如kube-apiserver、etcd)。
| 调度模式 | 核心机制 | 适用场景 |
|---|---|---|
| 默认自动调度 | kube-scheduler预选+优选 | 普通无状态应用 |
| 手动调度(nodeName) | 直接指定节点 | 测试、临时指定 |
| 节点亲和性 | 节点标签+软/硬约束 | 按节点属性调度(如区域、硬件) |
| Pod亲和/反亲和 | Pod标签+拓扑域 | 控制Pod间位置(高可用/集中) |
| 污点+容忍 | 节点污点+Pod容忍 | 节点隔离、专用节点 |
| 自定义调度器 | 第三方调度器实现 | 特殊调度需求 |
| 优先级调度 | PriorityClass定义优先级 | 控制调度顺序、资源抢占 |
| 静态Pod/DaemonSet | kubelet/DaemonSet控制器调度 | 控制平面组件、节点守护进程 |
通过组合以上调度模式,可以覆盖从简单到复杂的各种场景,满足生产环境对Pod调度的灵活需求。