污点调度
通过在节点上设置污点,只有Pod容忍这个污点才能被调度到这个节点上来。
taint中effect定义对pod的排斥等级
- PreferNoSchedule: 如果不能容忍该节点的污点,最好不要调度到该节点,但是不强制拒绝调度,仅影响调度过程,对现存的Pod对象不产生影响
- NoSchedule: 如果不能容忍该节点的污点,则不会调度到该节点,仅影响调度过程,对现存的Pod对象不产生影响
- NoExecute: 如果不能容忍该节点的污点,则不会调度到该节点,不仅影响调度过程,还对现存Pod对象产生影响,如果现存Pod不容忍新的污点,则会被驱逐。
污点调度的逻辑
- 检查节点污点是否可被Pod容忍
- 如果可容忍,则会调度到节点运行
- 如果不可容忍,则检查污点排斥等级
- 如果是PreferNoSchedule,Pod会调度到节点上
- 如果是NoSchedule或NoExecute都不会调度上来
如果后续节点增加污点
- 如果污点排斥等级是PreferNoSchedule或NoSchedule,则不会影响现有Pod
- 如果污点排斥等级是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
污点调度适用场景
- Master节点只调度运行k8s集群组件
- 特定的节点仅用特定的用户组使用
- 一般的Pods不要调度到具有特定硬件功能的节点
- ...
补充说明
关于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