本文介绍: 持续集成部署(CI/CD)、Kubernetes高级调度污点(Taints)和容忍(Tolerations)是现代容器化和微服务架构常见概念,它们之间存在一定的关联。下面我将简要介绍这些概念以及它们的使用场景

1. 基本概念

Kubernetes中,污点是一种属性,它可以被赋予Node节点),用于标记节点上的Pod应该避免调度的特定条件例如特定的硬件限制安全策略等。而容忍则是Pod的一个属性,它允许Pod在特定的污点条件下仍然被调度到对应节点上。

k8s 集群可能管理着非常庞大的服务器,这些服务可能是各种各样不同类型的,比如机房、地理位置配置等,有些是计算型节点,有些是存储型节点,此时我们希望能更好的将 pod 调度到与之需求匹配的节点上。

此时就需要用到污点Taint)和容忍(Toleration),这些配置都是 key: value 类型的。

比如我们一个三节点的 K8s 集群来说:

Master 节点一般是用来调度从节点实现对应任务,是更重要的角色,而从节点是用来执行对应任务的。当创建一个新的任务,无论是 Pod 还是 Deployment 都会先找没有存在污点的节点上执行

污点可以理解为,为了将未分配的任务排挤到没有污点的节点上运行

容忍,就是反过来的概念,你有污点,我这个任务配置了容忍,也就是可以容忍你有污点,这时候这个任务还是可以调度到这个节点上的。

2. 使用场景

总之,污点和容忍功能为Kubernetes集群高级调度提供了灵活性和精细化的控制,可以根据实际需求对Pod的调度行为进行定制,使得整个集群能够更好适应复杂业务场景运维需求。

3. 污点的基本操作

1. 添加污点

要向节点添加污点,可以使用kubectl命令行工具执行以下命令

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

其中:

例如,要向名为node1的节点添加一个gpu=true:NoSchedule的污点,可以执行以下命令:

kubectl taint nodes node1 gpu=true:NoSchedule

2. 查看污点

kubectl describe no k8s-master

3. 删除污点

删除节点上的污点,可以使用kubectl命令行工具执行以下命令:

kubectl taint nodes <node-name> key-

这里最后的这个 - 号,就是删除这个污点的意思。这跟操作 Label 是一样的。

例如,要删除名为node1的节点上的gpu=true:NoSchedule污点,可以执行以下命令:

kubectl taint nodes node1 gpu-

4. 污点的影响:

5. 配置容忍

# pod 的 spec 下面配置容忍
tolerations:
- key: "污点的 key"
  value: "污点的 value"
  offect: "NoSchedule" # 污点产生的影响
  operator: "Equal" # 表是 value 与污点的 value 要相等,也可以设置为 Exists 表示存在 key 即可,此时可以不用配置 value

其中:

6. 删除容忍

要删除Pod的容忍规则,可以通过编辑Pod的配置文件,将tolerations字段移除或者修改为其他的容忍规则

7. 测试添加污点

看下当前集群中 Pod 的调度情况:

[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS      RESTARTS        AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-bcc5c945c-ptqc6   1/1     Running     318 (42m ago)   13d     10.244.2.96    docker-56   <none&gt;           <none&gt;
nginx-deploy-bcc5c945c-vwbrd   1/1     Running     140 (42m ago)   5d20h   10.244.1.61    docker-55   <none&gt;           <none&gt;
[root@docker-54 ~]# 

可以看到当前集群中在没有配置任何污点时的调度,docker-55、docker-56 两个节点的调度情况基本一致;

现在给 docker-56 节点添加一个内存低的污点:memory=low:NoSchedule

kubectl tain no docker-56 memory=low:NoSchedule

在执行前可以先看下节点的污点情况:kubectl describe no docker-56
其中污点信息Taints如下

CreationTimestamp:  Sun, 14 May 2023 23:05:48 +0800
Taints:             <none>
Unschedulable:      false

看下 Master 节点的污点情况:

[root@docker-54 ~]# kubectl describe no docker-54
CreationTimestamp:  Sun, 14 May 2023 22:57:50 +0800
Taints:             node-role.kubernetes.io/master:NoSchedule
Unschedulable:      false

可以看到这里设置了污点的内容是:node-role.kubernetes.io/master:NoSchedule ,也就是如果没有配置容忍为 node-role.kubernetes.io/master 则不会调度到 Master 节点上。

然后对节点 docker-56 添加完污点信息,则变为:

CreationTimestamp:  Sun, 14 May 2023 23:05:48 +0800
Taints:             memory=low:NoSchedule
Unschedulable:      false

接着看下 Pod 的执行情况:

[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS      RESTARTS        AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-bcc5c945c-ptqc6   1/1     Running     318 (51m ago)   13d     10.244.2.96    docker-56   <none>           <none>
nginx-deploy-bcc5c945c-vwbrd   1/1     Running     140 (51m ago)   5d20h   10.244.1.61    docker-55   <none>           <none>
[root@docker-54 ~]# 

可以看到这时候,是没什么区别的,因为我们上面配置的污点是 NoSchedule,只是不再往上面调度任务了,对于已经存在的Pod 则不会有影响。

对于 Master 节点的污点,如果删除了该污点,则新创建的 Pod 任务是允许调度到 Master 节点上的。

我们测试看看效果

先删除 Master 节点上的污点

[root@docker-54 ~]# kubectl taint no docker-54 node-role.kubernetes.io/master-
node/docker-54 untainted
[root@docker-54 ~]# 

然后手动删除之前部署nginx-deploy,由于之前是使用 deploy 创建的 Pod,在手动删除后,k8s 会自动启动两个 Pod;

[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS              RESTARTS          AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-bcc5c945c-blsgx   1/1     Running             0                 28s     10.244.1.72    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-ptqc6   1/1     Terminating         319 (5m15s ago)   13d     10.244.2.96    docker-56   <none>           <none>
nginx-deploy-bcc5c945c-rf6gl   0/1     ContainerCreating   0                 28s     <none>         docker-54   <none>           <none>
nginx-deploy-bcc5c945c-vwbrd   1/1     Terminating         141 (4m21s ago)   5d21h   10.244.1.61    docker-55   <none>           <none>
[root@docker-54 ~]# 
[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS              RESTARTS      AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-bcc5c945c-blsgx   1/1     Running             0             51s     10.244.1.72    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-rf6gl   0/1     ContainerCreating   0             51s     <none>         docker-54   <none>           <none>
[root@docker-54 ~]# 

可以看到,上面在删除了之后,两个新的 nginx-deploy 的 Pod 又重新启动,并且一个已经被调度到 Master 节点 docker-54 上。

然后调整 Master 节点的污点,新增一个 NoExecute 污点:

[root@docker-54 ~]# kubectl taint no docker-54 node-role.kubernetes.io/master:NoExecute
node/docker-54 tainted
[root@docker-54 ~]# 
[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS        RESTARTS      AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-bcc5c945c-9mcs5   1/1     Running       0             22s     10.244.1.75    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-blsgx   1/1     Running       0             4m13s   10.244.1.72    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-rf6gl   1/1     Terminating   0             4m13s   10.244.0.10    docker-54   <none>           <none>
[root@docker-54 ~]# 
[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS      RESTARTS      AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-bcc5c945c-9mcs5   1/1     Running     0             52s     10.244.1.75    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-blsgx   1/1     Running     0             4m43s   10.244.1.72    docker-55   <none>           <none>
[root@docker-54 ~]# 

可以看到,在新增 NoExecute 污点后,docker-54 节点上的 Pod 被驱离,这时候两个 nginx-deploy 的Pod 都被调度到 docker-55 节点上了。而没有调度到 docker-56 节点,这是因为 docker-56 节点上有个 NoSchedule 的污点。

测试完毕,恢复 Master 节点上的污点:

[root@docker-54 ~]# kubectl taint no docker-54 node-role.kubernetes.io/master-
node/docker-54 untainted
[root@docker-54 ~]# 
[root@docker-54 ~]# kubectl taint no docker-54 node-role.kubernetes.io/master:NoSchedule
node/docker-54 tainted
[root@docker-54 ~]# 
[root@docker-54 ~]# 
[root@docker-54 ~]# 
[root@docker-54 ~]# kubectl taint no docker-56 memory-
node/docker-56 untainted
[root@docker-54 ~]#

4. 容忍的配置

由于我的 docker-56 节点的污点设置值为memory=low:NoSchedule

[root@docker-54 ~]# kubectl describe no docker-56 |grep Taints
Taints:             memory=low:NoSchedule
[root@docker-54 ~]# 

所以接下来测试下设置容忍这个污点。

添加容忍前,Pod 调度情况:

[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS      RESTARTS      AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-bcc5c945c-9mcs5   1/1     Running     2 (31m ago)   151m    10.244.1.75    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-blsgx   1/1     Running     2 (35m ago)   155m    10.244.1.72    docker-55   <none>           <none>
[root@docker-54 ~]# 

由于我这里之前运行过 nginx-deploy 这里就直接修改deploy 新增容忍的配置:

[root@docker-54 jobs]# kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   2/2     2            2           46d
[root@docker-54 jobs]# 

然后编辑kubectl edit deploy nginx-deploy

  template:
    metadata:
      labels:
        app: nginx-deploy
    spec:
      tolerations:
      - effect: "NoSchedule"
        key: "memory"
        operator: "Equal"
        value: "low"
      containers:
        image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        name: nginx

新增 tolerations相关的内容,这里需要注意,需要配置在 模板template下的 spec里面,跟 containers 并齐。

这里为了测试上面的污点,所以配置了 Equal修改完毕保存,看下 Pod 的变化情况;

[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS      RESTARTS      AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-bcc5c945c-9mcs5   1/1     Running     2 (31m ago)   151m    10.244.1.75    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-blsgx   1/1     Running     2 (35m ago)   155m    10.244.1.72    docker-55   <none>           <none>
[root@docker-54 ~]# 
[root@docker-54 ~]# 
[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS              RESTARTS      AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-b8886d997-46sm4   1/1     Running             0             4s      10.244.2.118   docker-56   <none>           <none>
nginx-deploy-b8886d997-d92xh   0/1     ContainerCreating   0             2s      <none>         docker-55   <none>           <none>
nginx-deploy-bcc5c945c-9mcs5   1/1     Terminating         2 (33m ago)   153m    10.244.1.75    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-blsgx   1/1     Running             2 (37m ago)   157m    10.244.1.72    docker-55   <none>           <none>
[root@docker-54 ~]# kubectl get po -o wide
NAME                           READY   STATUS        RESTARTS      AGE     IP             NODE        NOMINATED NODE   READINESS GATES
nginx-deploy-b8886d997-46sm4   1/1     Running       0             14s     10.244.2.118   docker-56   <none>           <none>
nginx-deploy-b8886d997-d92xh   1/1     Running       0             12s     10.244.1.76    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-9mcs5   1/1     Terminating   2 (33m ago)   153m    10.244.1.75    docker-55   <none>           <none>
nginx-deploy-bcc5c945c-blsgx   1/1     Terminating   2 (37m ago)   157m    10.244.1.72    docker-55   <none>           <none>
[root@docker-54 ~]# 

可以看到,在更新deployment 之后,原先 docker-55 节点上的两个 Pod ,停止了一个,然后在 docker-56 节点上启动了一个 Pod。证明上面配置的容忍生效了。这就是容忍的一个效果

另外由于上面使用的是 Equal ,这个在比对污点的 key 的同时,还会比对 value ,当全部匹配的时候,容忍才能生效。当然也可以使用 Exists ,无需配置 value,因为这样就仅仅匹配污点的 key即可生效

测试下再次修改 deploy ,使用 Exists 来配置容忍,删除 value,保存,看下 Pod 的情况:

[root@docker-54 ~]# kubectl get po -o wide |grep nginx-deploy
nginx-deploy-b8886d997-46sm4   1/1     Terminating   0             19m    10.244.2.118   docker-56   <none>           <none>
nginx-deploy-b8886d997-d92xh   1/1     Terminating   0             19m    10.244.1.76    docker-55   <none>           <none>
nginx-deploy-b8976d7b5-77mgp   1/1     Running       0             29s    10.244.1.77    docker-55   <none>           <none>
nginx-deploy-b8976d7b5-fvqn8   1/1     Running       0             31s    10.244.2.119   docker-56   <none>           <none>
[root@docker-54 ~]# 
[root@docker-54 ~]# kubectl get po -o wide |grep nginx-deploy
nginx-deploy-b8976d7b5-77mgp   1/1     Running     0             2m10s   10.244.1.77    docker-55   <none>           <none>
nginx-deploy-b8976d7b5-fvqn8   1/1     Running     0             2m12s   10.244.2.119   docker-56   <none>           <none>
[root@docker-54 ~]# 

可以看到 Pod 被重新调度了,还是分别调度到两个从节点上。

有一点需要注意的是:如果设置了 NoExecute 的污点,这时候配置 NoSchedule 的容忍是没办法生效的。

可以这么理解,由于配置了 NoExecute 的污点,这时候上面所有没有配置容忍的 Pod 都会被驱离,即使 Pod 里面配置了 NoSchedule 的容忍。

在配置NoExecute 污点的容忍规则的时候,还有一种玩法使用tolerationSeconds参数,可以使用tolerationSeconds参数来设置Pod在被驱逐之前可以容忍的时间。如果没有配置,则可以一直容忍这个污点,Pod 可以一直运行。如果配置了这个时间,到这个时间就忍不下去了,这个 Pod 就会被停掉。

这里需要注意,在配置 tolerationSeconds参数的时候,可能会存在一个反复调度到上面,然后到容忍的时间之后被停掉,然后再次调度,再次被停掉的一个循环过程中。

所以,在配置tolerationSeconds参数时,需要仔细考虑集群的资源和调度策略,以避免出现Pod被循环停止和重新调度的问题

原文地址:https://blog.csdn.net/linmengmeng_1314/article/details/134749795

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_29672.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注