K8s 调度管理
1. 节点选择器(nodeSelector)
-
最简单的节点调度约束机制。
-
在 Pod 规范中指定某个 Label,只有具有该 Label 的 Node 才能被调度。
-
缺点 :功能简单,只支持 等于匹配。
示例:
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
spec:
nodeSelector:
diskType: ssd
containers:
- name: db
image: mysql:5.7
👉 Pod 只能调度到带有 disktype=ssd
标签的节点上。
2. 节点亲和度(Node Affinity)
相比 nodeSelector
,节点亲和度更灵活,支持 集合操作 、In/NotIn 、Gt/Lt 等表达式。
分两类:
-
强制 (requiredDuringSchedulingIgnoredDuringExecution)
必须满足条件,否则 Pod 无法调度。
-
偏好 (preferredDuringSchedulingIgnoredDuringExecution)
调度器会"尽量"满足,但不保证。
示例:
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod1
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions: # 匹配表达式
- key: diskType # 标签键
operator: In # 操作符
values: # 标签键对应的值,可以包含多个值
- ssd
containers:
- name: db
image: mysql:5.7
apiVersion: v1
kind: Pod
metadata:
name: web-pod2
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: topologyZone
operator: In
values:
- beijing
containers:
- name: db
image: nginx:1.23
👉 强制要求:必须在 disktype=ssd
的节点上
👉 偏好要求:最好在 region=us-east-1
的节点上
Kubernetes 节点/Pod 亲和性规则中的 operator
工作机制。
在调度规则(nodeSelectorTerms.matchExpressions
或 podAffinity/podAntiAffinity
)里,operator
是用来描述 标签的匹配方式 的核心字段。
1 operator
的作用
-
operator
定义了 如何根据 key 与 values 判断条件是否成立。 -
调度器 (kube-scheduler) 在分配 Pod 到节点时,会依次检查这些条件。
-
如果条件不满足:
-
在 强制型规则 (
requiredDuringSchedulingIgnoredDuringExecution
)下,Pod 不能调度。 -
在 偏好型规则 (
preferredDuringSchedulingIgnoredDuringExecution
)下,Pod 仍能调度,但会降低优先级。
-
2 常见 operator
及机制
✅ In
-
含义:标签键存在,并且值在指定集合中。
-
例子:
- key: diskType operator: In values: ["ssd", "nvme"]
👉 节点必须有
diskType=ssd
或diskType=nvme
。
✅ NotIn
-
含义:标签键存在,并且值不在指定集合中。
-
例子:
- key: diskType operator: NotIn values: ["hdd"]
👉 节点必须有
diskType
,且值不是hdd
。
✅ Exists
-
含义:只要标签键存在即可,不要求具体值。
-
例子:
- key: gpuType operator: Exists
👉 节点只要打了
gpuType=xxx
标签即可。
✅ DoesNotExist
-
含义:标签键不存在。
-
例子:
- key: gpuType operator: DoesNotExist
👉 节点上不能有
gpuType
标签。
✅ Gt
(大于)
-
含义 :标签值必须是 整数,节点该 key 的值 > 指定值。
-
例子:
- key: cpuCount operator: Gt values: ["8"]
👉 节点的
cpuCount
标签必须是 整数 > 8。
✅ Lt
(小于)
-
含义 :标签值必须是 整数,节点该 key 的值 < 指定值。
-
例子:
- key: cpuCount operator: Lt values: ["32"]
👉 节点的
cpuCount
必须 < 32。
3 工作机制总结
调度器检查时:
-
取出 Pod 的规则(affinity/anti-affinity)。
-
遍历
matchExpressions
列表(同一组是 AND 关系)。 -
每个
matchExpression
内部的 values 用operator
来判断。 -
nodeSelectorTerms
中多个 term 是 OR 关系,只要有一个 term 满足就行。
4 例子
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: diskType
operator: In
values: ["ssd"]
- key: region
operator: NotIn
values: ["us-east-1"]
逻辑等价于:
(diskType == "ssd") AND (region != "us-east-1")
如果有多个 nodeSelectorTerms
,逻辑会变成:
term1 OR term2 OR term3 ...
3. Pod 与 Pod 亲和性 / 反亲和性
Pod 之间的调度关系,可以让 Pod 贴在一起 或者分开运行。
Pod 亲和性 (Pod Affinity)
- 强制或偏好要求 Pod 调度到与某些 Pod 在一起的节点(例如共享机架,低延迟)。
Pod 反亲和性 (Pod Anti-Affinity)
- 强制或偏好要求 Pod 避开某些 Pod(例如避免多个副本在同一台机器上,提升高可用性)。
示例:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- frontend
topologyKey: "kubernetes.io/hostname"
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- frontend
topologyKey: "kubernetes.io/hostname"
👉 强制:Pod 必须调度到有 app=frontend
的节点上
👉 偏好:尽量避免与 app=frontend
的 Pod 在同一节点
详细例子
apiVersion: v1
kind: Pod
metadata:
name: web-pod-affinity
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- db
topologyKey: kubernetes.io/hostname
containers:
- name: web
image: nginx:1.23
逐行解释这个 Pod 配置 ,重点是 Pod 亲和性 (PodAffinity) 的字段含义:
apiVersion: v1
kind: Pod
metadata:
name: web-pod-affinity
- apiVersion: v1 → 使用的 Kubernetes API 版本。
- kind: Pod → 定义的资源类型是 Pod。
- metadata.name: web-pod-affinity → Pod 的名字。
spec:
affinity:
podAffinity:
- spec → Pod 的规格定义。
- affinity → Pod 的调度亲和性规则。
- podAffinity → Pod 亲和性,表示希望这个 Pod 调度到与某些 Pod 靠近(在同一拓扑范围内) 的节点上
preferredDuringSchedulingIgnoredDuringExecution:
-
preferredDuringSchedulingIgnoredDuringExecution → 偏好型规则(软约束)。
-
如果能满足条件,调度器会优先选择符合条件的节点;
-
如果条件不满足,也不会阻止 Pod 被调度(Pod 仍然可以运行,只是没有优先级)。
-
-
对比:
requiredDuringSchedulingIgnoredDuringExecution
→ 强制约束(硬条件,不满足则 Pod 无法调度)。
- weight: 100
-
weight: 100 → 权重,取值范围 1--100。
-
多个偏好规则时,调度器会根据权重打分,权重高的规则影响力更大。
-
这里
100
表示最高优先级。
podAffinityTerm:
- podAffinityTerm → 定义 Pod 亲和性的具体条件。
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- db
-
labelSelector → 选择目标 Pod 的标签。
-
matchExpressions → 匹配条件。
-
key: app → 匹配
app
标签。 -
operator: In → 取值在指定集合中。
-
values: ["db"] → 标签必须是
app=db
。
-
👉 也就是说:当前 Pod 期望调度到和已有 app=db
的 Pod 在同一拓扑范围的节点上。
topologyKey: kubernetes.io/hostname
-
topologyKey → 定义"靠近"的范围(拓扑域)。
-
kubernetes.io/hostname
→ 表示同一个节点(即 Node)。 -
也可以设置成
topology.kubernetes.io/zone
(同一个可用区)或topology.kubernetes.io/region
(同一个区域)。
👉 这里表示:调度器会优先把该 Pod 调度到已经运行了 app=db
Pod 的同一台 Node 上。
containers:
- name: web
image: nginx:1.23
-
定义 Pod 里的容器。
-
name: web → 容器名字。
-
image: nginx:1.23 → 使用的镜像
总结
-
Pod 名为
web-pod-affinity
,运行一个 Nginx 1.23 容器。 -
使用 Pod 亲和性,软约束。
-
希望它能调度到 与已有标签
app=db
的 Pod 同一节点 (topologyKey=kubernetes.io/hostname
)上。 -
权重 100,优先级最高。
4. 污点与容忍(Taints & Tolerations)
-
污点 (Taint):给 Node 打上"拒绝某类 Pod"的标记。
-
容忍 (Toleration):Pod 上的属性,可以"忍受"某些污点,从而被调度到该 Node。
常见用途:
-
专用节点(只运行特定 Pod)。
-
隔离节点(只允许具备特定容忍的 Pod 运行)。
-
节点异常(如不可达、内存压力)时调度器驱逐 Pod。
添加污点:
kubectl taint nodes node1 key=value:NoSchedule
Pod 容忍:
apiVersion: v1
kind: Pod
metadata:
name: tensorflow-pod2
spec:
tolerations:
- key: gpu
operator: Equal
value: "nvidia"
effect: NoSchedule
nodeSelector:
gpu: "nvidia"
containers:
- name: tf
image: tensorflow/tensorflow:latest
👉 Pod 只有带了对应容忍,才能调度到有该污点的节点。
5. NodeName
-
直接指定 Pod 运行在哪个节点上。
-
一般用于测试或特定场景,不推荐大规模使用,因为绕过了调度器。
示例:
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
nodeName: k8s-node1
containers:
- name: web
image: busybox
command: ['/bin/sh', '-c', "sleep 1d"]