容忍和污点Taint和Toleration设计理念:
Taint在一类服务器上打上污点,让不能容忍这个污点的Pod不能部署在打了污点的服务器上。(锁)
Toleration是让Pod容忍节点上配置的污点,可以让一些需要特殊配置的Pod能够调用到具有污点和特殊配置的节点上。(钥匙)
官方文档:https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/
Taint命令示例
NoSchedule:禁止调度到该节点,已经在该节点上的Pod不受影响
NoExecute:禁止调度到该节点,如果不符合这个污点,会立马被驱逐(或在一段时间后驱逐,默认300s,本文章后面可单独设置驱逐时间)
PreferNoSchedule:尽量避免将Pod调度到指定的节点上,如果没有更合适的节点,可以部署到该节点
创建一个污点(一个节点可以有多个污点):
kubectl taint nodes NODE_NAME TAINT_KEY=TAINT_VALUE:EFFECT
比如:
kubectl taint nodes k8s-node01 ssd=true:PreferNoSchedule
查看一个节点的污点:
kubectl get node k8s-node01 -o go-template --template {{.spec.taints}}
kubectl describe node k8s-node01 | grep Taints -A 10
删除污点(和label类似):
基于Key删除: kubectl taint nodes k8s-node01 ssd-
基于Key+Effect删除: kubectl taint nodes k8s-node01 ssd:PreferNoSchedule-
修改污点(Key和Effect相同):
kubectl taint nodes k8s-node01 ssd=true:PreferNoSchedule --overwrite
Toleration配置解析
示例1(完全匹配)
key和value必须一致,且Taint为NoSchedule才被匹配
Equal:等于
tolerations:
- key: "taintKey"
operator: "Equal"
value: "taintValue"
effect: "NoSchedule"
示例2(不完全匹配)
所有包含这个key的node,且Taint为NoSchedule都有可能被匹配
Exists:包含
tolerations:
- key: "taintKey"
operator: "Exists"
effect: "NoSchedule"
示例3(大范围匹配)
不能使用key为内置Taint
Exists:包含
tolerations:
- key: "taintKey"
operator: "Exists"
Taint和Toleration使用案例
需求:Node01是纯SSD硬盘的节点,把需要高性能存储的Pod调度到该节点上。
1、给节点打上污点和标签
kubectl taint nodes k8s-node01 ssd=true:NoExecute(此时会驱逐没有容忍该污点的Pod)
kubectl taint nodes k8s-node01 ssd=true:NoSchedule(禁止所有pod调度到该节点)
kubectl label node k8s-node01 ssd=true(给node01打标签)
2、配置pod
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
ssd: "true"
tolerations:
- key: "ssd"
operator: "Exists" # 包含key为ssd的所有节点
k8s内置污点
内置污点解析
node.kubernetes.io/not-ready:节点未准备好,相当于节点状态Ready的值为False。
node.kubernetes.io/unreachable:Node Controller访问不到节点,相当于节点状态Ready的值为Unknown。node.kubernetes.io/out-of-disk:节点磁盘耗尽。
node.kubernetes.io/memory-pressure:节点存在内存压力。
node.kubernetes.io/disk-pressure:节点存在磁盘压力。
node.kubernetes.io/network-unavailable:节点网络不可达。
node.kubernetes.io/unschedulable:节点不可调度。
node.cloudprovider.kubernetes.io/uninitialized:如果Kubelet启动时指定了一个外部的cloudprovider,它将给当前节点添加一个Taint将其标记为不可用。在cloud-controller-manager的一个controller初始化这个节点后,Kubelet将删除这个Taint。
如节点不健康,6000秒后再驱逐(默认是300秒):
tolerations:
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000
Taint&Toleration利用k8s内置污点,确保节点宕机后快速恢复业务应用(生产建议使用)
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: tolerations-second
name: tolerations-second
spec:
replicas: 1
selector:
matchLabels:
app: tolerations-second
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: tolerations-second
spec:
containers:
- image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx
name: nginx
resources:
requests:
cpu: 10m
nodeSelector:
ssd: "true"
tolerations:
- key: ssd
operator: Equal
value: "true"
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 10
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 10