持续集成部署-k8s-高级调度-污点和容忍

2023-12-03 04:12

本文主要是介绍持续集成部署-k8s-高级调度-污点和容忍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

持续集成部署-k8s-高级调度-污点和容忍

  • 1. 基本概念
  • 2. 使用场景
  • 3. 污点的基本操作
    • 1. 添加污点
    • 2. 查看污点
    • 3. 删除污点
    • 4. 污点的影响:
    • 5. 配置容忍
    • 6. 删除容忍
    • 7. 测试添加污点
  • 4. 容忍的配置

1. 基本概念

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

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

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

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

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

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

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

2. 使用场景

  • 硬件特性限制:当某些节点具有特定的硬件特性(如GPU、TPU等)时,可以给这些节点打上对应的污点,然后只有带有对应容忍标记的Pod才会被调度到这些节点上,从而保证Pod能够充分利用这些硬件资源。

  • 避免节点负载过高:当节点负载过高时,可以给这些节点打上污点,防止新的Pod被调度到这些节点上,以避免进一步加重节点负载。

  • 安全策略:通过污点和容忍,可以实现对部分节点进行安全隔离,例如将某些特殊的安全策略应用到特定的节点上,以满足安全合规性要求。

  • 节点维护:在节点需要维护时,可以先将节点打上污点,然后逐步驱逐上面的Pod,以确保维护操作不会影响到正在运行的应用程序。

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

3. 污点的基本操作

1. 添加污点

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

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

其中:

  • <node-name> 是要添加污点的节点名称。
  • key=value 是污点的键值对,可以根据实际情况定义不同的键值对,例如gpu=true。
  • taint-effect 指定了污点的效果,包括:
    • NoSchedule:表示新的Pod将不会被调度到带有此污点的节点上。
    • NoExecute:表示已经存在的Pod如果不满足对应的容忍条件,则将被驱逐出该节点。

例如,要向名为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. 污点的影响:

  • NoSchedule:不能容忍的 pod 不能被调度到该节点,但是已经存在的节点不会被驱逐
  • NoExecute:不能容忍的节点会被立即清除,能容忍且没有配置- tolerationSeconds 属性,则可以一直运行,设置了 tolerationSeconds: 3600 属性,则该 pod 还能继续在该节点运行 3600 秒

5. 配置容忍

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

其中:

  • Equal: 比较操作类型为 Equal,则意味着必须与污点值做匹配,key/value都必须相同,才表示能够容忍该污点;
  • Exists:容忍与污点的比较只比较 key,不比较 value,不关心 value 是什么东西,只要 key 存在,就表示可以容忍。

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>           <none>
nginx-deploy-bcc5c945c-vwbrd   1/1     Running     140 (42m ago)   5d20h   10.244.1.61    docker-55   <none>           <none>
[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-deployspec:tolerations:- effect: "NoSchedule"key: "memory"operator: "Equal"value: "low"containers:image: nginx:1.7.9imagePullPolicy: IfNotPresentname: 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被循环停止和重新调度的问题。

这篇关于持续集成部署-k8s-高级调度-污点和容忍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/448024

相关文章

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

k8s中实现mysql主备过程详解

《k8s中实现mysql主备过程详解》文章讲解了在K8s中使用StatefulSet部署MySQL主备架构,包含NFS安装、storageClass配置、MySQL部署及同步检查步骤,确保主备数据一致... 目录一、k8s中实现mysql主备1.1 环境信息1.2 部署nfs-provisioner1.2.

k8s admin用户生成token方式

《k8sadmin用户生成token方式》用户使用Kubernetes1.28创建admin命名空间并部署,通过ClusterRoleBinding为jenkins用户授权集群级权限,生成并获取其t... 目录k8s admin用户生成token创建一个admin的命名空间查看k8s namespace 的

SpringBoot集成WebService(wsdl)实践

《SpringBoot集成WebService(wsdl)实践》文章介绍了SpringBoot项目中通过缓存IWebService接口实现类的泛型入参类型,减少反射调用提升性能的实现方案,包含依赖配置... 目录pom.XML创建入口ApplicationContextUtils.JavaJacksonUt

k8s搭建nfs共享存储实践

《k8s搭建nfs共享存储实践》本文介绍NFS服务端搭建与客户端配置,涵盖安装工具、目录设置及服务启动,随后讲解K8S中NFS动态存储部署,包括创建命名空间、ServiceAccount、RBAC权限... 目录1. NFS搭建1.1 部署NFS服务端1.1.1 下载nfs-utils和rpcbind1.1

linux部署NFS和autofs自动挂载实现过程

《linux部署NFS和autofs自动挂载实现过程》文章介绍了NFS(网络文件系统)和Autofs的原理与配置,NFS通过RPC实现跨系统文件共享,需配置/etc/exports和nfs.conf,... 目录(一)NFS1. 什么是NFS2.NFS守护进程3.RPC服务4. 原理5. 部署5.1安装NF

k8s容器放开锁内存限制问题

《k8s容器放开锁内存限制问题》nccl-test容器运行mpirun时因NCCL_BUFFSIZE过大导致OOM,需通过修改docker服务配置文件,将LimitMEMLOCK设为infinity并... 目录问题问题确认放开容器max locked memory限制总结参考:https://Access

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s