污点与容忍

对于 nodeAffinity 无论是硬策略还是软策略方式,都是调度 Pod 到预期节点上,而污点(Taints)恰好与之相反,如果一个节点标记为 Taints ,除非 Pod 也被标识为可以容忍污点节点,否则该 Taints 节点不会被调度 Pod。

比如用户希望把 Master 节点保留给 Kubernetes 系统组件使用,或者把一组具有特殊资源预留给某些 Pod,则污点就很有用了,Pod 不会再被调度到 taint 标记过的节点。我们使用 kubeadm 搭建的集群默认就给 master 节点添加了一个污点标记,所以我们看到我们平时的 Pod 都没有被调度到 master 上去:

$ kubectl describe node k8s-master
Name:               k8s-master
Roles:              master
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=ydzs-master
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/master=
......
Taints:             node-role.kubernetes.io/master:NoSchedule  # kuberadm安装master自己带污点。
Unschedulable:      false
......

我们可以使用上面的命令查看 master 节点的信息,其中有一条关于 Taints 的信息:node-role.kubernetes.io/master:NoSchedule,就表示master 节点打了一个污点的标记,其中影响的参数是 NoSchedule,表示 Pod 不会被调度到标记为 taints 的节点,除了 NoSchedule 外,还有另外两个选项:
1.PreferNoSchedule:NoSchedule 的软策略版本,表示尽量不调度到污点节点上去
2.NoExecute:该选项意味着一旦 Taint 生效,如该节点内正在运行的 Pod 没有对应容忍(Tolerate)设置,则会直接被逐出
污点 taint 标记节点的命令如下:

[root@k8s-master01 ~]# kubectl taint node k8s-node02 test=node2:NoSchedule # 添加污点
node/k8s-node02 tainted

[root@k8s-master01 ~]# kubectl taint node k8s-node02 test-  # 删除污点
node/k8s-node02 untainted

上面的命名将 k8s-node02 节点标记为了污点,影响策略是 NoSchedule,只会影响新的 Pod 调度,如果仍然希望某个 Pod 调度到 taint 节点上,则必须在 Spec 中做出 Toleration 定义,才能调度到该节点,比如现在我们想要将一个 新Pod 调度到 master 节点:(taint-demo.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: taint
  labels:
    app: taint
spec:
  replicas: 3
  selector:
    matchLabels:
      app: taint
  template:
    metadata:
      labels:
        app: taint
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"

由于 master 节点被标记为了污点,所以我们这里要想 Pod 能够调度到改节点去,就需要增加容忍的声明:

tolerations:
- key: "node-role.kubernetes.io/master"
  operator: "Exists"
  effect: "NoSchedule"

然后创建上面的资源,查看结果:

[root@k8s-master01 ~]# kubectl apply -f taint-demo.yaml
deployment.apps "taint" created
[root@k8s-master01 ~]# kubectl get pods -o wide
NAME                                      READY     STATUS             RESTARTS   AGE       IP             NODE
......
taint-845d8bb4fb-57mhm                    1/1       Running            0          1m        10.244.4.247   ydzs-node2
taint-845d8bb4fb-bbvmp                    1/1       Running            0          1m        10.244.0.33    ydzs-master
taint-845d8bb4fb-zb78x                    1/1       Running            0          1m        10.244.4.246   ydzs-node2
......

我们可以看到有一个 Pod 副本被调度到了 master 节点,这就是容忍的使用方法。

容忍小实验

1.查看当前pod所在的节点
[root@k8s-master01 ~]# kubectl get pod -owide
NAME                           READY   STATUS    RESTARTS   AGE     IP              NODE           NOMINATED NODE   READINESS GATES
busybox                        1/1     Running   268        11d     172.17.125.9    k8s-node01     <none>           <none>
nginx-68db656dd8-mprnc         1/1     Running   0          6h1m    172.17.125.13   k8s-node01     <none>           <none>
nginx-68db656dd8-znwgp         1/1     Running   1          11d     172.18.195.11   k8s-master03   <none>           <none>
pod-affinity-6967f7785-j9dqs   1/1     Running   0          69s     172.27.14.249   k8s-node02     <none>           <none>
pod-affinity-6967f7785-lcstr   1/1     Running   0          69s     172.27.14.250   k8s-node02     <none>           <none>
pod-affinity-6967f7785-v97lc   1/1     Running   0          69s     172.27.14.248   k8s-node02     <none>           <none>
test-busybox                   1/1     Running   0          2m22s   172.27.14.246   k8s-node02     <none>           <none>
web                            2/2     Running   0          4d      172.18.195.14   k8s-master03   <none>           <none>

2.现在k8s-node02节点上打上一个NoExecute
[root@k8s-master01 ~]# kubectl taint nodes k8s-node02 test=xtaint:NoExecute
node/k8s-node02 tainted
You have new mail in /var/spool/mail/root
[root@k8s-master01 ~]# kubectl get pod -owide
NAME                           READY   STATUS        RESTARTS   AGE     IP              NODE           NOMINATED NODE   READINESS GATES
busybox                        1/1     Running       268        11d     172.17.125.9    k8s-node01     <none>           <none>
nginx-68db656dd8-mprnc         1/1     Running       0          6h2m    172.17.125.13   k8s-node01     <none>           <none>
nginx-68db656dd8-znwgp         1/1     Running       1          11d     172.18.195.11   k8s-master03   <none>           <none>
pod-affinity-6967f7785-542rg   0/1     Pending       0          13s     <none>          <none>         <none>           <none>
pod-affinity-6967f7785-8dmkf   0/1     Pending       0          13s     <none>          <none>         <none>           <none>
pod-affinity-6967f7785-lcstr   0/1     Terminating   0          2m29s   <none>          k8s-node02     <none>           <none>
pod-affinity-6967f7785-v97lc   0/1     Terminating   0          2m29s   <none>          k8s-node02     <none>           <none>
pod-affinity-6967f7785-vvpj2   0/1     Pending       0          13s     <none>          <none>         <none>           <none>
test-busybox                   1/1     Terminating   0          3m42s   172.27.14.246   k8s-node02     <none>           <none>
web                            2/2     Running       0          4d      172.18.195.14   k8s-master03   <none>           <none>

3.创建一个包含有容忍toleration的配置文件
[root@k8s-master01 ~]# cat node-selector-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: busybox-pod
  name: test-busybox
spec:
  containers:
  - command:
    - sleep
    - "3600"
    image: busybox
    imagePullPolicy: Always
    name: test-busybox
  nodeSelector:
    com: youdianzhishi
  tolerations:
  - key: "test"
    operator: "Equal"
    value: "xtaint"
    effect: "NoExecute"
    tolerationSeconds: 3600 

配置解释:
tolerations:----------->容忍
- key: "check" ----------->容忍的键
operator: "Equal"----------->操作符"等于"
value: "xtaint"----------->容忍的键对应的键值
effect: "NoExecute"----------->容忍的键对应的影响效果
tolerationSeconds: 3600----------->容忍3600秒。本pod配置文件中有这个参数了,然后再给本服务器设置污点NoExecute,那么这个pod也不会像普通pod那样立即被驱逐,而是再等上3600秒才被删除。

[root@k8s-master01 ~]# kubectl create -f node-selector-demo.yaml 
pod/test-busybox created

[root@k8s-master01 ~]# kubectl get pod -owide
NAME                           READY   STATUS    RESTARTS   AGE     IP              NODE           NOMINATED NODE   READINESS GATES
busybox                        1/1     Running   268        11d     172.17.125.9    k8s-node01     <none>           <none>
nginx-68db656dd8-mprnc         1/1     Running   0          6h8m    172.17.125.13   k8s-node01     <none>           <none>
nginx-68db656dd8-znwgp         1/1     Running   1          11d     172.18.195.11   k8s-master03   <none>           <none>
pod-affinity-6967f7785-542rg   0/1     Pending   0          5m59s   <none>          <none>         <none>           <none>
pod-affinity-6967f7785-8dmkf   0/1     Pending   0          5m59s   <none>          <none>         <none>           <none>
pod-affinity-6967f7785-vvpj2   0/1     Pending   0          5m59s   <none>          <none>         <none>           <none>
test-busybox                   1/1     Running   0          34s     172.27.14.251   k8s-node02     <none>           <none>
web                            2/2     Running   0          4d      172.18.195.14   k8s-master03   <none>           <none>

toleration配置方式

方式一:
tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"
方式二:
tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoSchedule"
  
   一个Toleration和一个Taint相匹配是指它们有一样的key和effect,并且如果operator是Exists(此时toleration不指定value)或者operator是Equal,则它们的value应该相等。
注意两种情况:

    如果一个Toleration的key为空且operator为Exists,表示这个Toleration与任意的key、value和effect都匹配,即这个Toleration能容忍任意的Taint:
tolerations:
- operator: "Exists"

    如果一个Toleration的effect为空,则key与之相同的相匹配的Taint的effect可以是任意值:
tolerations:
- key: "key"
  operator: "Exists"

一个使用了很多本地状态的应用程序在网络断开时,仍然希望停留在当前节点上运行一段时间,愿意等待网络恢复以避免被驱逐。在这种情况下,Pod的Toleration可以这样配置:
tolerations:
- key: "node.alpha.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 6000

上述例子使用到effect的一个值NoSchedule,也可以使用PreferNoSchedule,该值定义尽量避免将Pod调度到存在其不能容忍的Taint的节点上,但并不是强制的。effect的值还可以设置为NoExecute。
对于 tolerations 属性的写法,其中的 key、value、effect 与 Node 的 Taint 设置需保持一致, 还有以下几点说明:

如果 operator 的值是 Exists,则 value 属性可省略
如果 operator 的值是 Equal,则表示其 key 与 value 之间的关系是 equal(等于)
如果不指定 operator 属性,则默认值为 Equal
另外,还有两个特殊值:

空的 key 如果再配合 Exists 就能匹配所有的 key 与 value,也就是是能容忍所有节点的所有 Taints
空的 effect 匹配所有的 effect

原文地址:https://www.cnblogs.com/Applogize/p/14596404.html