1.1. 污点和容忍度调度

在Kubernetes中通过给一个Node设置污点,以及Pod对于这个污点的容忍度结合起来实现哪些Pod可以被调度到哪些节点上,只有当一个Pod可以容忍某个节点的污点,这个Pod才会可能被调度该节点上。

请注意污点是在Node上设置的,而容忍度是在Pod上设置的。

1.2. Taints(污点)

[root@linux-node1 ~]# kubectl describe node linux-node1.example.com | grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule

Taints的表现形式为

<key>=<value>:<effect>
  • key: 就是污点的key
  • value:污点的值,如上面是一个空的value,所以没有显示=
  • effect:设置当有这个污点是产生的效果。

effect的三种类型:

  • NoSchedule: 如果Pod没有容忍该污点,不调度到该节点上。
  • PreferNoSchedule:尽量阻止Pod被调度到这个节点上,但是如果没有其它节点能够调度,可以调度到该节点。
  • NoExecute: NoScheduler和PreferNoSchedule只是在调度阶段起作用,但是NoExecute会影响正常运行的Pod,如果一个节点被打了NoExecute的污点,而运行在该节点的Pod没有容忍会直接被这个节点移除。

1.3. 污点容忍度度

查看Flannel为何能调度到Master节点

[root@linux-node1 ~]# kubectl get po -n kube-system | grep flannel
kube-flannel-ds-amd64-f2jrk                       1/1     Running   2          22h
kube-flannel-ds-amd64-mh75v                       1/1     Running   2          22h
kube-flannel-ds-amd64-n52zm                       1/1     Running   4          22h

[root@linux-node1 ~]# kubectl describe pod kube-flannel-ds-amd64-f2jrk -n kube-system
...
Tolerations:     :NoSchedule
                 node.kubernetes.io/disk-pressure:NoSchedule
                 node.kubernetes.io/memory-pressure:NoSchedule
                 node.kubernetes.io/network-unavailable:NoSchedule
                 node.kubernetes.io/not-ready:NoExecute
                 node.kubernetes.io/pid-pressure:NoSchedule
                 node.kubernetes.io/unreachable:NoExecute
                 node.kubernetes.io/unschedulable:NoSchedule

1.3.1. 自定义污点

案例:让Pod不能运行在用于运行Ingress Controller的Node上。

  1. 设置污点

    [root@linux-node1 ~]# kubectl taint node linux-node2.example.com node-type=edge:NoSchedule
    node/linux-node2.example.com tainted
    
  2. 创建Deployment测试

[root@linux-node1 ~]# kubectl run taint-test --image=alpine --replicas 3 sleep 360000
  1. 查看调度情况
    [root@linux-node1 ~]# kubectl get pod -o wide | grep taint-test
    taint-test-5967486bf-mqvj7                1/1     Running   0          54s     10.2.2.52   linux-node3.example.com   <none>           <none>
    taint-test-5967486bf-stqp9                1/1     Running   0          54s     10.2.2.54   linux-node3.example.com   <none>           <none>
    taint-test-5967486bf-vtwrb                1/1     Running   0          54s     10.2.2.53   linux-node3.example.com   <none>           <none>
    

1.3.2. 自定义污点容忍

  1. 创建一个Nginx的Deployment并设置污点容忍度
[root@linux-node1 example]# cat nginx-deployment-taint.yaml    
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.13.12
        ports:
        - containerPort: 80
      tolerations:
      - key: node-type
        operator: Equal
        value: edge
        effect: NoSchedule
  1. 创建并查看调度结果
    [root@linux-node1 ~]# kubectl create -f nginx-deployment-taint.yaml 
    deployment.apps/nginx-deployment created
    [root@linux-node1 ~]# kubectl get pod -o wide | grep nginx-deployment
    nginx-deployment-7ccbbfb64c-24gfn         1/1     Running   0          15s     10.2.1.35   linux-node2.example.com   <none>           <none>
    nginx-deployment-7ccbbfb64c-fk26t         1/1     Running   0          15s     10.2.1.36   linux-node2.example.com   <none>           <none>
    nginx-deployment-7ccbbfb64c-qtv2w         1/1     Running   0          15s     10.2.2.55   linux-node3.example.com   <none>           <none>
    

operator支持两个选项Equal和Exists,Equal用与匹配对应的value也是默认的操作符,Exists用来匹配污点的Key。

1.3.3. 删除节点的污点

[root@linux-node1 ~]# kubectl taint node linux-node2.example.com node-type-

1.4. 关键组件的调度保证

除了Kubernetes核心组件,像运行在 master 机器上的 api-server、scheduler、controller-manager之外,还有很多插件,出于各种原因必须运行在一个普通的集群节点上(而不是 Kubernetes master),例如使用kubeadm创建的集群使用了DaemonSet运行kube-proxy,如果一个Pod被定义为关键组件,那么

成为关键插件

想变成关键插件,首先该Pod必须运行在 kube-system Namespace 中,并且需要符合以下两个条件:

  1. 需要将 priorityClassName 设置为 system-cluster-critical 或 system-node-critical ,后者是整个群集的最高级别。 或者,也可以为 Pod 添加名为 scheduler.alpha.kubernetes.io/critical-pod、值为空字符串的注解。 不过,这一注解从 1.13 版本开始不再推荐使用,并将在 1.14 中删除。
  2. 将PodSpec 的 tolerations 字段设置为 [{"key":"CriticalAddonsOnly", "operator":"Exists"}]

kube-proxy案例

[root@linux-node1 ~]# kubectl describe pod kube-proxy-7gxrh -n kube-system | grep Only
                 CriticalAddonsOnly
[root@linux-node1 ~]# kubectl describe pod kube-proxy-7gxrh -n kube-system | grep Priority
Priority:             2000001000
Priority Class Name:  system-node-critical

1.5. 默认的污点容忍度

[root@linux-node1 ~]# kubectl get pod jenkins-deployment-687ffcd9c4-l7b5k -o yaml
...
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
...

创建的Pod如果没有增加以上两个容忍度的,会默认加上。

  • key: node.kubernetes.io/not-ready:表示Pod所在节点处于not ready的时候,Pod将会等待300秒之后把该Pod重新调度到其它节点上。
  • key:node.kubernetes.io/unreachable:表示Pod所在的节点处于unreachable状态时,Pod将会等待300秒之后把Pod重新调度到其它节点上。

如果你认为300秒时间有点长,可以在Pod定义中添加自定义的时间。

Copyright © 赵班长@新运维社区 2019 all right reserved,powered by Gitbook该文件修订时间: 2020-05-20 22:58:56

results matching ""

    No results matching ""