首页 > 其他分享 >k8s 的污点与容忍度

k8s 的污点与容忍度

时间:2023-01-29 09:58:03浏览次数:58  
标签:node kubernetes taint io 容忍度 污点 pod k8s 节点

污点和容忍度是相互匹配的关系,在node上定义一个污点,pod上定义容忍度,如果pod能容忍这个污点,就会被调度到拥有这个污点的节点上,不能容忍这个污点就不会调度到拥有这个污点的节点上,如果node节点上没有定义污点,那么任何pod都会调度到这个节点上

给节点添加污点

[root@master-1 ~]# kubectl taint node node-1 key=cx:NoSchedule
node/node-1 tainted

  删除污点

[root@master-1 ~]# kubectl taint node node-1 key:NoSchedule-
node/node-1 untainted

  

可以在 PodSpec 中为容器设定容忍标签。以下两个容忍标签都与上面的 kubectl taint 创建的污点“匹配”, 因此具有任一容忍标签的Pod都可以将其调度到 node-1 上:

 

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

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

 

  

Equal 相当于等于号key 与 effect 还有 value精确匹配检查
Exists 相当于等于号key 与 effect 可以没有value 不检查value

如果一个 toleration 的 effect 为空,则 key 值与之相同的相匹配 taint 的 effect 可以是任意值。
tolerations:
- key: "key"
  operator: "Exists"

  

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


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

 

kubectl taint nodes node-1 key1=value1:NoSchedule
kubectl taint nodes node-1 key1=value1:NoExecute
kubectl taint nodes node-1 key2=value2:NoSchedule
然后存在一个 pod,它有两个 toleration:
tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule" # 未运行是不分配
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute" #不会将 pod 分配到该节点(如果 pod 还未在节点上运行),或者将 pod 从该节点驱逐(如果 pod 已经在节点上运行)。

 

  

上述 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(即, 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 的驱逐: 这是在每个 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。

    在节点被驱逐时,节点控制器或者 kubelet 会添加带有 NoExecute 效应的相关污点。如果异常状态恢复正常,kubelet 或节点控制器能够移除相关的污点。

    注意:

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

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

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

 

tolerations:
- key: "node.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.kubernetes.io/unreachable
  • node.kubernetes.io/not-ready

 

这保证了出现上述问题时 DaemonSet 中的 pod 永远不会被驱逐。

 

Node 生命周期控制器会自动创建与 Node 条件相对应的带有 NoSchedule 效应的污点。 同样,调度器不检查节点条件,而是检查节点污点。这确保了节点条件不会影响调度到节点上的内容。用户可以通过添加适当的 Pod 容忍度来选择忽略某些 Node 的问题(表示为 Node 的调度条件)。

 

自 Kubernetes 1.8 起, DaemonSet 控制器自动为所有守护进程添加如下 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。

测试

 

[root@master-1 pod]# kubectl taint node node-1 cx=cx-node:NoSchedule
node/node-1 tainted
[root@master-1 pod]# kubectl taint node node-2 cx=cx-node:NoSchedule
node/node-2 tainted
[root@master-1 pod]# cat pod-1.yaml   # 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
spec:
  containers:
  - name: nginx
    image: nginx
[root@master-1 pod]# kubectl apply -f pod-1.yaml 
pod/nginx-test created
[root@master-1 pod]# kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
nginx-test   0/1     Pending   0          9s
[root@master-1 pod]# kubectl describe pods nginx-test
Name:         nginx-test
Namespace:    default
Priority:     0
Node:         <none>
Labels:       <none>
Annotations:  <none>
Status:       Pending
IP:           
IPs:          <none>
Containers:
  nginx:
    Image:        nginx
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-w7bhz (ro)
Conditions:
  Type           Status
  PodScheduled   False 
Volumes:
  default-token-w7bhz:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-w7bhz
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  2m8s  default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) had taint {cx: cx-node}, that the 
pod didn't tolerate.  Warning  FailedScheduling  2m8s  default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) had taint {cx: cx-node}, that the 
pod didn't tolerate.  #pod不容忍污点
[root@master-1 pod]# kubectl delete pods nginx-test 
pod "nginx-test" deleted
[root@master-1 pod]# cat pod-1.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
spec:
  containers:
  - name: nginx
    image: nginx
  tolerations: #定义pod容忍
  - key: cx
    value: cx-node
    effect: NoSchedule
[root@master-1 pod]# kubectl apply -f pod-1.yaml 
pod/nginx-test created
[root@master-1 pod]# kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
nginx-test   1/1     Running   0          7s
[root@master-1 pod]# kubectl describe pods nginx-test 
Name:         nginx-test
Namespace:    default
Priority:     0
Node:         node-1/192.168.10.30
Start Time:   Sun, 29 Jan 2023 09:31:00 +0800
Labels:       <none>
Annotations:  cni.projectcalico.org/podIP: 10.244.84.136/32
              cni.projectcalico.org/podIPs: 10.244.84.136/32
Status:       Running
IP:           10.244.84.136
IPs:
  IP:  10.244.84.136
Containers:
  nginx:
    Container ID:   docker://6007930c71983df9ba71b0ef27d59ffc663c659aab1bec18277136175c42ac0e
    Image:          nginx
    Image ID:       docker-pullable://nginx@sha256:b8f2383a95879e1ae064940d9a200f67a6c79e710ed82ac42263397367e7cc4e
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 29 Jan 2023 09:31:06 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-w7bhz (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-w7bhz:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-w7bhz
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     cx=cx-node:NoSchedule
                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  80s   default-scheduler  Successfully assigned default/nginx-test to node-1
  Normal  Pulling    79s   kubelet            Pulling image "nginx"
  Normal  Pulled     74s   kubelet            Successfully pulled image "nginx" in 5.427330105s
  Normal  Created    74s   kubelet            Created container nginx
  Normal  Started    74s   kubelet            Started container nginx
[root@master-1 pod]# kubectl taint node node-1 cx:NoSchedule-  #删除污点
node/node-1 untainted

 

  

 

 

  

 

标签:node,kubernetes,taint,io,容忍度,污点,pod,k8s,节点
From: https://www.cnblogs.com/rdchenxi/p/17071807.html

相关文章

  • k8s~fluentd从kafka到elk
    有时为了日志解耦,通常不把日志打到文件,而是直接打到kafka,而为了分析日志,我们可以通过sidecar的方式,把日志从kafka写入到es里,而通过kibana对日志进行分析。我的k8s-fluentd......
  • 2、使用腾讯云k8s
    1、先购买集群,后创建命名空间test_app_namespace2、后创建镜像仓库my_repo3、本地登录腾讯云容器镜像服务DockerRegistrydockerloginccr.ccs.tencentyun.com--us......
  • velero备份恢复k8s集群
    参考文档:https://blog.51cto.com/kaliarch/4919159https://blog.csdn.net/john1337/article/details/123335046一、什么是velero?Velero是一个云原生的灾难恢复和迁移......
  • 将Portiner部署到MicroK8s集群
    在MicroK8s的帮助下,你可以部署Portiner,从而使Kubernetes的管理变得容易多了。Portainer是一个强大的容器管理平台,不仅可以在Docker部署中使用,还可以在Kubernetes环境中使用......
  • k8s 单节点部署
    k8s单节点部署参考kubeasz:https://github.com/easzlab/kubeasz/blob/master/docs/setup/quickStart.mddashboard:https://github.com/easzlab/kubeasz/blob/master......
  • 不背锅运维:一文搞清楚应用发布到k8s集群的基本流程
    1.使用yaml文件创建资源对象❝每种资源的apiVersion和kind可通过kubectlapi-resources命令进行查看❞tantianran@test-b-k8s-master:~$ kubectl api-resources......
  • 【云原生kubernetes】k8s中pod使用详解
    一、前言在之前k8s组件一篇中,我们谈到了pod这个组件,了解到pod是k8s中资源管理的最小单位,可以说Pod是整个k8s对外提供服务的最基础的个体,有必要对Pod做深入的学习和探究。二......
  • 基于KubeSphere在K8S发布微服务ruoyi----5.部署基础环境Gitlab
      Docker搭建Gitlab服务器1、Gitlab镜像dockersearchgitlab    dockersearchgitlab-ce  dockerpullgitlab/gitlab-ce      2、创......
  • 基于KubeSphere在K8S发布微服务ruoyi----4.部署基础环境Redis
    从dockerhub查看redis启动所需相关参数https://hub.docker.com/_/redisIfpersistenceisenabled,dataisstoredinthe VOLUME/data,whichcanbeusedwith --......
  • k8s资源调度
    1资源调度流程资源创建流程如下所示。 资源调度流程是从资源创建流程的④开始的,即Kube-scheduler在需要创建的资源队列中监听到相应的资源时,会调用可用的调度算法和调......