Kubernetes 结点排水卡住的原因及解决方案
1. Pod 不能被安全驱逐
Pod 没有副本(如 Deployment
、StatefulSet
)
如果 Pod 不是由 Deployment
、DaemonSet
、StatefulSet
之类的控制器管理,而是一个独立的 Pod(kubectl run
创建的或者直接使用 Pod
资源定义的),K8s 不会自动重新调度它,从而导致 drain
命令卡住。
Pod 具有 PodDisruptionBudget(PDB)
限制
如果 PodDisruptionBudget
(PDB)策略规定了最少可用副本数,而驱逐该节点上的 Pod 会导致违反 PDB,drain
就会卡住。
解决办法:
kubectl get pdb -A
找到受影响的 PDB,并根据情况调整 minAvailable
或 maxUnavailable
参数。
2. DaemonSet Pod 不能被驱逐
DaemonSet
管理的 Pod 默认不会被驱逐,kubectl drain
会一直等待它们被手动删除或使用--ignore-daemonsets
参数。
解决办法:
kubectl drain <node> --ignore-daemonsets
3. 强制 Pod 驱逐
- 如果有 Pod 设置了
finalizer
或TerminationGracePeriodSeconds
,K8s 会等待 Pod 正常终止,超时可能会卡住。
解决办法:
kubectl delete pod <pod-name> --force --grace-period=0 --namespace=<namespace>
4. Pod 持有本地存储(emptyDir、hostPath)
- 如果 Pod 使用了
emptyDir
或hostPath
,那么kubectl drain
默认不会强行驱逐。
解决办法:
kubectl drain <node> --delete-emptydir-data
5. API Server 网络或权限问题
- 如果
kubectl drain
一直挂起,可能是 API Server 连接异常,或者 RBAC 权限不足。
解决办法:
kubectl auth can-i drain node --all-namespaces --as=<your-user>
如果尝试了以上方法仍然卡住,可以提供 kubectl drain
的日志或者执行 kubectl describe node <node>
查看具体情况。