美文网首页Kubernetes
巧用标签+污点对节点划分资源池

巧用标签+污点对节点划分资源池

作者: 街上太拥挤 | 来源:发表于2020-03-19 17:34 被阅读0次

    背景

    在日常使用k8s集群中,有时候需要某些节点只运行某些pod,既不希望有其他的pod调度过来,也不希望这些pod调度到别的其他节点上。比如说,有NodeA,只希望运行一个PodA,不想要PodB也调度到NodeA上,并且,不希望PodA会调度到NodeB上

    针对上面的问题,其实我们可以使用标签+污点的方式去实现,而当使用多组标签+污点时,也就把节点资源划分一个个池了
    接下来,我们看看标签和污点如何使用

    1. 标签label

    node资源的metadata.labels属性,给节点加上标签,比如test=test,pod通过nodeAffinitynodeSelector配置test: test,则pod会调度到含有该标签的节点上
    kubectl label命令时,label的格式为key=value

    1.1 示例

    1. 先给主机打上label
    root@10 ~]# kubectl get no
    NAME                   STATUS   ROLES    AGE     VERSION
    10.10.101.170-master   Ready    master   7d21h   v1.17.2
    10.10.101.171-slave    Ready    <none>   7d21h   v1.17.2
    10.10.101.172-slave    Ready    <none>   7d21h   v1.17.2
    10.10.101.173-slave    Ready    <none>   7d20h   v1.17.2
    10.10.101.174-build    Ready    <none>   7d20h   v1.17.2
    10.10.101.176-share    Ready    <none>   7d20h   v1.17.2
    10.10.103.108-share    Ready    <none>   6d23h   v1.17.2
    
    [root@10 ~]# kubectl get no -l test=test
    No resources found in default namespace.
    
    // 删除该label的命令是kubectl label no 10.10.101.176-share test-
    [root@10 ~]# kubectl label no 10.10.101.176-share test=test
    node/10.10.101.176-share labeled
    
    [root@10 ~]# kubectl get no -l test=test
    NAME                  STATUS   ROLES    AGE     VERSION
    10.10.101.176-share   Ready    <none>   7d20h   v1.17.2
    
    1. 部署一个pod不指定和nodeAffinitynodeSelector
      预期:随机调度到一个节点上
    // 未指定label的yaml文件
    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
      namespace: default
      labels:
        app: test-pod
    spec:
      containers:
      - name: test-container
        image: busybox
        command: ['sh', '-c', 'echo Hello Harmonycloud! && sleep 3600']
    
    [root@10 ~]# kubectl create -f busybox.yaml
    pod/test-pod created
    
    [root@10 ~]# kubectl get po -owide
    NAME       READY   STATUS    RESTARTS   AGE   IP               NODE                  NOMINATED NODE   READINESS GATES
    test-pod   1/1     Running   0          38s   10.168.216.168   10.10.103.108-share   <none>           <none>
    

    多删除创建几次,可以发现test-pod会调度到不同的节点

    1. 部署一个pod指定nodeAffinitynodeSelector
      预期:只调度到10.10.101.176-share节点上
    // 通过nodeSelector指定label的yaml文件如下
    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
      namespace: default
      labels:
        app: test-pod
    spec:
      containers:
      - name: test-container
        image: busybox
        command: ['sh', '-c', 'echo Hello Harmonycloud! && sleep 3600']
      nodeSelector:
        test: test
    
    // 按照上面的yaml添加nodeSelector
    [root@10 ~]# kubectl edit po test-pod
    pod "test-pod" edited
    
    [root@10 ~]# kubectl get po -owide
    NAME       READY   STATUS    RESTARTS   AGE   IP               NODE                  NOMINATED NODE   READINESS GATES
    test-pod   1/1     Running   0          52s   10.168.216.170   10.10.101.176-share   <none>           <none>
    

    无论test-pod删除再创建多少次,都会调度到10.10.101.176-share节点上

    2. 污点taint

    node资源的spec.taints属性,给节点加上污点,比如说node-role.kubernetes.io/slave=:NoSchedule,则只有配置了容忍该污点(tolerations)的pod才能调度到该节点上
    污点的格式分为三段,key=value:effect,其中 effect 有三个策略:

    • NoSchedule:表示 pod 不会被调度到标记为 taints 的节点
    • PreferNoSchedule:NoSchedule 的软策略版本,表示尽量不调度到污点节点上去
    • NoExecute:该选项意味着一旦 Taint 生效,如该节点内正在运行的 pod 没有对应 tolerations 设置,会直接被逐出

    示例

    1. 10.10.101.176-share加上污点node-role.kubernetes.io/slave=:NoSchedule
    [root@10 ~]# kubectl describe no 10.10.101.176-share | grep -E '(Roles|Taints)'
    Roles:              <none>
    Taints:             <none>
    
    [root@10 ~]# kubectl taint node 10.10.101.176-share node-role.kubernetes.io/slave=:NoSchedule
    node/10.10.101.176-share tainted
    
    [root@10 ~]# kubectl describe no 10.10.101.176-share | grep -E '(Roles|Taints)'
    Roles:              <none>
    Taints:             node-role.kubernetes.io/slave:NoSchedule
    
    1. 部署pod-test,通过label指定调度到10.10.101.176-share节点
      由于是NoSchedule策略,之前已在该节点上的podpod-test不会被驱逐,所以我们先把pod删了再创建
      预期:pod-test处于Pending状态
    // 先删除原本的pod再创建
    [root@10 ~]# kubectl delete po test-pod
    pod "test-pod" deleted
    [root@10 ~]# kubectl create -f busybox.yaml
    pod/test-pod created
    [root@10 ~]# kubectl get po -owide
    NAME       READY   STATUS    RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
    test-pod   0/1     Pending   0          14s   <none>   <none>   <none>           <none>
    
    // 查看Pending原因
    [root@10 ~]# kubectl describe po test-pod
    Events:
      Type     Reason            Age                From               Message
      ----     ------            ----               ----               -------
      Warning  FailedScheduling  49s (x2 over 49s)  default-scheduler  0/7 nodes are available: 1 node(s) had taints that the pod didn't tolerate, 6 node(s) didn't match node selector.
    
    1. test-pod加上tolerations
    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
      namespace: default
      labels:
        app: test-pod
    spec:
      containers:
      - name: test-container
        image: busybox
        command: ['sh', '-c', 'echo Hello Harmonycloud! && sleep 3600']
      nodeSelector:
        test: test
      tolerations:
        - key: "node-role.kubernetes.io/slave"
          operator: "Exists"
          value: ""
          effect: "NoSchedule"
    
    // 按照上面的yaml去添加tolerations
    [root@10 ~]# kubectl edit po test-pod
    pod "test-pod" edited
    
    [root@10 ~]# kubectl get po -owide
    NAME       READY   STATUS    RESTARTS   AGE   IP               NODE                  NOMINATED NODE   READINESS GATES
    test-pod   1/1     Running   0          16s   10.168.216.171   10.10.101.176-share   <none>           <none>
    

    可以看到,test-pod调度到10.10.101.176-share节点上了


    节点资源池划分

    节点资源池,是对k8s集群的所有节点进行逻辑层面的划分,每个池里的pod,应该要做到无论重启多少次,只会在该池的节点上,如何对pod调度进行控制,通过上面的示例,我们知道了:

    • 使用标签,可以使pod调度到预期的节点上
    • 使用污点,可以避免未容忍该污点的pod调度到节点上

    如果只使用标签,固然我们可以把自己想要的pod调度到预期节点上,但是其他的pod也有可能调度到上面,因此只靠标签还不够,我们需要把其他的pod都驱逐,避免资源被占用。
    反过来,如果只使用污点,的确能够避免其他的pod调度到预期节点上,但是我们自己的pod也可能调度到其他无污点的节点上,并不能保证只调度到我们的预期的节点上

    至此,使用 标签 + 污点 ,我们的节点资源池划分也就可以实现了!

    相关文章

      网友评论

        本文标题:巧用标签+污点对节点划分资源池

        本文链接:https://www.haomeiwen.com/subject/bbmlyhtx.html