Kubernetes 调度 Node污点/容忍

网友投稿 921 2022-11-29

Kubernetes 调度 Node污点/容忍

Kubernetes 调度 Node污点/容忍

Node 标记/容忍

还有第三类调度,可以通过给 Node 打一些标记,来限制 Pod 调度到某些 Node 上。Kubernetes 把这些标记称之为 Taints,它的字面意思是污染。(污点=key + value + effect)

那我们如何限制 Pod 调度到某些 Node 上呢?比如说现在有个 node 叫 demo-node,这个节点有问题,我想限制一些 Pod 调度上来。这时可以给这个节点打一个 taints,taints 内容包括 key、value、effect:

key 就是配置的键值value 就是内容effect 是标记了这个 taints 行为是什么

目前 Kubernetes 里面有三个 taints 行为:

NoSchedule 禁止新的 Pod 调度上来PreferNoSchedul 尽量不调度到这台NoExecute 会 evict 没有对应 toleration 的 Pods,并且也不会调度新的上来。这个策略是非常严格的,大家在使用的时候要小心一点

如上图绿色部分,给这个 demo-node 打了 k1=v1,并且 effect 等于 NoSchedule 之后。它的效果是:新建的 Pod  没有专门容忍这个 taint,那就没法调度到这个节点上去了。

假如有些 Pod 是可以调度到这个节点上的,应该怎么来做呢?这时可以在 Pod 上打一个 Pod Tolerations。从上图中蓝色部分可以看到:在 Pod 的 spec 中填写一个 Tolerations,它里面也包含了 key、value、effect,这三个值和 taint 的值是完全对应的,taint 里面的 key,value,effect 是什么内容,Tolerations 里面也要填写相同的内容。

Tolerations 还多了一个选项 Operator,Operator 有两个 value:Exists/Equal。Equal 的概念是必须要填写 value,而 Exists 就跟上文说的 NodeAffinity 一样,不需要填写 value,只要 key 值对上了,就认为它跟 taints 是匹配的。

上图中的例子,给 Pod 打了一个 Tolerations,只有打了这个 Tolerations 的 Pod,才能调度到绿色部分打了 taints 的 Node 上去。这样的好处是 Node 可以有选择性的调度一些 Pod 上来,而不是所有的 Pod 都可以调度上来,这样就做到了限制某些 Pod 调度到某些 Node 的效果。

小结

我们已经介绍完了 Pod/Node 的特殊关系和条件调度,来做一下小结。

首先假如有需求是处理 Pod 与 Pod 的时候,比如 Pod 和另一个 Pod 有亲和的关系或者是互斥的关系,可以给它们配置下面的参数:

PodAffinityPodAntiAffinity

假如存在 Pod 和 Node 有亲和关系,可以配置下面的参数:

NodeSelectorNodeAffinity

假如有些 Node 是限制某些 Pod 调度的,比如说一些故障的 Node,或者说是一些特殊业务的 Node,可以配置下面的参数:

Node -- TaintsPod -- Tolerations

Taint 和 Toleration

Taints: 避免Pod调度到特定Node上

Tolerations: 允许Pod调度到持有Taints的Node上

应用场景:

• 专用节点:根据业务线将Node分组管理,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配

• 配备特殊硬件:部分Node配有SSD硬盘、GPU,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配

• 基于Taint的驱逐

Nodeselector和afflinte是需要调度到哪个节点上。污点是不调度到相应的节点上,拒绝某个Pod分配过来。

节点亲和性,是pod的一种属性(偏好或硬性要求),它使pod被吸引到一类特定的节点。Taint 则相反,它使节点能够排斥一类特定的 pod。

Taint 和 toleration 相互配合,可以用来避免 pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个taint ,这表示对于那些不能容忍这些 taint 的 pod,是不会被该节点接受的。如果将 toleration 应用于 pod上,则表示这些 pod 可以(但不要求)被调度到具有匹配 taint 的节点上。

如果你不懂上面枯燥无味的术语没关系,举个例子如下:

当年龄大以后,都会遇到相亲。比如一个女孩相亲一个男孩,会问这个男孩晚上会不会打呼噜,如果打呼噜是容忍不了的。也就是有些男孩特点标签上被贴上了打呼噜的两个字,那么这个女孩就没有可能和这个男孩走在一起。

这就是一个典型的污点和容忍。如果你能容忍这个污点,代表你有可能发生故事,但是不一定会发生故事。这里指的是有发生故事的可能性而且。在k8s里面依然是这个概念。

[root@k8s-master ~]# kubectl get nodeNAME STATUS ROLES AGE VERSIONk8s-master Ready master 22d v1.19.0k8s-node1 Ready 22d v1.19.0k8s-node2 Ready 22d v1.19.0

假设我有一个Pod,它不能容忍任何污点,在其中一个node上面,它有一个污点存在,那么这个pod就不会调度到这个节点上面去了。

如果pod能够容忍这个node污点,难道就一定会运行在该节点吗?不一定吧,也可能在其他节点上运行。(有污点的可以容忍,没有污点的凭什么不可以运行呢,只不过污点的节点不会成为选择的障碍而已)

污点(Taint)

1、污点的组成

使用kubectl taint 命令可以给某个node节点设置污点,Node被设置上污点之后就和Pod之间存在了一种相斥的关系,可以让Node拒绝Pod的调度执行,甚至将已经存在得Pod驱逐出去,每个污点的组成如下:

key=value:effect

每个污点有一个 key 和 value 作为污点标签,其中 value 可以为空,effect描述污点的作用,当前 effect 支持如下三个选项:

NoSchedule:表示 k8s 不会将Pod调度到具有该污点的Node上PreferNoSchedule:表示 k8s 将尽量避免将Pod调度到具有该污点的Node上NoExecute:表示 k8s 将不会将Pod调度到具有该污点的Node上,同时会将Node上已有的Pod驱逐出去(相当于结婚了还得离婚)

2、污点的设置、查看和去除

k8s的master节点本身就带有effect类型为NoSchedule的污点,这也是为什么k8s在调度Pod时,不会调度到master节点的原因,具体查看如下:(Kubeadm在安装初始化init的时候给master打上了污点,其余节点是没有该污点的。Master节点主要任务是管理集群的,不应该跑具体的业务应用。所以不允许pod落在master节点)

如果不让pod调度到某个节点,那么可以对该节点打污点

[root@k8s-master ~]# kubectl describe node k8s-master Taints: node-role.kubernetes.io/master:NoSchedule kubectl taint nodes k8s-master node-role.kubernetes.io/master=:NoSchedule

注意⚠️ : 为master设置的这个taint中, ​​node-role.kubernetes.io/master​​​为​​key​​​, ​​value​​​为空, ​​effect​​​为​​NoSchedule,​​​如果输入命令时, 你丢掉了​​=​​​符号, 写成了​​node-role.kubernetes.io/master:NoSchedule​​​, 会报​​error: at least one taint update is required​​错误

过程介绍

# 设置污点kubectl taint nodes [node name] key1=value:NoSchedule# 节点说明中,查看Taint字段kubectl describe node [node name]# 去除污点kubectl taint nodes [node name] key1:NoSchedule-

演示

# 查看当前节点所拥有Pod,kubia-859d757f8c-97zn 在ks-master节点[root@k8s-master ~]# kubectl get pod -o wide --show-labelsNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELSkubia-859d757f8c-74g6s 1/1 Running 0 33d 10.244.2.4 k8s-node2 app=kubia,pod-template-hash=859d757f8ckubia-859d757f8c-97znt 1/1 Running 0 33d 10.244.0.14 k8s-master app=kubia,pod-template-hash=859d757f8ckubia-859d757f8c-9mjf9 1/1 Running 0 33d 10.244.1.5 k8s-node1 app=kubia,pod-template-hash=859d757f8c# 给k8s-master设置NoExecute污点,使已经落在本节点的Pod被驱赶出去[root@k8s-master ~]# kubectl taint nodes k8s-master app=kubia:NoExecutenode/k8s-master tainted# 可以看到pod kubia-859d757f8c-97znty因为不能容忍污点,结束了其生命周期[root@k8s-master ~]# kubectl get pod -o wide --show-labelsNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELSkubia-859d757f8c-74g6s 1/1 Running 0 33d 10.244.2.4 k8s-node2 app=kubia,pod-template-hash=859d757f8ckubia-859d757f8c-97znt 0/1 Terminating 0 33d k8s-master app=kubia,pod-template-hash=859d757f8ckubia-859d757f8c-9mjf9 1/1 Running 0 33d 10.244.1.5 k8s-node1 app=kubia,pod-template-hash=859d757f8ckubia-859d757f8c-jttrw 1/1 Running 0 46s 10.244.2.5 k8s-node2 app=kubia,pod-template-hash=859d757f8c# 由于有了deployment控制器,那么就会在其他节点被创建[root@k8s-master ~]# kubectl get pod -o wide --show-labelsNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELSkubia-859d757f8c-74g6s 1/1 Running 0 33d 10.244.2.4 k8s-node2 app=kubia,pod-template-hash=859d757f8ckubia-859d757f8c-9mjf9 1/1 Running 0 33d 10.244.1.5 k8s-node1 app=kubia,pod-template-hash=859d757f8ckubia-859d757f8c-jttrw 1/1 Running 0 79s 10.244.2.5 k8s-node2 app=kubia,pod-template-hash=859d757f8c

如果只有一个node节点,并且有污点,那么新建的Pod会一直处于Pending状态,因为没有可用的Node节点,这时候就可以使用容忍(Toleration)了。

容忍(Toleration)

设置了污点的Node将根据 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之间产生互斥的关系,Pod将在一定程度上不会被调度到 Node 上。但我们可以在 Pod 上设置容忍(Toleration),意思是设置了容忍的 Pod 将可以在有相对应污点的 Node 中存在。

容忍(Toleration)的策略规则如下:

Pod.spec.tolerations

tolerations:- key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" tolerationSeconds: 3600- key: "key1" operator: "Equal" value: "value1" effect: "NoExecute"- key: "key2" operator: "Exists" effect: "NoSchedule"

其中 key、value、effect 要与Node中的 taint 保持一致operator 的值为 Exists 将会忽略 value 的值,值为 Equal 时则必须匹配相同的valuetolerationSeconds 用于描述当Pod需要驱逐时可以在Node上继续保留运行的时间(即多少秒后被驱逐)

1、当不指定key时,表示容忍所有污点的key:

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

vim pod3.yamlapiVersion: v1kind: Podmetadata: name: pod-3 labels: app: nginx type: webspec: containers: - name: pod-3 image: nginx:1.2.1 imagePullPolicy: IfNotPresent ports: - name: web containerPort: 80 tolerations: - operator: "Exists" effect: "NoSchedule"

yaml策略为:可以容忍所有策略为NoSchedule的污点。

[root@k8s-master ~]# kubectl create -f pod3.yaml pod/pod-3 created[root@k8s-master ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE pod-3 1/1 Running 0 9s 10.244.0.107 k8s-master

因为k8s-master为master节点,污点默认为NoSchedule,所以Pod-3被调度到master节点。

2、当不指定 effect 值时,表示容忍所有的污点类型

tolerations:- key: "key1" value: "value1" operator: "Exists"

Pod容忍测试用例:

vim pod2.yamlapiVersion: v1kind: Podmetadata: name: pod-2 labels: app: nginx type: webspec: containers: - name: pod-2 image: nginx:1.2.1 imagePullPolicy: IfNotPresent ports: - name: web containerPort: 80 tolerations: - key: "check" operator: "Equal" value: "vfan"

以上策略表示:能够容忍所有key:value为check:vfan的污点类型。

[root@k8s-master ~]# kubectl create -f pod2.yaml pod/pod-2 created[root@k8s-master ~]# kubectl get pod NAME READY STATUS RESTARTS AGEpod-1 0/1 Pending 0 3m25spod-2 1/1 Running 0 4s

设置容忍的Pod,可以正常调度到Node节点,而没有设置容忍的,还一直处于Pending状态

3、具体指定 key、value、effect 值

[root@k8s-master ~]# cat torl.yml apiVersion: v1kind: Podmetadata: name: pod-1 labels: app: pod-1spec: containers: - name: pod-1 image: nginx tolerations: - key: "app" operator: "Equal" value: "kubia" effect: "NoExecute" tolerationSeconds: 360[root@k8s-master ~]# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESpod-1 1/1 Running 0 109s 10.244.0.15 k8s-master [root@k8s-master ~]# kubectl describe node k8s-masterTaints: app=kubia:NoExecute

可以看到容忍污点了,那么就可以运行了

最后别忘记将Node污点去除:

[root@k8s-master ~]# kubectl taint nodes k8s-master app=kubia:NoExecute-node/k8s-master untainted

总结

为什么calio pod在每个节点都有,因为calio有污点容忍,所以在master节点也会创建Pod

[root@k8s-master ~]# kubectl get pod -o wide -n kube-systemNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATEScalico-kube-controllers-5c6f6b67db-q5qb6 1/1 Running 3 22d 10.244.36.81 k8s-node1 calico-node-6hgrq 1/1 Running 3 22d 192.168.179.102 k8s-master calico-node-jxh4t 1/1 Running 3 22d 192.168.179.103 k8s-node1 calico-node-xjklb 1/1 Running 6 22d 192.168.179.104 k8s-node2 nodeSelector: kubernetes.io/os: linux tolerations: # Make sure calico-node gets scheduled on all nodes. - effect: NoSchedule operator: Exists # Mark the pod as a critical add-on for rescheduling. - key: CriticalAddonsOnly operator: Exists - effect: NoExecute operator: Exists

flannel

tolerations: - operator: Exists effect: NoSchedule

一幅图总结如下:

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Mybatis-Plus中sum等聚合函数的使用
下一篇:Kubernetes 当中启用IPVS模式
相关文章

 发表评论

暂时没有评论,来抢沙发吧~