k8s教程(pod篇)-污点与容忍

简介: k8s教程(pod篇)-污点与容忍

01 引言

声明:本文为《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)》的读书笔记

在前面的博客《k8s教程(15)-pod之亲和性与互斥性调度》讲解的NodeAffinity节点亲和性,是在Pod上定义的一种属性,使得Pod 能够被调度到某些Node上运行(优先选择或强制要求)。

Taint(污点) 则正好相反,它让Node拒绝Pod的运行。简单地说,被标记为Taint的节点就是存在问题的节点,比 如磁盘要满、资源不足、存在安全隐患要进行升级维护,希望新的Pod不会被调度过来。

但被标记为Taint的节点并非故障节点,仍是有效的工作节点,所以仍需将某些Pod调度到这些节点上时,可以通过使用Toleration属性来实现。

02 案例

2.1 污点与容忍设置

在默认情况下,在Node上设置一个或多个Taint之后,除非Pod明确声明能够容忍这些污点,否则无法在这些Node上运行。

2.1.1 Node设置污点

可以用kubectl taint命令为Node设置Taint信息:

kubectl taint nodes node1 key=value:NoSchedule

描述:这个设置为node1加上了一个Taint,该Taint的键为key,值为valueTaint的效果是NoSchedule,这意味着除非Pod明确声明可以容忍这个Taint,否则不会被调度到node1

2.1.2 Pod声明容忍

Pod上声明容忍的例子如下,下面的两个Toleration都被设置为可以容忍(Tolerate)具有该TaintNode,使得Pod能够被调度到node1上:

tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"

或者

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

2.1.3 小结

PodToleration声明中的keyeffect需要与Taint的设置保持一致,并且满足以下条件之一:

条件
key 空的key配合Exists操作符能够匹配所有键和值
operator 值是Exists(无须指定value), operator的值是Equal并且value相等, 如果不指定operator,则默认值为Equal
effect 空的effect匹配所有effect,在上面的例子中,effect的取值为NoSchedule,还可以取值为PreferNoSchedule,这个值的意思是优先,也可以算作NoSchedule的软限制版本 - 一个Pod如果没有声明容忍这个Taint,则系统会尽量避免把这个Pod调度到这一 节点上,但不是强制的

系统允许在同一个Node上设置多个Taint,也可以在Pod上设置多个Toleration

Kubernetes调度器处理多个Taint和Toleration的逻辑顺序为:首先列出节点中所有的Taint,然后忽略Pod的Toleration能够匹配的部分,剩下的没被忽略的Taint就是对Pod的效果了

2.2 特殊情况

下面是几种特殊情况:

  • 如果在剩余的Taint中存在effect=NoSchedule,则调度器不会把该Pod调度到这一节点上;
  • 如果在剩余的Taint中没有NoSchedule效果,但是有PreferNoSchedule效果,则调度器会尝试不把这个Pod指派给这个节点;
  • 如果在剩余的Taint中有NoExecute效果,并且这个Pod已经在该节点上运行,则会被驱逐;
  • 如果没有在该节点上运行,则也不会再被调度到该节点上。

例如,我们这样对一个节点进行Taint设置:

kubectl taint nodes node1 keyl=valuel:NoSchedule 
kubectl taint nodes node1 keyl=valuel:NoExecute 
kubectl taint nodes node1 key2=value2:NoSchedule

然后在Pod上设置两个Toleration:

tolerations:
- key: "key1"
  operator: "Equal"
  value: "valuel"
  effect: "NoSchedule"
- key: "key1"
  operator: "Equal"
  value: "valuel"
  effect: "NoExecute"

结果:

  • 这样的结果是该Pod无法被调度到node1上,这是因为第3个Taint没有匹配的Toleration
  • 但是如果该Pod已经在node1上运行了,那么在运行时设置第3个Taint,它还能继续在node1上运行,这是因为Pod可以容忍前两个Taint。

一般来说,如果给Node加上effect=NoExecuteTaint,那么在该Node上正在运行的所有无对应TolerationPod都会被立刻驱逐,而具有相应TolerationPod永远不会被驱逐。不过,系统允许给具有NoExecute效果的Toleration加入一 个可选tolerationSeconds“字段,这个设置表明Pod可以在Taint添加到Node之后还能在这个Node上运行多久(单位为s):

tolerations:
- key: "key1"
  operator: "Equal"
  value: "valuel"
  effect: "NoExecute"
  tolerationSeconds: 3600

上述定义的意思是,如果Pod正在运行,所在节点都被加入一个匹配的Taint,则这个Pod会持续在这个节点上存活3600s后被逐出。如果在这个宽限期内Taint被移除,则不会触发驱逐事件

03 应用场景

TaintToleration一种处理节点并且让Pod进行规避或者驱逐Pod的弹性处理方式,下面列举一些常见的用例。

3.1 独占节点

如果想要拿出一部分节点专门给一些特定应用使用,则可以为节点添加这样Taint

kubectl taint nodes nodename dedicated=groupName:NoSchedule

然后给这些应用的Pod加入对应的Toleration,这样,带有合适TolerationPod就会被允许同使用其他节点一样使用有Taint的节点

通过自定义Admission Controller也可以实现这一目标。如果希望让这些应用独占一批节点,并且确保它们只能使用这些节点,则还可以给这些Taint节点加入类似的标签dedicated=groupName,然后Admission Controller需要加入节点亲和 性设置,要求Pod只会被调度到具有这一标签的节点上。

3.2 具有特殊硬件设备的节点

在集群里可能有一小部分节点安装了特殊的硬件设备(如GPU芯片),用户自然会希望把不需要占用这类硬件的Pod排除在外,以确保对这类硬件有需求的Pod能够被顺利调度到这些节点上

可以用下面的命令为节点设置Taint

kubectl taint nodes nodename special=true:NoSchedule 
kubectl taint nodes nodename special=true:PreferNoSchedule

然后在Pod中利用对应的Toleration来保障特定的Pod能够使用特定的硬件。

和上面独占节点的示例类似,使用Admission Controller来完成这一任务会更方便,例如:

  • Admission Controller使用Pod的一些特征来判断这些Pod,如果可以使用这些件,就添加Toleration来完成这一工作;
  • 要保障需要使用特殊硬件的Pod只被调度到安装这些硬件的节点上,则还需要一些额外的工作,比如将这些特殊资源使用opaque-int-resource的方式对自定义资源进行量化,然后在PodSpec中进行请求;
  • 也可以使用标签的方式来标注这些安装有特别硬件的节点,然后在Pod 中定义节点亲和性来实现这个目标。

3.3 定义Pod驱逐行为,以应对节点故障

前面提到的NoExecute这个Taint效果对节点上正在运行的Pod有以下影响:

  • 没有设置Toleration的Pod会被立刻驱逐;
  • 配置了对应Toleration的Pod,如果没有为tolerationSeconds赋值,则会一直留在这一节点中;
  • 配置了对应Toleration的Pod且指定了tolerationSeconds值,则会在指定的时间后驱逐(注意,在节点发生故障的情况下,系统将会以限速(rte- limiting)模式逐步给Node设置Taint,这样就能避免在一些特定情况下(比如
    Master暂时失联)有大量的Pod被驱逐)。

注意,Kubernetes会自动给Pod添加下面几种Toleration:

  • key为node.kubernetes.io/not-ready,并配置tolerationSeconds=300;
  • key 为node.kubernetes.io/unreachable,并配置tolerationSeconds=300。

以上添加的这种自动机制保证了在某些节点发生一些临时性问题时,Pod默认能够继续停留在当前节点运行5min等待节点恢复,而不是立即被驱逐,从而避免系统的异常波动。

另外,Kubernetes从1.6版本开始引入两个与Taint相关的新特性,TaintNodesByCondition及TaintBasedEvictions用来改善异常情况下的Pod调度与驱逐问题,比如在节点内存吃紧、节点磁盘空间已满、节点失联等情况下,是 否自动驱逐某些Pod或者暂时保留这些Pod等待节点恢复正常。这个过程的完整逻 辑基本如下。

  1. 不断地检查所有Node状态,设置对应的Condition;
  2. 不断地根据Node Condition设置对应的Taint;
  3. 不断地根据Taint驱逐Node上的Pod。

其中,检查Node的状态并设置NodeTaint就是TaintNodesByCondition特性,即在Node满足某些特定的条件时,自动为Node节点添加Taint,目前主要有以下几种条件:

条件 描述
node.kubernetes.io/not-ready:节点未就绪 对应NodeCondition Ready为False的情况
node.kubernetes.io/unreachable:节点不可触达 对应NodeCondition Ready.为Unknown的情况
node.kubernetes.io/out-of-disk 节点磁盘空间已满
node.kubernetes.io/network-unavailable 节点网络不可用
node.kubernetes.io/unschedulable 节点不可调度
node.cloudprovider,kubernetes.io/uninitialized 如果kubelet是由"外部"云服务商启动的,则该污点用来标识某个节点当前为不可用状态。在云控制器 (cloud-controller-manager)初始化这个节点以后,kubelet会将此污点移除

自Kubernetes 1.13开始,上述两个特性被默认启用,TaintNodesByCondition 这个特性只会为节点添加NoSchedule效果的污点,TaintBasedEviction则为节点添加NoExecute效果的污点。

在TaintBasedEvictions特性被开启之后,kubelet会在有资源压力时对相应的Node节点自动加上对应的NoExecute效果的Taint,例如 node.kubernetes.io/memory-pressure、node.kubernetes.io/disk-pressure。

如果Pod没有设置对应的Toleration,则这部分Pod将被驱逐,以确保节点不会崩溃。

04 文末

本文主要讲解了pod的污点与容忍的概念、案例及应用的场景,希望能帮助到大家,谢谢大家的阅读,本文完!

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
7月前
|
Kubernetes Docker 容器
Kubernetes与Docker参数对照:理解Pod中的command、args与Dockerfile中的CMD、ENTRYPOINT。
需要明确的是,理解这些都需要对Docker和Kubernetes有一定深度的理解,才能把握二者的区别和联系。虽然它们都是容器技术的二个重要组成部分,但各有其特性和适用场景,理解它们的本质和工作方式,才能更好的使用这些工具,将各自的优点整合到生产环境中,实现软件的快速开发和部署。
223 25
|
11月前
|
Prometheus Kubernetes 监控
深入探索Kubernetes中的Pod自动扩展(Horizontal Pod Autoscaler, HPA)
深入探索Kubernetes中的Pod自动扩展(Horizontal Pod Autoscaler, HPA)
|
7月前
|
Kubernetes Shell Windows
【Azure K8S | AKS】在AKS的节点中抓取目标POD的网络包方法分享
在AKS中遇到复杂网络问题时,可通过以下步骤进入特定POD抓取网络包进行分析:1. 使用`kubectl get pods`确认Pod所在Node;2. 通过`kubectl node-shell`登录Node;3. 使用`crictl ps`找到Pod的Container ID;4. 获取PID并使用`nsenter`进入Pod的网络空间;5. 在`/var/tmp`目录下使用`tcpdump`抓包。完成后按Ctrl+C停止抓包。
226 12
|
7月前
|
人工智能 运维 Kubernetes
2025 超详细!Lens Kubernetes IDE 多平台下载安装与集群管理教程
Lens 是一款企业级 Kubernetes 可视化操作平台,2025版实现了三大技术革新:AI智能运维(异常检测准确率98.7%)、多云联邦管理(支持50+集群)和实时3D拓扑展示。本文介绍其安装环境、配置流程、核心功能及高阶技巧,帮助用户快速上手并解决常见问题。适用于 Windows、macOS 和 Ubuntu 系统,需满足最低配置要求并前置依赖组件如 kubectl 和 Helm。通过 Global Cluster Hub 实现多集群管理,AI辅助故障诊断提升运维效率,自定义监控看板和插件生态扩展提供更多功能。
|
11月前
|
存储 Kubernetes Docker
【赵渝强老师】Kubernetes中Pod的基础容器
Pod 是 Kubernetes 中的基本单位,代表集群上运行的一个进程。它由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。基础容器负责维护 Pod 的网络空间,对用户透明。文中附有图片和视频讲解,详细介绍了 Pod 的组成结构及其在网络配置中的作用。
181 1
【赵渝强老师】Kubernetes中Pod的基础容器
|
5月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
ACK One 的多集群应用分发,可以最小成本地结合您已有的单集群 CD 系统,无需对原先应用资源 YAML 进行修改,即可快速构建成多集群的 CD 系统,并同时获得强大的多集群资源调度和分发的能力。
190 9
|
5月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
本文介绍如何利用阿里云的分布式云容器平台ACK One的多集群应用分发功能,结合云效CD能力,快速将单集群CD系统升级为多集群CD系统。通过增加分发策略(PropagationPolicy)和差异化策略(OverridePolicy),并修改单集群kubeconfig为舰队kubeconfig,可实现无损改造。该方案具备多地域多集群智能资源调度、重调度及故障迁移等能力,帮助用户提升业务效率与可靠性。
|
7月前
|
存储 Kubernetes 监控
K8s集群实战:使用kubeadm和kuboard部署Kubernetes集群
总之,使用kubeadm和kuboard部署K8s集群就像回归童年一样,简单又有趣。不要忘记,技术是为人服务的,用K8s集群操控云端资源,我们不过是想在复杂的世界找寻简单。尽管部署过程可能遇到困难,但朝着简化复杂的目标,我们就能找到意义和乐趣。希望你也能利用这些工具,找到你的乐趣,满足你的需求。
647 33
|
7月前
|
Kubernetes 开发者 Docker
集群部署:使用Rancher部署Kubernetes集群。
以上就是使用 Rancher 部署 Kubernetes 集群的流程。使用 Rancher 和 Kubernetes,开发者可以受益于灵活性和可扩展性,允许他们在多种环境中运行多种应用,同时利用自动化工具使工作负载更加高效。
374 19
|
7月前
|
人工智能 分布式计算 调度
打破资源边界、告别资源浪费:ACK One 多集群Spark和AI作业调度
ACK One多集群Spark作业调度,可以帮助您在不影响集群中正在运行的在线业务的前提下,打破资源边界,根据各集群实际剩余资源来进行调度,最大化您多集群中闲置资源的利用率。

热门文章

最新文章

推荐镜像

更多