一、什么是容忍

容忍度(Toleration)是应用于 Pod 上的。容忍度允许调度器调度带有对应污点的 Pod。 容忍度允许调度但并不保证调度。

污点和容忍度(Toleration)相互配合,可以用来避免 Pod 被分配到不合适的节点上。 每个节点上都可以应用一个或多个污点,这表示对于那些不能容忍这些污点的 Pod, 是不会被该节点接受的。

二、容忍出现背景

当我们给节点打上污点后,此时如果我们想让某些Pod部署在已经打过污点的节点,这就需要涉及到容忍了。我们可以把污点比喻成锁,容忍相当于其对应的钥匙,要想打开锁,我们需要配置锁的钥匙才能打开。

三、容忍配置解析

容忍配置在Pod里面,一般有四种方式:

方式一:完全匹配

tolerations:
- key: "taintKey"
  operator: "Equal"
  value: "taintValue"
  effect: "NoSchedule"

方式二:不完全匹配

tolerations:
- key: "taintKey"
  operator: "Exists"
  effect: "NoSchedule"

方式三:大范围匹配(不推荐key为内置Taint)

- key: "taintKey"
  operator: "Exists"

方式四:匹配所有(不推荐)

tolerations:
- operator: "Exists"

四、容忍如何使用

下面我们先在k8s-master01节点打上指定标签,再在Pod里面添加容忍配置,查看容忍有无配置对Pod状态的影响。

1.在k8s-master01节点上给k8s-node01节点打上标签

[root@k8s-master01 ~]# kubectl label node k8s-node01 ssd=true
node/k8s-node01 labeled

2.在k8s-master01节点上查看ssd标签的节点

[root@k8s-master01 ~]# kubectl get node -l ssd
NAME         STATUS   ROLES    AGE     VERSION
k8s-node01   Ready    <none>   6d22h   v1.23.17

3.在k8s-masTer01节点上定义一个yaml文件

[root@k8s-master01 Taint]# vim toleration.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    ssd: "true"
  tolerations:
  - key: "ssd"
    operator: "Exists"

4.部署

[root@k8s-master01 Taint]# kubectl create -f toleration.yaml
pod/nginx created

5.查看pod状态,观察状态为Running

[root@k8s-master01 Taint]# kubectl get -f toleration.yaml -owide
NAME    READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          39s   172.17.125.11   k8s-node01   <none>           <none>

6.在k8s-masTer01节点上删除Pod

[root@k8s-master01 Taint]# kubectl delete -f toleration.yaml
pod "nginx" deleted

7.在k8s-masTer01节点上修改yaml文件,取消容忍

[root@k8s-master01 Taint]# vim toleration.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    ssd: "true"
  #tolerations:
  #- key: "ssd"
  #  operator: "Exists"

8.在k8s-masTer01节点上重新部署

[root@k8s-master01 Taint]# kubectl create  -f toleration.yaml

9.在k8s-masTer01节点上查看Pod状态,发现一直为Pending

[root@k8s-master01 Taint]# kubectl get -f toleration.yaml -owide
NAME    READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
nginx   0/1     Pending   0          29s   <none>   <none>   <none>           <none>

10.在k8s-masTer01节点上详细查看Pod状态

[root@k8s-master01 Taint]# kubectl describe po nginx
...
...
...
Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  2m15s  default-scheduler  0/5 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 1 node(s) had taint {ssd: true}, that the pod didn't tolerate, 3 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.
  Warning  FailedScheduling  58s    default-scheduler  0/5 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 1 node(s) had taint {ssd: true}, that the pod didn't tolerate, 3 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate.

11.修改yaml文件设置完全匹配

[root@k8s-master01 Taint]# vim toleration.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    ssd: "true"
#以下是主要修改的参数
  tolerations:
  - key: "ssd"
    operator: "Equal"
    value: "true"

12.在k8s-masTer01节点上重新部署,观察到Pod节点重新变回Running

[root@k8s-master01 Taint]# kubectl delete -f toleration.yaml
pod "nginx" deleted

[root@k8s-master01 Taint]# kubectl create -f toleration.yaml
pod/nginx created

[root@k8s-master01 Taint]# kubectl get -f toleration.yaml -owide
NAME    READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          10s   172.17.125.12   k8s-node01   <none>           <none>