持续集成部署-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

相关文章

springboot简单集成Security配置的教程

《springboot简单集成Security配置的教程》:本文主要介绍springboot简单集成Security配置的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录集成Security安全框架引入依赖编写配置类WebSecurityConfig(自定义资源权限规则

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

SpringBoot配置Ollama实现本地部署DeepSeek

《SpringBoot配置Ollama实现本地部署DeepSeek》本文主要介绍了在本地环境中使用Ollama配置DeepSeek模型,并在IntelliJIDEA中创建一个Sprin... 目录前言详细步骤一、本地配置DeepSeek二、SpringBoot项目调用本地DeepSeek前言随着人工智能技

通过Docker Compose部署MySQL的详细教程

《通过DockerCompose部署MySQL的详细教程》DockerCompose作为Docker官方的容器编排工具,为MySQL数据库部署带来了显著优势,下面小编就来为大家详细介绍一... 目录一、docker Compose 部署 mysql 的优势二、环境准备与基础配置2.1 项目目录结构2.2 基

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

springboot集成Deepseek4j的项目实践

《springboot集成Deepseek4j的项目实践》本文主要介绍了springboot集成Deepseek4j的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录Deepseek4j快速开始Maven 依js赖基础配置基础使用示例1. 流式返回示例2. 进阶

CentOS 7部署主域名服务器 DNS的方法

《CentOS7部署主域名服务器DNS的方法》文章详细介绍了在CentOS7上部署主域名服务器DNS的步骤,包括安装BIND服务、配置DNS服务、添加域名区域、创建区域文件、配置反向解析、检查配置... 目录1. 安装 BIND 服务和工具2.  配置 BIND 服务3 . 添加你的域名区域配置4.创建区域

Spring Boot 集成 Quartz 使用Cron 表达式实现定时任务

《SpringBoot集成Quartz使用Cron表达式实现定时任务》本文介绍了如何在SpringBoot项目中集成Quartz并使用Cron表达式进行任务调度,通过添加Quartz依赖、创... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启

OpenManus本地部署实战亲测有效完全免费(最新推荐)

《OpenManus本地部署实战亲测有效完全免费(最新推荐)》文章介绍了如何在本地部署OpenManus大语言模型,包括环境搭建、LLM编程接口配置和测试步骤,本文给大家讲解的非常详细,感兴趣的朋友一... 目录1.概况2.环境搭建2.1安装miniconda或者anaconda2.2 LLM编程接口配置2

kotlin中的行为组件及高级用法

《kotlin中的行为组件及高级用法》Jetpack中的四大行为组件:WorkManager、DataBinding、Coroutines和Lifecycle,分别解决了后台任务调度、数据驱动UI、异... 目录WorkManager工作原理最佳实践Data Binding工作原理进阶技巧Coroutine