【kubernetes系列】Kubernetes之Taints和tolerations

这篇具有很好参考价值的文章主要介绍了【kubernetes系列】Kubernetes之Taints和tolerations。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

节点亲和性是pod的一种属性(优先选择或硬性要求),它使 pod 被优先分配到一类特定的节点上。而Taint则相反,它使节点能够排斥一类特定的 pod。

Taints(污点)与tolerations(容忍度)一起工作确保Pod不会被调度到不合适的节点上。Taints是node的属性,单个节点可以添加多个taint(污点),node不接受无法容忍taint(污点)的pod的调度。Toleration(容忍度)是pod的属性,允许(非强制)pod调度到taints(污点)相匹配的node上去。(注意taints是node的属性,tolerations是pod的属性。)

操作

添加

#通过kubectl taint为node添加taint,如:

kubectl taint nodes k8s-node1 key=value:NoSchedule

为node节点 k8s-node1增加一条taint(污点)。Taint(污点)的关键字为key,值为value,taint(污点)影响NoSchedule。意味着如果pod没有设置容忍该污点,pod将不会被调度到k8s-node1上,除非Pod它有设置匹配的toleration(容忍度)。

删除

#为k8s-node1删除刚才添加的taints,如下:

kubectl taint nodes k8s-node1 key:NoSchedule-

可以为pod指定toleration(容忍度)。以下的两种toleration(容忍度)都与上文中创建的taint(污点)匹配,因此这个pod有可能被调试到k8s-node1上。

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

Toleration(容忍度)与taint(污点)匹配的条件是key相同、effect相同,并且:

  • operator的值是Exists(无需指定values的值)
  • operator的值是Equal,并且values的值相等
    而如果不指定,operator默认是Equal。

注意:两种特殊情况。

  • 如果一个 toleration 的 key 为空且 operator 为 Exists ,表示这个 toleration 与任意的 key 、 value 和 effect 都匹配,即这个 toleration 能容忍任意 taint。
tolerations:
- operator: "Exists"
  • 空effect表示匹配所有effect,如:
tolerations:
- key: "key"
  operator: "Exists"

即空则匹配所有

上例中用到了NoSchedule的effect。另外,可以使用PreferNoSchedule的effect,这是NoSchedule的“偏好”或者“软“版本。系统尽量避免非tolerate的pod调度到taint node上,但非强制要求。effect 的值还可以设置为 NoExecute。

其中 [effect] 可取值:[ NoSchedule | PreferNoSchedule | NoExecute ]

NoSchedule: 一定不能被调度
PreferNoSchedule: 尽量不要调度,实在没有地方调度的情况下,才考虑可以调度过来
NoExecute: 不仅不会调度, 还会立即驱逐Node上已有的Pod

添加多个tainit(污点)

可以为单个node指定多条taint(污点),也可以为单个pod指定多条toleration(容忍度)。系统采用过滤的方式处理这种情况:首先从node的所有taint(污点)开始,然后将与pod中的toleration(容忍度)相匹配的taint(污点)删除,余下的taint(污点)对部署进来的pod产生影响。特别地:

  • 如果余下的taint(污点)中至少有一条的effect是NoSchedule,kubernetes将不会高度这个pod到的node上。
  • 如果余下的taint(污点)中没有effect为NoSchedule的taint(污点),但至少有一条effect为PreferNoSchedule,则系统尝试着不将pod部署在node上(也就是有可能还是会部署到这个node上)。
  • 如果余下的taint(污点)中至少有一条的effect是NoExecute,那么不旦新的pod不会被调度到这个node上,而且已经运行在这个node上的pod还会被驱逐出去。
    例如,假如像这样taint一个node:
kubectl taint nodes k8s-node1 key1=value1:NoSchedule
kubectl taint nodes k8s-node1 key1=value1:NoExecute
kubectl taint nodes k8s-node1 key2=value2:NoSchedule

pod有两个toleration:

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

这种情况下,pod不能调度到该node上。因为pod没有toleration(容忍度)与node的第三条taint(污点)匹配。但是如果在给节点添加 上述 taint 之前,该 pod 已经在上述节点运行,那么它还可以继续运行在该节点上,因为第三个 taint 是三个 taint 中唯一不能被这个 pod 容忍的。

一般情况下,如果一个effect为NoExecute的taint(污点)应用于node,运行在node上的所有不能容忍这条taint(污点)的pod都会被排挤出node,能容忍这种taint(污点)的pod则不会被排挤。然而,如果effect为NoExecute的toleration(容忍度)指定给pod,同时添加可选的tolerationSeconds字段,则表示pod被排挤出node之前,以taint(污点)的添加时间为起点,允许此pod在此node上的生存时间。

#例如:

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

#表示可以多存活3600秒。

默认情况下,kubernetes会自动添加一些基础的容忍度。如下是kubernetes1.19.16版本添加的,不同版本可能有所区别,请自行查看。

Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s

使用案例:

Taints与tolerations可以灵活的控制pod远离node,或者将不应该运行的pod从node上排挤出去。以下是几个使用案例:

  • 专用node:如果打算指定特定node集合供特定用户专用,那么可以给这些node添加一条taint(kubectl taint nodes nodename dedicated=groupName:NoSchedule),然后在相应的pod上添加匹配的toleration(容忍度)。拥有toleration的pod被允许像使用集群中的其它node一样使用拥有taint的node。如果打算让pod只使用taint性质的node,并且只能使用taint的node的话,可以对这些taint的node再额外增加标签(例如:dedicated=groupName),然后再通过入口控制器为这些pod额外再增加亲和性要求它们只能部署到拥有dedicated=groupName的node上。总结就是通过标签的亲和性控制pod部署到特定的node上,通过为node增加taint并且为pod增加toleration抵制其它pod部署到这些node上,从而实现node专用。
  • 拥有特殊硬件的node:在集群中,有少数node拥有特殊的硬件配置(例如 GPUs),希望那些不使用特殊的硬件的pod尽量不要部署到这些拥有特殊硬件的node上,为后续到达的需要使用特殊硬件的pod预留出空间。通过如下方法达到这个目的。首先为node添加taint,taint表示node拥有特殊硬件(例如: kubectl taint nodes nodename special=true:NoSchedule 或者 kubectl taint nodes nodename special=true:PreferNoSchedule),然后为需要使用特殊硬件的pod添加相应的toleration。像专用node的例子一样,通过入口控制器很容易为pod添加对应的toleration。例如:推荐使用“扩展资源”代表特殊硬件,使用“扩展资源”的名称为拥有特殊硬件的node添加taint,当提交的pod被配置为需要使用特殊硬件时,扩展资源入口控制器自动为其加上正确的toleration。
  • 基于taint的驱逐(测试特性):一种当node出现问题时per-pod-configurable的驱逐行为,下节介绍。

基于taint的驱逐:

先前提到的effect为NoExecute的taint,它对已经运行在node上的pod的影响如下:

如果pod没有toleration这个taint的话,pod立即被驱逐。
如果toleration了这个taint,并且没有指定tolerationSeconds的值,则一直不会驱逐
如果toleration了这个taint,但是指定tolerationSeconds限定了容忍的时间,则到期后驱逐
此外,Kubernetes用taint代表node出了问题(1.13beta版)。换句话说,当Node某些条件为True时,节点控制器自动为Node节点添加污点,而在状态为Ready的Node上,之前设置过的普通的驱逐逻辑将会被禁用。内置以下污点:

node.kubernetes.io/not-ready:节点尚未就绪。这对应于NodeCondition Ready为“ False”。
node.kubernetes.io/unreachable:Node controlloer无法访问节点。这对应于NodeCondition 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-controller-manager的控制器初始化此节点后,kubelet将删除此污点。
注意:在节点故障的情况下,为了保持现存的Pod驱逐的限速设置,系统将会以限速的模式逐步给Node设置Taint,这就能避免在一些特定情况下(比如Master暂时失联)大量的Pod被驱逐。这一功能兼容于tolerationSeconds允许Pod定义节点故障时持续多久才被逐出。
例如:一个包含很多本地状态的应用可能需要在网络发生故障时,还能持续在节点上运行,期望网络能够快速恢复,从而避免被从这个节点上驱逐。Pod的toleration可以这样定义:

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

对于Node未就绪状态,可以把Key设置为node.kubernetes.io/not-ready如果没有为Pod指定node.kubernetes.io/not-ready 的Tolerations,那么Kubernetes会自动为Pod加入tolerationSeconds= 300的node.kubernetes.io/not-ready 类型的Tolerations
同样如果Pod没有定义node.kubernetes.io/unreachable的Tolerations那么系统会自动为其加入tolerationSeconds=300的node.kubernetes.io/unreachable类型的Tolerations
这些系统自动设置的Tolerations在Node发现问题时,能够为Pod确保驱逐前再运行5min。这两个默认 toleration 是由 DefaultTolerationSeconds admission controller添加的。

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

  • node.alpha.kubernetes.io/unreachable
  • node.kubernetes.io/not-ready
    这保证了出现上述问题时 DaemonSet 中的 pod 永远不会被驱逐,这和 TaintBasedEvictions 这个特性被禁用后的行为是一样的。

驱逐阈值设定

其阈值由kubelet如下参数控制:
–eviction-hard:驱逐阈值(例如memory.available<1Gi),如果满足这些阈值,就会触发pod驱逐。(默认imagefs.available < 15%, memory.available < 100 mi, nodefs.available < 10%, nodefs.inodesFree < 5%)
–eviction-soft:驱逐阈值(例如memory.available<1.5Gi),如果在相应的宽限期内达到该阈值,就会触发pod驱逐。
–eviction-minimum-reclaim:最小回收(例如imagef .available=2Gi),描述kubelet在执行pod回收(如果该资源处于压力之下)时回收的最小资源量。
–eviction-pressure-transition-period:kubelet必须等待一段时间才能从驱逐压力状态过渡出来。(默认5m0)

优化方案:

  • 二进制部署方式:
    编辑kubelet-conf.yml文件修改默认阈值来调整驱逐条件:
- pods
eventBurst: 10
eventRecordQPS: 5
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 5m0s
  • kubeadm部署方式:
mkdir -p /sys/fs/cgroup/cpu,cpuacct/kubelet.slice
mkdir -p /sys/fs/cgroup/memory/kubelet.slice
mkdir -p /sys/fs/cgroup/systemd/kubelet.slice
mkdir -p /sys/fs/cgroup/pids/kubelet.slice
mkdir -p /sys/fs/cgroup/cpu,cpuacct/kubelet.slice
mkdir -p /sys/fs/cgroup/cpuset/kubelet.slice
mkdir -p /sys/fs/cgroup/hugetlb/kubelet.slice


cat >>/var/lib/kubelet/config.yaml<<EOF
enforce-node-allocatable: 'pods,kube-reserved,system-reserved'
kube-reserved-cgroup: '/system.slice/kubelet.service'
system-reserved-cgroup: '/system.slice'
kube-reserved: 'cpu=1,memory=1500Mi'
system-reserved=cpu: '500m,memory=1Gi'
eviction-hard: 'memory.available<5%,nodefs.available<10%,imagefs.available<10%'
eviction-soft: 'memory.available<10%,nodefs.available<15%,imagefs.available<15%'
eviction-soft-grace-period: 'memory.available=2m,nodefs.available=2m,imagefs.available=2m'
eviction-max-pod-grace-period: '30'
eviction-minimum-reclaim: 'memory.available=0Mi,nodefs.available=500Mi,imagefs.available=500Mi'
EOF

然后重启kubelet服务

更多关于kubernetes的知识分享,请前往博客主页。编写过程中,难免出现差错,敬请指出文章来源地址https://www.toymoban.com/news/detail-527771.html

到了这里,关于【kubernetes系列】Kubernetes之Taints和tolerations的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【云原生 | Kubernetes 系列】K8s 实战 如何给应用注入数据 II 将pod数据传递给容器

    在上一篇文章中,我们学习了针对容器设置启动时要执行的命令和参数、定义相互依赖的环境变量、为容器设置环境变量,三种设置方式,本篇文章,我们将继续学习数据的传递。 有两种方式可以将 Pod 和 Container 字段传递给运行中的容器: 环境变量 卷文件 这两种呈现 Pod

    2024年01月25日
    浏览(134)
  • 【云原生】Kubernetes临时容器

    特性状态: Kubernetes v1.25 [stable] 本页面概述了临时容器:一种特殊的容器,该容器在现有 Pod 中临时运行,以便完成用户发起的操作,例如故障排查。 你会使用临时容器来检查服务,而不是用它来构建应用程序 Pod 是 Kubernetes 应用程序的基本构建块。 由于 Pod 是一次性且可替

    2024年02月15日
    浏览(38)
  • 【云原生】Kubernetes容器编排工具

    目录 1. K8S介绍 1.1 k8s的由来 下载地址 1.2 docker编排与k8s编排相比 1.3 传统后端部署与k8s 的对比 传统部署 k8s部署  ​2. k8s的集群架构与组件 (1) Kube-apiserver (2)Kube-controller-manager  (3)Kube-scheduler   2.2 k8s的配置存储中心 2.3  k8s的Node 组件   (1)Kubelet   (2)Kube-Proxy 

    2024年02月10日
    浏览(39)
  • 【云原生】容器编排工具Kubernetes

    目录 一、 K8S介绍 官网地址: 1.1docker编排与k8s编排相比 1.2特性 1.3功能 二、K8S重要组件 2.1核心组件 (1)Kube-apiserver (2)Kube-controller-manager (3)Kube-scheduler (4)Node ①kubelet ②kube-proxy ③docker (5)etcd 2.2Kubernetes工作原理 三、Pod 3.1 Pod控制器 (1)Deployment (2)ReplicaSet (3)

    2024年02月09日
    浏览(45)
  • 云原生、容器化、Kubernetes、微服务

    作者:禅与计算机程序设计艺术 云原生(Cloud Native)是一个开放且社区驱动的项目,它定义了一组架构原则、最佳实践和工具集,这些原则、实践和工具围绕业务需求和工程实践而设计,可用于开发人员在构建和运行分布式系统时更加顺畅地交付可靠的软件。云原生可以帮助

    2024年02月07日
    浏览(44)
  • 【云原生】kubernetes中容器的资源限制

    目录 1 metrics-server 2 指定内存请求和限制 3 指定 CPU 请求和限制 资源限制 在k8s中对于容器资源限制主要分为以下两类: 内存资源限制: 内存 请求 (request)和内存 限制 (limit)分配给一个容器。 我们保障容器拥有它请求数量的内存,但不允许使用超过限制数量的内存。 官网参

    2024年02月14日
    浏览(47)
  • 【云原生 | Kubernetes 系列】— Kubernetes存储方案

    目录 【云原生 | Kubernetes 系列】— Kubernetes存储方案 🍇 一、基本存储 EmptyDir HostPath NFS 搭建nfs服务器 🍋 二、高级存储 PV和PVC pv pvc 演示 -NFS StorageClass(动态存储) StorageClass准备 创建deployment应用StorageClass 创建StatefulSet应用StorageClass 🥭三、配置存储 ConfigMap ConfigMap 的创建

    2024年02月03日
    浏览(48)
  • 云原生Kubernetes:CRI 容器运行时接口

    目录 一、理论 1.​CRI 2.容器运行时层级 3.容器运行时比较 二、总结 (1)概念       Kubernetes Node (kubelet) 的主要功能就是启动和停止容器的组件,我们 称之为容器运行时( Container Runtime) ,其中最知名的就是 Docker 。为了 更具扩展性, Kubernetes 1.5 版本开始就加入了容器运行

    2024年02月09日
    浏览(42)
  • 【云原生|Kubernetes】08-Pod中的Init容器

    Init 容器是一种特殊容器,在 Pod内的应用容器启动之前运行。Init 容器可以包括一些应用镜像中不存在的实用工具和安装脚本。 你可以在 Pod 的spec中与用来描述应用容器的 containers 数组平行的位置指定 Init 容器。 Init 容器的状态在 status.initContainerStatuses 字段中以容器状态数组

    2024年02月09日
    浏览(51)
  • 容器和云原生(三):kubernetes搭建与使用

            目录 单机K8S docker containerd image依赖 kubeadm初始化 验证 crictl工具 K8S核心组件 上文安装单机docker是很简单docker,但是生产环境需要多个主机,主机上启动多个docker容器,相同容器会绑定形成1个服务service,微服务场景中多个service会互相调用,那么就需要保证多个servi

    2024年02月11日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包