Kubernetes 污点与容忍

2023年 5月 4日 36.8k 0

首先说一下污点(Taint),当我们需要将master节点保留给Kubernetes系统组件调用时,或者需要保留master节点的资源时,我们可以标记一个Taint,当节点标记Taint时,除非Pod也被识别为可以容忍(Toleration)污点的节点,否则默认情况下Kubernetes scheduler不会将Pod调度到有污点的节点上

Kubernetes 亲和性调度

新闻联播老司机

  • 20年2月25日
  • 喜欢:0
  • 浏览:2.7k
  • 污点 Taint
    容忍 Toleration
    首先说一下污点Taint,当我们需要将master节点保留给Kubernetes系统组件调用时,或者需要保留master节点的资源时,我们可以标记一个Taint,当节点标记Taint时,除非Pod也被识别为可以容忍Toleration污点的节点,否则默认情况下Kubernetes scheduler不会将Pod调度到有污点的节点上
    Taint(污点)和 Toleration(容忍)可以作用于node和 pod 上,其目的是优化pod在集群间的调度,这跟节点亲和性类似,只不过它们作用的方式相反,具有taint的node和pod是互斥关系,而具有节点亲和性关系的node和pod是相吸的。另外还有可以给node节点设置label,通过给pod设置nodeSelector将pod调度到具有匹配标签的节点上。
    Taint 和 toleration 相互配合,可以用来避免pod被分配到不合适的节点上。每个节点上都可以应用一个或多个taint,这表示对于那些不能容忍这些taint的 pod,是不会被该节点接受的。如果将toleration应用于pod上,则表示这些pod可以(但不要求)被调度到具有相应taint的节点上。
    如果使用kubeadm搭建的集群,默认就会给master节点添加一个污点标记。我这里使用二进制安装一切自定义,所以我们跳过这步。从添加污点开始
    污点taint标记节点的命令

    # 添加taint污点命令
    kubectl taint nodes k8s-01 key=value:NoSchedule
    kubectl taint nodes k8s-02 key=value:NoExecute
    kubectl taint nodes k8s-03 key=value:PreferNoSchedule
    
    # 查看taint污点命令
    [root@k8s-01 test]# kubectl describe node k8s-01|grep Taints
    Taints:             key=value:NoSchedule
    
    
    #删除污点命令
    kubectl taint node k8s-01 key:NoSchedule-
    
    example
    kubectl taint node [节点] [任意值]:[NoSchedule、NoExecute、PreferNoSchedule]
    #删除和创建中的值要对应上,node节点的名称需要通过kubectl get node对应上
    
    #这里不执行
    

    首先我们先了解一下对应的参数

  • NoSchedule 新的不能容忍的pod不能再调度过来,但是之前运行在node节点中的Pod不受影响
  • NoExecute 新的不能容忍的pod不能调度过来,老的pod也会被驱逐
  • PreferNoScheduler 表示尽量不调度到污点节点中去
  • 容忍 Toleration
    前面我们介绍了将Pod添加污点,但是可能有一些比较重要的服务需要跑在master节点上,那么我们就需要添加一个容忍,允许哪些Pod跑在有污点的节点上
    这里我们还是使用上面学到的nodeAffinity,使用硬策略将pod捆绑在k8s-01节点上,同时又在k8s-01节点上配置污点

    #首先在k8s-01节点配置污点,将之前的pod全部移除
    kubectl taint nodes k8s-01 key1=value:NoExecute
    
    
    $ kubectl get pod --all-namespaces  -o wide
    NAMESPACE     NAME                                    READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
    kube-system   coredns-6776c9d69-6chbp                 1/1     Running   3          25d   172.30.200.2   k8s-03              
    kube-system   coredns-6776c9d69-n45nb                 1/1     Running   0          26s   172.30.232.2   k8s-02              
    kube-system   kubernetes-dashboard-78bcf8c65c-vfbkq   1/1     Running   4          25d   172.30.8.2     k8s-04               
    
    #目前k8s-01节点的pod已经全部移除
    

    接下来我们编写yaml文件,将nginx 添加容忍,并且使用硬策略只捆绑在k8s-01上 (这里使用硬策略和软策略或者不添加都是可以的。)

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: affinity
      labels:
        app: affinity
    spec:
      replicas: 3
      revisionHistoryLimit: 10
      template:
        metadata:
          labels:
            app: affinity
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - name: http
              containerPort: 80
    
          tolerations:      #添加容忍策略
            - key: "key1"    #对应我们添加节点的变量名
              operator: "Equal"    #操作符
              value: "value"    #容忍的值   key1=value对应
              effect: NoExecute   #添加容忍的规则,这里必须和我们标记的五点规则相同
    
          affinity:        
            nodeAffinity: 
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms: 
                - matchExpressions: 
                  - key: kubernetes.io/hostname
                    operator: In
                    values:
                    - k8s-01
    

    operator值是Exists,则value属性可以忽略
    operator值是Equal,则表示key与value之间的关系是等于
    operator不指定,则默认为Equal
    接下来我们创建查看结果

    kubectl get pod  -o wide
    NAME                        READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
    affinity-7c85766dcb-2g6sv   1/1     Running   0          29s   172.30.40.3   k8s-01              
    affinity-7c85766dcb-gfmb2   1/1     Running   0          29s   172.30.40.2   k8s-01              
    affinity-7c85766dcb-vpctf   1/1     Running   0          29s   172.30.40.4   k8s-01              
    
    #目前所有的Pod都调度在k8s-01节点上,但是如果我们这里规则写的不匹配,那么Pod将处于pending状态
    

    当然我们的匹配规则也是可以写成多个

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

    在NoExecute可以指定一个可选tolerationSeconds字段,该字段指示添加污点后,指定停留在node污点的时间

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

    意味着如果此Pod正在运行并将匹配的污点添加到该节点,则该Pod将与该节点绑定3600秒,然后被逐出。
    同时在Kubernets 1.6 引入了代表node问题的污点,node控制器当某种条件成立的时候会自动的给node打上污点。下面是其中内置的污点:

    node.kubernetes.io/not-ready:node不是ready状态。对应于node的condition ready=false.
    
    node.kubernetes.io/unreachable:node controller与node失联了。对应于node的condition ready=unknown
    
    node.kubernetes.io/out-of-disk:node磁盘空间不足了。
    
    node.kubernetes.io/network-unavailable:node的网断了
    
    node.kubernets.io/unschedulable:node不是可调度状态
    
    node.cloudprovider.kubernetes.io/uninitalized:kubelet是由外部云提供商提供的时候,刚开始的时候会打上这个污点来标记还未被使用。当cloud-controller-manager控制器初始化完这个node,kubelet会自动移除这个污点。
    

    配置案例,只需要将key修改成对应的值即可

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

    参考
    https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
    https://www.cnblogs.com/xiexj/p/10561237.html

    相关文章:

    1. Kubernetes 1.14 二进制集群安装
    2. Kubenetes 1.13.5 集群二进制安装
    3. Kuerbernetes 1.11 集群二进制安装
    4. CentOS 7 ETCD集群配置大全

    相关文章

    KubeSphere 部署向量数据库 Milvus 实战指南
    探索 Kubernetes 持久化存储之 Longhorn 初窥门径
    征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
    那些年在 Terraform 上吃到的糖和踩过的坑
    无需 Kubernetes 测试 Kubernetes 网络实现
    Kubernetes v1.31 中的移除和主要变更

    发布评论