污点调度

通过在节点上设置污点,只有Pod容忍这个污点才能被调度到这个节点上来。

taint中effect定义对pod的排斥等级

  • PreferNoSchedule: 如果不能容忍该节点的污点,最好不要调度到该节点,但是不强制拒绝调度,仅影响调度过程,对现存的Pod对象不产生影响
  • NoSchedule: 如果不能容忍该节点的污点,则不会调度到该节点,仅影响调度过程,对现存的Pod对象不产生影响
  • NoExecute: 如果不能容忍该节点的污点,则不会调度到该节点,不仅影响调度过程,还对现存Pod对象产生影响,如果现存Pod不容忍新的污点,则会被驱逐。

污点调度的逻辑

  1. 检查节点污点是否可被Pod容忍
  2. 如果可容忍,则会调度到节点运行
  3. 如果不可容忍,则检查污点排斥等级
  4. 如果是PreferNoSchedule,Pod会调度到节点上
  5. 如果是NoSchedule或NoExecute都不会调度上来

如果后续节点增加污点

  1. 如果污点排斥等级是PreferNoSchedule或NoSchedule,则不会影响现有Pod
  2. 如果污点排斥等级是NoExecute,则Pod会被驱逐出节点

示例

给node002打了一个污点

# kubectl taint node node002 node-type=develop:NoExecute
node/node002 tainted

此时创建容器,容忍污点

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 2
  revisionHistoryLimit: 5
  selector:
    matchLabels:
      app: myapp
      release: canary
      environment: qa
  strategy:
    type: RollingUpdate
    rollingUpdate: 
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      name: myapp-container
      labels:
        app: myapp
        release: canary
        environment: qa
    spec:
      tolerations:
      - key: "node-type"
        # Exists 较为宽松,只要容忍指定污点的KEY就可以
        # Equal 则较严格,严格判断指定的污点KEY和VALUE
        operator: "Equal"
        value: "production"
        effect: "NoExecute"
        # 因为是NoExecute会驱逐Pod,所以这里需要配置容忍时间
        tolerationSeconds: 1800

      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: app-port
          containerPort: 80
        livenessProbe:
          tcpSocket:
            port: app-port
          timeoutSeconds: 1
        readinessProbe:
          httpGet:
            scheme: HTTP
            port: app-port
            path: /index.html

创建Pod可以看到,由于node002上有污点,虽然配置了容忍node-type污点,但是由于值不同,所以Pod全部调度到node003上了

# kubectl apply -f pod-toleration-deploy-demo.yaml 
deployment.apps/myapp-deploy created

# kubectl get pods -o wide
NAME                           READY     STATUS    RESTARTS   AGE       IP            NODE
client-bbf58867f-5qmcc         1/1       Running   0          2m        10.244.2.32   node003
myapp-deploy-745847577-6gw8w   0/1       Running   0          5s        10.244.2.34   node003
myapp-deploy-745847577-vwsm4   0/1       Running   0          5s        10.244.2.35   node003

污点调度适用场景

  1. Master节点只调度运行k8s集群组件
  2. 特定的节点仅用特定的用户组使用
  3. 一般的Pods不要调度到具有特定硬件功能的节点
  4. ...

补充说明

关于operator、value、effect

以下几种情况代表的含义

容忍污点,不校验污点值以及影响级别

tolerations:
- key: "node-type"
operator: "Exists"
value: ""
effect: ""

容忍污点,不校验污点值,但校验影响级别

tolerations:
- key: "node-type"
operator: "Exists"
value: ""
effect: "NoSchedule"

严格校验容忍污点、污点值以及污点影响级别

tolerations:
- key: "node-type"
operator: "Equal"
value: "production"
effect: "NoExecute"

还有一种奇怪的写法,突发奇想出来的,这种需要node-type污点的值为空,才会调度上去

tolerations:
- key: "node-type"
operator: "Equal"
value: ""
effect: ""

可以简单,一点理解

operator value effect 描述
Exists 必须为空"" "" 容忍指定污点不管什么值和影响级别
EXists 必须为空"" "NoSchedule" 容忍指定影响级别的指定污点
Equal "blabla" "" 容忍任何影响级别的指定污点
Equal "blabla" "PreferNoSchedule"\ "NoSchedule"\ "NoExecute" 容忍指定影响级别的指定污点,并且污点值要一样

同名污点可以有多个值

# kubectl taint node node002 node-type=:NoExecute
# kubectl taint node node002 node-type=kvm:PreferNoSchedule
# kubectl describe node node002|egrep -a1  Taint 
CreationTimestamp:  Fri, 31 Aug 2018 11:22:31 +0800
Taints:             node-type:NoExecute
                    node-type=kvm:PreferNoSchedule

results matching ""

    No results matching ""