云原生学习02-pod调度

污点与容忍度

在 Kubernetes 中,污点(Taint) 和 容忍度(Toleration) 是用于控制 Pod 调度的一种机制,它们协同工作,决定 Pod 能否被调度到某个节点上。

概念 作用对象 说明
污点(Taint) Node 给节点打上”排斥”标记,阻止不容忍该污点的 Pod 调度上去
容忍度(Toleration) Pod 给 Pod 打上”容忍”标记,允许其调度到带有对应污点的节点上

污点

1
kubectl taint nodes <node-name>  key=value:effect

eg:

1
Kubectl taint nodes minikube key=true:NoSchedule

判断是否打上污点

1
kubectl describe node <node-name> | grep Taints

image-20261015161641181

先查看节点的labels

1
kubectl get node --show-labels

image-20261015162756427

可以看到每一个node的hosename这个labels都是不同的,就拿这个来实践一遍,如下创建一个pod,正常来说会选择minikube这个节点

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Pod
metadata:
name: btop251
spec:
nodeSelector:
kubernetes.io/hostname: minikube
containers:
- name: btop251
image: alpine
command: ["/bin/sh"]
stdin: true
tty: true
1
kubectl apply -f pod.yaml

image-20261015163006071

也确实如此

现在打上NoSchedule污点

1
kubectl taint nodes minikube kubernetes.io/hostname=minikube:NoSchedule

再检查一下状态

1
kubectl get po

image-20261015163356646

还是正常的,但是如果在创建污点之后再创建pod

image-20261015163605772

状态就变成Pending了

详细看看原因

1
kubectl describe po btop251

在最底下可以看到

Warning FailedScheduling 2m19s default-scheduler 0/3 nodes are available: 1 node(s) had untolerated taint(s), 2 node(s) didn’t match Pod’s node affinity/selector. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.

当前三个节点都不可用,一个有不可容忍的污点,另外两个没有对应的labels

这是因为污点有三种效果

effect 含义 对新 Pod 的影响 对已运行 Pod 的影响
NoSchedule 不调度 不容忍的 Pod 不会被调度到该节点 不驱逐,继续运行
PreferNoSchedule 尽量不调度 尽量避免调度,但没地方去时仍可调度 不驱逐
NoExecute 不执行 不容忍的 Pod 不会被调度 立即驱逐已运行的不容忍 Pod

容忍度

1
kubectl explain pod.spec.tolerations

容忍度是打在 Pod 上的,用来”抵消”节点上的污点。只有 Pod 的容忍度能匹配节点的污点,Pod 才能被调度到该节点上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
name: btop251
spec:
nodeSelector:
kubernetes.io/hostname: minikube
tolerations:
- key: "kubernetes.io/hostname"
operator: "Equal"
value: "minikube"
effect: "NoSchedule"
containers:
- name: btop251
image: alpine
command: ["/bin/sh"]
stdin: true
tty: true
字段 是否必填 说明
key 否 要匹配的污点键。为空且 operator 为 Exists 时,匹配所有 key
operator 否 Equal(默认:要求 key、value、effect 都相等才匹配)或 Exists(只要 key 存在)
value 否 匹配的污点值。operator 为 Exists 时可省略
effect 否 匹配的效果。为空表示匹配所有 effect
tolerationSeconds 否 仅用于 NoExecute,容忍多久后被驱逐

重新apply

image-20261015165417139

Running了

添加一个NoExecute的污点再检查

1
kubectl taint nodes minikube kubernetes.io/hostname=minikube:NoExecute

image-20261015165629041

将容忍度也换了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
name: btop251
spec:
nodeSelector:
kubernetes.io/hostname: minikube
tolerations:
- key: "kubernetes.io/hostname"
operator: "Equal"
value: "minikube"
effect: "NoExecute"
tolerationSeconds: 5
containers:
- name: btop251
image: alpine
command: ["/bin/sh"]
stdin: true
tty: true
~

image-20261015170438878

可以看到pod先running了5秒才被驱逐

节点亲和性

特性 nodeSelector nodeAffinity
匹配方式 精确匹配(等值) 支持 In、NotIn、Exists、DoesNotExist、Gt、Lt
逻辑关系 多个标签之间是 AND 支持 AND / OR 组合
软硬策略 只有硬性要求 支持硬亲和 + 软亲和
匹配字段 仅节点标签 节点标签 + 节点字段(matchFields)
表达能力 弱 强

nodeSelector

1
2
3
4
# 只能精确匹配,多个规则之间是and关系
nodeSelector:
disktype: ssd
environment: production

nodeAffinity(节点亲和性)

requiredDuringSchedulingIgnoredDuringExecution(硬亲和性)

  • 同一 matchExpressions 内的多个条件:AND 关系
  • 不同 matchExpressions(即不同 nodeSelectorTerms)之间:OR 关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 必须满足规则, 不满足则不调度
# 同一matchExpressions中是and关系
# 不同matchExpressions之间是or关系
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
- hdd
- matchExpressions:
- key: environment
operator: NotIn
values: [staging, test]
- matchExpressions:
- key: environment
operator: Exists
- matchExpressions:
- key: environment
operator: DoesNotExist
- matchExpressions:
- key: memory
operator: Gt # 大于, Lt 小于
values:
- "16"

- matchFields: # 节点元数据
- key: metadata.name # 节点名称
operator: In
values: [node1, node2, node3]
- key: metadata.uid # 节点唯一ID
operator: In
values: ["uid-value"]
# 节点规格
- key: spec.unschedulable # 节点是否可调度
operator: NotIn
values: ["true"]
# 节点状态
- key: status.allocatable.cpu # 可分配CPU
operator: Gt
values: ["4"]
- key: status.allocatable.memory # 可分配内存
operator: Gt
values: ["8Gi"]
操作符 含义 示例
In 标签值在给定列表中 disktype In [ssd, hdd]
NotIn 标签值不在给定列表中 environment NotIn [staging, test]
Exists 标签键存在 environment Exists
DoesNotExist 标签键不存在 environment DoesNotExist
Gt 标签值大于给定值(字符串比较) memory Gt "16"
Lt 标签值小于给定值 memory Lt "16"

preferredDuringSchedulingIgnoredDuringExecution(软亲和性)

优先满足规则, 不强制要求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: v1
kind: Pod
metadata:
name: preferred-affinity-pod
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
matchExpressions:
- key: zone
operator: In
values:
- us-west-2a
- weight: 20
preference:
matchExpressions:
- key: instance-type
operator: In
values:
- c5.large
containers:
- name: web-app
image: nginx

pod亲和性与反亲和性

1
2
3
4
5
6
7
8
9
10
affinity:
podAffinity: # 亲和性, podAntiAffinity: 亲和性
requiredDuringSchedulingIgnoredDuringExecution: # 同节点亲和性配置
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname # 不同节点 # 根据节点标签

Contents