Kubernetes单副本Deployment节点Drain:先调度新Pod再驱逐旧Pod方案求助
单副本Deployment节点Drain时的优雅迁移方案
针对你遇到的单副本Deployment+PDB(minAvailable=1)场景下,节点Drain无法自动迁移Pod的问题,以下是无需额外亲和性配置、保持最终副本数为1的实现方案:
核心思路
利用Deployment的滚动更新策略,强制触发"先启新Pod、再删旧Pod"的流程,绕过PDB对直接驱逐的限制,同时确保迁移过程中始终满足PDB的可用性要求。
1. 调整Deployment滚动更新策略
修改Deployment的滚动更新参数,确保更新时先启动新Pod,且不会减少可用Pod数量:
apiVersion: apps/v1 kind: Deployment metadata: name: 你的Deployment名称 spec: replicas: 1 strategy: rollingUpdate: maxSurge: 1 # 允许临时超出副本数1个 maxUnavailable: 0 # 更新过程中不可用Pod数为0 type: RollingUpdate # 其余原有配置(镜像、资源限制等)保持不变
这个配置会让Deployment在更新时,先调度新Pod到其他节点,待新Pod就绪后再销毁旧Pod,完全符合你"先调度、后驱逐"的需求。
2. 触发滚动更新以迁移Pod
在执行节点Drain前,通过修改Pod模板的任意元数据(比如添加临时注解)触发Deployment滚动更新:
kubectl patch deployment 你的Deployment名称 -p '{"spec":{"template":{"metadata":{"annotations":{"drain-trigger":"'$(date +%s)'"}}}}}'
执行该命令后,Kubernetes会立即启动一个新Pod,由于原节点即将被Drain(后续会添加污点),新Pod会自动调度到其他可用节点。
3. 执行节点Drain操作
等待新Pod进入Running且Ready状态后,执行Drain命令清理目标节点:
kubectl drain 目标节点名称 --ignore-daemonsets --delete-emptydir-data
此时旧Pod已经被Deployment的滚动更新流程自动销毁,Drain只会处理节点上剩余的其他资源(比如DaemonSet Pod,已通过--ignore-daemonsets忽略)。
关键说明
- 整个过程中,PDB的
minAvailable=1要求始终被满足:滚动更新时新旧Pod短暂共存,但可用Pod数始终≥1,不会触发PDB的驱逐阻止规则。 - 最终Deployment的副本数仍保持为1,符合你"不能增加副本数"的要求,仅在迁移过程中临时出现2个Pod。
- 无需配置任何节点亲和性规则,完全依赖Kubernetes的默认调度逻辑避开带污点的待Drain节点。
内容的提问来源于stack exchange,提问作者Karan Kumar
相关产品推荐
相关产品推荐

