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

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

概念

您可以使用命令 kubectl taint 给节点增加一个 taint。比如,

kubectl taint nodes node1 key=value:NoSchedule

给节点 node1 增加一个 taint,它的 key 是 key,value 是 value,effect 是 NoSchedule。这表示只有拥有和这个 taint 相匹配的 toleration 的 pod 才能够被分配到 node1 这个节点。您可以在 PodSpec 中定义 pod 的 toleration。下面两个 toleration 均与上面例子中使用 kubectl taint 命令创建的 taint 相匹配,因此如果一个 pod 拥有其中的任何一个 toleration 都能够被分配到 node1 :

想删除上述命令添加的 taint ,您可以运行:

kubectl taint nodes kube11 key:NoSchedule-
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"

一个 toleration 和一个 taint 相“匹配”是指它们有一样的 key 和 effect ,并且:

  • 如果 operator 是 Exists (此时 toleration 不能指定 value),或者
  • 如果 operator 是 Equal ,则它们的 value 应该相等
Note:

注意: 存在两种特殊情况:

  • 如果一个 toleration 的 key 为空且 operator 为 Exists ,表示这个 toleration 与任意的 key 、 value 和 effect 都匹配,即这个 toleration 能容忍任意 taint。
tolerations:
- operator: "Exists"
  • 如果一个 toleration 的 effect 为空,则 key 值与之相同的相匹配 taint 的 effect 可以是任意值。
tolerations:
- key: "key"
operator: "Exists"

上述例子使用到的 effect 的一个值 NoSchedule,您也可以使用另外一个值 PreferNoSchedule。这是“优化”或“软”版本的 NoSchedule ——系统会*尽量*避免将 pod 调度到存在其不能容忍 taint 的节点上,但这不是强制的。effect 的值还可以设置为 NoExecute ,下文会详细描述这个值。

您可以给一个节点添加多个 taint ,也可以给一个 pod 添加多个 toleration。Kubernetes 处理多个 taint 和 toleration 的过程就像一个过滤器:从一个节点的所有 taint 开始遍历,过滤掉那些 pod 中存在与之相匹配的 toleration 的 taint。余下未被过滤的 taint 的 effect 值决定了 pod 是否会被分配到该节点,特别是以下情况:

  • 如果未被过滤的 taint 中存在一个以上 effect 值为 NoSchedule 的 taint,则 Kubernetes 不会将 pod 分配到该节点。
  • 如果未被过滤的 taint 中不存在 effect 值为 NoSchedule 的 taint,但是存在 effect 值为 PreferNoSchedule 的 taint,则 Kubernetes 会*尝试*将 pod 分配到该节点。
  • 如果未被过滤的 taint 中存在一个以上 effect 值为 NoExecute 的 taint,则 Kubernetes 不会将 pod 分配到该节点(如果 pod 还未在节点上运行),或者将 pod 从该节点驱逐(如果 pod 已经在节点上运行)。

例如,假设您给一个节点添加了如下的 taint

kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule

然后存在一个 pod,它有两个 toleration

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

在这个例子中,上述 pod 不会被分配到上述节点,因为其没有 toleration 和第三个 taint 相匹配。但是如果在给节点添加 上述 taint 之前,该 pod 已经在上述节点运行,那么它还可以继续运行在该节点上,因为第三个 taint 是三个 taint 中唯一不能被这个 pod 容忍的。

通常情况下,如果给一个节点添加了一个 effect 值为 NoExecute 的 taint,则任何不能忍受这个 taint 的 pod 都会马上被驱逐,任何可以忍受这个 taint 的 pod 都不会被驱逐。但是,如果 pod 存在一个 effect 值为 NoExecute 的 toleration 指定了可选属性 tolerationSeconds 的值,则表示在给节点添加了上述 taint 之后,pod 还能继续在节点上运行的时间。例如,

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

这表示如果这个 pod 正在运行,然后一个匹配的 taint 被添加到其所在的节点,那么 pod 还将继续在节点上运行 3600 秒,然后被驱逐。如果在此之前上述 taint 被删除了,则 pod 不会被驱逐。

使用例子

通过 taint 和 toleration ,可以灵活地让 pod *避开*某些节点或者将 pod 从某些节点驱逐。下面是几个使用例子:

  • 专用节点:如果您想将某些节点专门分配给特定的一组用户使用,您可以给这些节点添加一个 taint(即, kubectl taint nodes nodename dedicated=groupName:NoSchedule),然后给这组用户的 pod 添加一个相对应的 toleration(通过编写一个自定义的admission controller,很容易就能做到)。拥有上述 toleration 的 pod 就能够被分配到上述专用节点,同时也能够被分配到集群中的其它节点。如果您希望这些 pod 只能被分配到上述专用节点,那么您还需要给这些专用节点另外添加一个和上述 taint 类似的 label (例如:dedicated=groupName),同时 还要在上述 admission controller 中给 pod 增加节点亲和性要求上述 pod 只能被分配到添加了 dedicated=groupName 标签的节点上。
  • 配备了特殊硬件的节点:在部分节点配备了特殊硬件(比如 GPU)的集群中,我们希望不需要这类硬件的 pod 不要被分配到这些特殊节点,以便为后继需要这类硬件的 pod 保留资源。要达到这个目的,可以先给配备了特殊硬件的节点添加 taint(例如 kubectl taint nodes nodename special=true:NoSchedule or kubectl taint nodes nodename special=true:PreferNoSchedule),然后给使用了这类特殊硬件的 pod 添加一个相匹配的 toleration。和专用节点的例子类似,添加这个 toleration 的最简单的方法是使用自定义 admission controller。比如,我们推荐使用 Extended Resources 来表示特殊硬件,给配置了特殊硬件的节点添加 taint 时包含 extended resource 名称,然后运行一个 ExtendedResourceToleration admission controller。此时,因为节点已经被 taint 了,没有对应 toleration 的 Pod 会被调度到这些节点。但当你创建一个使用了 extended resource 的 Pod 时,ExtendedResourceToleration admission controller 会自动给 Pod 加上正确的 toleration ,这样 Pod 就会被自动调度到这些配置了特殊硬件件的节点上。这样就能够确保这些配置了特殊硬件的节点专门用于运行 需要使用这些硬件的 Pod,并且您无需手动给这些 Pod 添加 toleration。
  • 基于 taint 的驱逐 (alpha 特性): 这是在每个 pod 中配置的在节点出现问题时的驱逐行为,接下来的章节会描述这个特性

基于 taint 的驱逐

前文我们提到过 taint 的 effect 值 NoExecute ,它会影响已经在节点上运行的 pod * 如果 pod 不能忍受effect 值为 NoExecute 的 taint,那么 pod 将马上被驱逐 * 如果 pod 能够忍受effect 值为 NoExecute 的 taint,但是在 toleration 定义中没有指定 tolerationSeconds,则 pod 还会一直在这个节点上运行。 * 如果 pod 能够忍受effect 值为 NoExecute 的 taint,而且指定了 tolerationSeconds,则 pod 还能在这个节点上继续运行这个指定的时间长度。

此外,Kubernetes 1.6 已经支持(alpha阶段)节点问题的表示。换句话说,当某种条件为真时,node controller会自动给节点添加一个 taint。当前内置的 taint 包括: * node.kubernetes.io/not-ready:节点未准备好。这相当于节点状态 Ready 的值为 “False“。 * node.kubernetes.io/unreachable:node controller 访问不到节点. 这相当于节点状态 Ready 的值为 “Unknown“。 * node.kubernetes.io/out-of-disk:节点磁盘耗尽。 * node.kubernetes.io/memory-pressure:节点存在内存压力。 * node.kubernetes.io/disk-pressure:节点存在磁盘压力。 * node.kubernetes.io/network-unavailable:节点网络不可用。 * node.kubernetes.io/unschedulable: 节点不可调度。 * node.cloudprovider.kubernetes.io/uninitialized:如果 kubelet 启动时指定了一个 “外部” cloud provider,它将给当前节点添加一个 taint 将其标志为不可用。在 cloud-controller-manager 的一个 controller 初始化这个节点后,kubelet 将删除这个 taint。

在启用了 TaintBasedEvictions 这个 alpha 功能特性后(在 Kubernetes controller manager 的 --feature-gates 参数中包含TaintBasedEvictions=true 开启这个功能特性,例如:--feature-gates=FooBar=true,TaintBasedEvictions=true),NodeController (或 kubelet)会自动给节点添加这类 taint,上述基于节点状态 Ready 对 pod 进行驱逐的逻辑会被禁用。

Note:

注意:为了保证由于节点问题引起的 pod 驱逐rate limiting行为正常,系统实际上会以 rate-limited 的方式添加 taint。在像 master 和 node 通讯中断等场景下,这避免了 pod 被大量驱逐。

使用这个 alpha 功能特性,结合 tolerationSeconds ,pod 就可以指定当节点出现一个或全部上述问题时还将在这个节点上运行多长的时间。

比如,一个使用了很多本地状态的应用程序在网络断开时,仍然希望停留在当前节点上运行一段较长的时间,愿意等待网络恢复以避免被驱逐。在这种情况下,pod 的 toleration 可能是下面这样的:

tolerations:
- key: "node.alpha.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000

注意,Kubernetes 会自动给 pod 添加一个 key 为 node.kubernetes.io/not-ready 的 toleration 并配置 tolerationSeconds=300,除非用户提供的 pod 配置中已经已存在了 key 为 node.kubernetes.io/not-ready 的 toleration。同样,Kubernetes 会给 pod 添加一个 key 为 node.kubernetes.io/unreachable 的 toleration 并配置 tolerationSeconds=300,除非用户提供的 pod 配置中已经已存在了 key 为 node.kubernetes.io/unreachable 的 toleration。

这种自动添加 toleration 机制保证了在其中一种问题被检测到时 pod 默认能够继续停留在当前节点运行 5 分钟。这两个默认 toleration 是由 DefaultTolerationSeconds admission controller添加的。

DaemonSet 中的 pod 被创建时,针对以下 taint 自动添加的 NoExecute 的 toleration 将不会指定 tolerationSeconds

  • node.alpha.kubernetes.io/unreachable
  • node.kubernetes.io/not-ready

这保证了出现上述问题时 DaemonSet 中的 pod 永远不会被驱逐,这和 TaintBasedEvictions 这个特性被禁用后的行为是一样的。

基于节点状态添加 taint

1.8 版本引入了一个 alpha 特性,让 node controller 根据节点的状态创建 taint。当开启了这个特性时(通过给 scheduler 的 --feature-gates 添加 TaintNodesByCondition=true 参数,例如:--feature-gates=FooBar=true,TaintNodesByCondition=true),scheduler不会去检查节点的状态,而是检查节点的 taint。这确保了节点的状态不影响应该调度哪些 Pod 到节点上。用户可以通过给 Pod 添加 toleration 来选择忽略节点的一些问题(节点状态的形式表示)。 从 Kubernetes 1.8 开始,DaemonSet controller 会自动添加如下 NoSchedule toleration,以防止 DaemonSet 中断。 * node.kubernetes.io/memory-pressure * node.kubernetes.io/disk-pressure * node.kubernetes.io/out-of-disk (只适合 critical pod) * node.kubernetes.io/unschedulable (1.10 或更高版本) * node.kubernetes.io/network-unavailable (只适合 host network)

添加上述 toleration 确保了向后兼容,您也可以选择自由的向 DaemonSet 添加 toleration。

反馈

调度《Taint(污点) 和 Toleration(容忍)》的更多相关文章

  1. Kubernetes中的Taint污点和Toleration容忍

    Taint(污点)和 Toleration(容忍)可以作用于 node 和 pod master 上添加taint kubectl taint nodes master1 node-role.kube ...

  2. kubernetes调度之污点(taint)和容忍(toleration)

    系列目录 节点亲和性(affinity),是节点的一种属性,让符合条件的pod亲附于它(倾向于或者硬性要求).污点是一种相反的行为,它会使pod抗拒此节点(即pod调度的时候不被调度到此节点) 污点和 ...

  3. Kubernetes高级调度- Taint和Toleration、Node Affinity分析

    此文分享了污点和Node Affinity实际使用过程中的细节.坑和思维误区.同时整理且回答了诸多细节问题,尤其那些在官方文档中不曾提及的细节. 阅读提示:文中的节点指Node (避免Pod和Node ...

  4. kubernetes之Taints污点和Tolerations容忍

    介绍说明 nodeaffinity节点亲和性是pod上定义的一种属性, 使得pod能够被调度到某些node上运行, taint污点正好相反, 它让node拒绝pod运行, 除非pod明确声明能够容忍这 ...

  5. Kubernetes K8S之Taints污点与Tolerations容忍详解

    Kubernetes K8S之Taints污点与Tolerations容忍详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master C ...

  6. 容器编排系统K8s之节点污点和pod容忍度

    前文我们了解了k8s上的kube-scheduler的工作方式,以及pod调度策略的定义:回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/14243312.ht ...

  7. Kubernetes使用节点污点和pod容忍度阻止节点调度到特定节点

    Kubernetes允许你去影响pod被调度到哪个节点.起初,只能通过在pod规范里指定节点选择器来实现,后面其他的机制逐渐加入来扩容这项功能,本章将包括这些内容. 现在要介绍的高级调度的两个特性是节 ...

  8. kubernetes系列(十五) - 集群调度

    1. 集群调度简介 2. 调度过程 2.1 调度过程概览 2.2 Predicate(预选) 2.3 Priorities(优选) 3. 调度的亲和性 3.1 node亲和性 3.1.1 node亲和 ...

  9. centos7.8 安装部署 k8s 集群

    centos7.8 安装部署 k8s 集群 目录 centos7.8 安装部署 k8s 集群 环境说明 Docker 安装 k8s 安装准备工作 Master 节点安装 k8s 版本查看 安装 kub ...

  10. k8s 基础概念

    摘录自k8s中文社区https://www.kubernetes.org.cn/course kubernetes 源自希腊文,意为舵手,k与s之间是8个字母,所以也叫k8s, docker就像一个个 ...

随机推荐

  1. kafka-Reblance

    谁来执行Rebalance以及管理consumer的group呢 coordinator来执行对于consumer group的管理,当consumer group的第一个consumer启动的时候, ...

  2. 069 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 01 综合案例-数组移位-案例需求

    069 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 01 综合案例-数组移位-案例需求 本文知识点:综合案例-数组移位-案例需求 说明:因为时间紧张,本人写博客 ...

  3. python文档下载

    网址记录:https://docs.python.org/3.6/

  4. c++中CreateEvent函数

    参考:https://blog.csdn.net/u011642774/article/details/52789969 函数原型: HANDLE CreateEvent( LPSECURITY_AT ...

  5. CSS中居中的完全指南(中英对照翻译)

    翻译自:https://css-tricks.com/centering-css-complete-guide/ Centering things in CSS is the poster child ...

  6. Linux系统编程 —共享内存之mmap

    共享内存概念 共享内存是通信效率最高的IPC方式,因为进程可以直接读写内存,而无需进行数据的拷备.但是它没有自带同步机制,需要配合信号量等方式来进行同步. 共享内存被创建以后,同一块物理内存被映射到了 ...

  7. Jmeter之『JSR223脚本』

    Json处理(通过JS) 对于Json字符串,需要使用单引号『''』(因为Json中已存在双引号) // String转为Object var jsonObj = JSON.parse('${data ...

  8. Oracle缓存表与Oracle缓存的区别

    一.Oracle缓存表 与 Oracle缓存 的概念 Oracle 缓存:是把Oracle近期查询的语句放置在Oracle设定的缓存当中. Oracle 缓存表:是把某个表放置在缓存当中,缓存是Ora ...

  9. Linux下clock子系统

    常用API: 1.struct clk *clk_get(struct device *dev, const char *id):从一个时钟list链表中以dev或者字符id名称查找一个时钟clk结构 ...

  10. 题解:POI2012 Salaries

    题解:POI2012 Salaries Description The Byteotian Software Corporation (BSC) has \(n\) employees. In BSC ...