目录
Kubernetes 节点管理:cordon
、drain
和 delete
命令
在 Kubernetes 集群中,管理节点时常涉及到将节点从调度中排除以便进行维护。常用的操作包括 cordon
、drain
和 delete
。这三个命令的主要作用是停止新 Pod 的调度到特定节点上,但其实施的方式和影响程度各不相同。
1. cordon
命令
cordon
命令将节点标记为不可调度状态 (SchedulingDisabled
)。执行该命令后,新创建的 Pod 不会被调度到该节点,但现有的 Pod 继续运行,不受影响。这是影响最小的操作,适用于需要短时间隔离节点的情况。
命令使用:
- 禁止调度:
kubectl cordon <node-name>
- 恢复调度:
kubectl uncordon <node-name>
(恢复到K8S集群中,变回可调度状态)
2. drain
命令
drain
命令比 cordon
更进一步,不仅将节点标记为不可调度,还会逐步将节点上的 Pod 迁移到其他节点。在迁移过程中,drain
会优雅地终止 Pod,遵循 PodDisruptionBudgets (PDB) 的设置,确保应用不中断。
- drain方式是安全驱逐pod,会等到pod容器应用程序优雅停止后再删除该pod。
- drain驱逐流程:先在Node节点删除pod,然后再在其他Node节点创建该pod。所以为了确保drain驱逐pod过程中不中断服务(即做到"无感知"地平滑驱逐),必须保证要驱逐的pod副本数大于1,并且采用了"反亲和策略"将这些pod调度到不同的Node节点上了!也就是说,在"多个pod副本+反亲和策略"的场景下,drain驱逐过程对容器服务是没有影响的。
命令使用:
- 驱逐并禁止调度:
kubectl drain <node-name> --force --ignore-daemonsets --delete-local-data
- 恢复调度:
kubectl uncordon <node-name>
注意事项:
drain
命令会忽略 DaemonSet 管理的 Pod,需要加--ignore-daemonsets
参数。- 对于使用本地存储的 Pod,可能需要加
--delete-local-data
以强制删除。
drain
是一种安全的驱逐方式,适用于节点维护前的操作,如内核升级或硬件更换。在实施 drain
之前,确保 Pod 副本数大于 1 并且配置了反亲和策略,以避免服务中断。
在生产环境中,通常会为 Kubernetes 集群中的 Pod 配置 PodDisruptionBudget (PDB),以确保在 Pod 被驱逐时服务的可用性。理想情况下,PDB 的配置通常是 maxUnavailable
设置为 0,maxSurge
设置为 1。这意味着在驱逐过程中,Pod 的总数不会减少,从而确保服务的连续性和稳定性。
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
3. delete
命令
delete
命令是最具破坏性的操作,会直接从集群中删除节点及其上的所有 Pod。此操作类似于强制删除,会忽略 PDB 和 Pod 的优雅终止设置。使用 delete
命令后,如果需要重新将节点加入集群,需要手动重新启动 kubelet
并处理证书签发。
命令使用:
- 删除节点:
kubectl delete node <node-name >
恢复调度(即重新加入到K8S集群中)
- delete删除后,后续如果需重新加入K8S集群。则需要重启node节点的kubelet服务,重启后,基于node的自注册功能,该节点才能重新加入到K8S集群,并且恢复使用(即恢复可调度的身份)。
- 另外:如果kubelet服务重启后,node节点系统时间跟其他节点不一致,则导致该节点证书会失效!kubelet注册后,还需要手动approve签发TLS认证操作了。如下示例:
node02节点重启后,系统时间变了,跟其他node节点系统时间不一致,导致该节点的集群证书失效!
[root@k8s-master01 ingress]# kubectl exec -ti test-finhub-app-56df548879-ghlb2 -n wiseco -- /bin/bash
Error from server: error dialing backend: x509: certificate is valid for k8s-master01, not k8s-node02
[root@k8s-master01 ingress]# kubectl get csr
NAME AGE REQUESTOR CONDITION
csr-7zt2w 50m system:node:k8s-node02 节点重启后 Pending
csr-8sw6k 36m system:node:k8s-node02 节点重启后 Pending
csr-9jv7z 21m system:node:k8s-node02 节点重启后 Pending
需要手动approve签发TLS认证
[root@k8s-master01 ingress]# kubectl certificate approve csr-7zt2w
[root@k8s-master01 ingress]# kubectl certificate approve csr-8sw6k
[root@k8s-master01 ingress]# kubectl certificate approve csr-9jv7z
4.节点平滑维护的推荐步骤
通常情况下,如果要对K8S集群中的一台Node节点进行平滑维护,如升级或调整配置。正确的操作:
- cordon临时从K8S集群隔离出来,标识为SchedulingDisabled不可调度状态。
- drain排干该节点上的pod资源到其他node节点上。
- 对该节点展开平滑维护操作,如升级或调整配置。
- uncordon恢复,重新回到K8S集群,变回可调度状态。
同时注意:为了确保drain驱逐pod的时候,容器应用服务不中断,必须满足:
- 要驱逐的pod副本数量必须大于1
- 要配置"反亲和策略",确保被驱逐的pod被调度到不同的Node节点上
- deployment采用滚动更新,设置maxUnavailable为0,maxSurge为1