Kubernetes

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

2020-03-19  本文已影响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 有三个策略:

示例

  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也可能调度到其他无污点的节点上,并不能保证只调度到我们的预期的节点上

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

上一篇 下一篇

猜你喜欢

热点阅读