环境:k8s 1.22.15、docker
一直对cordon、drain、 taint命令混淆,所以来区别一下。
kubectl cordon NODE命令设置节点不可调度,仅仅是节点不可调度而已,已存在的pod不会驱逐,新的pod不会被调度到该节点上。
Usage:
kubectl cordon NODE [options]
演示示例:
#设置node2不可调度
kubectl cordon node2
#查看节点信息,现在node2已经设置不可调度了,所以新创建的pod不会被调度到node2节点,之前就已经存在于node2节点上的pod也不会被驱逐
[root@matser ~]# kubectl describe node node2 | grep Unschedulable
Unschedulable: true
[root@matser ~]# kubectl get node node2
NAME STATUS ROLES AGE VERSION
node2 Ready,SchedulingDisabled node 353d v1.22.15
#我们发现,当设置节点不可调度的时候,k8s会自动打上污点,如下:
Taints: node.kubernetes.io/unschedulable:NoSchedule
Unschedulable: true
#使用path命令也可以设置节点不可调度
kubectl patch node node2 -p '{"spec":{"unschedulable": true}}'
#使用path命令恢复节点可以可调度
kubectl patch node node2 -p '{"spec":{"unschedulable": false}}'
#除了上面的使用cordon、patch命令设置节点不可调度之后之外,还可以直接修改节点资源来实现节点不可调度
#默认没有unschedulable参数,在spec下添加unschedulable: true 即可实现设置node不可调度
kubectl edit node node2
#去除不可调度也可以直接kubectl edit node node2,找到unschedulable设置false即可
与cordon命令设置节点不可调度,对应的恢复节点可调度的命令是uncordon
Usage:
kubectl uncordon NODE [options]
演示示例:
#恢复node2节点可调度
kubectl uncordon node2
drain命令用于节点停机维护、节点下线的操作,其原理也是通过设置节点不可调度并且驱逐节点的全部pod来实现的。
Usage:
kubectl drain NODE [options]
#驱逐pod,默认当节点存在ds的pod时,命令执行报错,所以需要加上--ignore-daemonsets=true参数
kubectl drain node2 --ignore-daemonsets=true
--ignore-daemonsets
#强制驱逐pod
kubectl drain node2 --force
#设置驱逐15分钟的宽限期
kubectl drain node2 --ignore-daemonsets=true --grace-period=900
#我们发现,当使用drain命令之后,k8s默认会将节点设置为不可调度
Taints: node.kubernetes.io/unschedulable:NoSchedule
Unschedulable: true
#所以以上,当我们需要对一个节点下线停机维护时,可以这样做:
#先设置节点不可调度,防止新的pod调度到节点,此时不会驱逐节点上的pod
kubectl cordon node2
#此时使用drain命令驱逐节点pod
kubectl drain node2 --ignore-daemonsets=true
#节点维护之后需要重新上线恢复调度
kubectl uncordon node2
taints,污点是定义在node节点之上的键值型属性数据,用于让node节点拒绝将pod调度运行于其上,除非该pod对象具有接纳节点污点的容忍度。
污点是pod调度中的一种调度策略,污点作用在node节点上,当为某个node节点打上污点,则表示该node是否允许pod调度过来。
污点的格式:key=value:effect,其中key和value是污点的标签,可以自行拟定,effect描述污点的作用,effect支持如下三个选项:
PreferNoSchedul: kubernetes将尽量避免把pod调度到具有该污点的node上,除非没有其他节点可调度;
NoSchedule: kubernetes将不会把pod调度到具有该污点的node上,但不会影响当前node已存在的pod;
NoExecute: kubernetes将不会把pod调度到具有该污点的node上,同时还会驱逐node上已存在的pod;
Usage:
kubectl taint NODE NAME KEY_1=VAL_1:TAINT_EFFECT_1 ... KEY_N=VAL_N:TAINT_EFFECT_N [options]
演示示例:
#设置污点,指定标签为dedicated=special-user,策略为NoSchedule,如果该标签已存在则更新策略
kubectl taint nodes node2 dedicated=special-user:NoSchedule
#移除key为dedicated的NoSchedule污点
kubectl taint nodes node2 dedicated:NoSchedule-
#移除key为dedicated的所有污点
kubectl taint nodes node2 dedicated-
#查看污点
[root@master ~]# kubectl describe nodes node2 | grep Taints
Taints: dedicated=special-user:NoSchedule
#以上,train的设置并不会影响节点的Unschedulable,如下所示;因为污点仅仅是污点,而当pod存在容忍时,仍然是可以调度到节点上的
[root@matser ~]# kubectl describe node node2 | grep -A1 -i Taints
Taints: dedicated=special-user:NoSchedule
Unschedulable: false
[root@matser ~]# kubectl get node node2
NAME STATUS ROLES AGE VERSION
node2 Ready node 353d v1.22.15
#注意taint并不能代替drain,如下
kubectl taint nodes node2 dedicated=special-user:NoExecute
#测试node2上的普通pod已经被驱逐,但是ds的pod没有被驱逐,因为pod存在NoExecute的容忍
[root@matser ~]# kubectl describe node node2 | grep -A1 -i Taints
Taints: dedicated=special-user:NoExecute
Unschedulable: false
[root@matser ~]# kubectl get node node2 #节点仍然是可以调度的,只要存在pod中存在容忍即可调度到node2节点
NAME STATUS ROLES AGE VERSION
node2 Ready node 353d v1.22.15
1、cordon命令用于设置节点不可调度
#设置节点不可调度,不会驱逐已有的pod
kubectl cordon node2
#恢复节点可调度
kubectl uncordon node2
2、cordon 命令用于节点下线停机维护
#先设置节点不可调度,防止新的pod调度到节点,此时不会驱逐节点上的pod
kubectl cordon node2
#此时使用drain命令驱逐节点pod
kubectl drain node2 --ignore-daemonsets=true
#节点维护之后需要重新上线恢复可调度即可
kubectl uncordon node2
小结:
使用cordon命令设置节点不可调度或cordon命令驱逐节点pod下线停机维护都会给节点打上污点,如下:
Taints: node.kubernetes.io/unschedulable:NoSchedule
Unschedulable: true
3、taint设置更新节点的污点
污点的格式: key=value:effect,key和value是污点的标签,可以自行拟定,effect描述污点的作用,effect支持如下三个选项:
PreferNoSchedul: kubernetes将尽量避免把pod调度到具有该污点的node上,除非没有其他节点可调度;
NoSchedule: kubernetes将不会把pod调度到具有该污点的node上,但不会影响当前node已存在的pod;
NoExecute: kubernetes将不会把pod调度到具有该污点的node上,同时还会驱逐node上已存在的pod;
#设置污点,指定标签为dedicated=special-user,策略为NoSchedule
kubectl taint nodes node2 dedicated=special-user:NoSchedule
#移除key为dedicated的NoSchedule污点
kubectl taint nodes node2 dedicated:NoSchedule-
#移除key为dedicated的所有污点
kubectl taint nodes node2 dedicated-
#设置node2污点,策略为NoExecute
kubectl taint nodes node2 dedicated=special-user:NoExecute
#注意一点,不要混淆节点不可调度,节点上存在污点节点仍然是可以调度的,只要pod中存在容忍即可调度到node2节点
[root@matser ~]# kubectl describe node node2 | grep -A1 -i Taints
Taints: dedicated=special-user:NoExecute
Unschedulable: false #不要混淆节点不可调度
[root@matser ~]# kubectl get node node2
NAME STATUS ROLES AGE VERSION
node2 Ready node 353d v1.22.15