cordon设置节点不可调度、uncordon恢复节点可调度、drain停机维护、 taint设置更新节点的污点

前言

环境:k8s 1.22.15、docker

一直对cordon、drain、 taint命令混淆,所以来区别一下。

cordon设置节点不可调度

bash 复制代码
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即可

uncordon恢复节点可调度

与cordon命令设置节点不可调度,对应的恢复节点可调度的命令是uncordon

bash 复制代码
Usage:
kubectl uncordon NODE [options]
演示示例:
#恢复node2节点可调度
kubectl uncordon node2

drain停机维护

drain命令用于节点停机维护、节点下线的操作,其原理也是通过设置节点不可调度并且驱逐节点的全部pod来实现的。

bash 复制代码
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

taint 设置更新node 上的污点

bash 复制代码
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

总结

bash 复制代码
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
相关推荐
运维开发故事6 天前
基于 Arthas 的多集群在线诊断系统设计与实现
kubernetes
Patrick_Wilson8 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
探索云原生8 天前
K8s 1.36 这个 GA 特性,把 initContainer 拉模型的 hack 干掉了
ai·云原生·kubernetes
Java之美9 天前
一次k8s升级引发的DevicePlugin注册失败
云原生·kubernetes
java_cj16 天前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes
qq_4523962316 天前
第十三篇:《K8s 安全基础:RBAC、ServiceAccount、Pod Security》
java·安全·kubernetes
睡不醒男孩03082316 天前
云原生运维实战:高并发架构下的云原生可观测性、韧性降级与自动化干预体系
数据库·kubernetes·高并发·prometheus·devops·sre·缓存调优
qq_4523962316 天前
第十四篇:《K8s 网络模型与 CNI 插件(Calico、Flannel、Cilium)》
网络·kubernetes·php
Hadoop_Liang16 天前
Kubernetes 应用 HTTPS 安全访问配置实践
https·kubernetes