Kubernetes:如何限制集群同时执行的Deployment数量?
好问题!批量更新Deployment时,并发的滚动操作很容易引发节点CPU、内存资源过载,甚至影响服务的100%可用性——毕竟每个Deployment的滚动更新都会创建新Pod、销毁旧Pod,多实例同时操作的话,节点压力会陡增。下面分享几种实用的解决方案,从快速落地到长期架构都覆盖到:
一、快速落地:用脚本分批控制更新
这是最直接的临时方案,适合小规模集群或者一次性批量更新场景。你可以写个简单的Shell脚本,把Deployment分成若干批次,每批最多执行N个更新,等当前批次全部完成后再启动下一批。
举个bash脚本示例(假设要更新prod命名空间下的所有Deployment,每批最多10个):
#!/bin/bash NAMESPACE="prod" BATCH_SIZE=10 # 获取所有需要更新的Deployment名称 DEPLOYMENTS=($(kubectl get deployments -n "$NAMESPACE" -o custom-columns=NAME:.metadata.name --no-headers)) # 分批处理更新 for ((i=0; i<${#DEPLOYMENTS[@]}; i+=BATCH_SIZE)); do # 截取当前批次的Deployment列表 CURRENT_BATCH=("${DEPLOYMENTS[@]:i:BATCH_SIZE}") echo "=== 开始处理批次 $((i/BATCH_SIZE + 1)):${CURRENT_BATCH[*]} ===" # 逐个启动更新并等待完成 for DEPLOY in "${CURRENT_BATCH[@]}"; do echo "重启Deployment: $DEPLOY" kubectl rollout restart deployment/"$DEPLOY" -n "$NAMESPACE" # 等待滚动更新完成(超时10分钟,可根据实际调整) if kubectl rollout status deployment/"$DEPLOY" -n "$NAMESPACE" --timeout=10m; then echo "$DEPLOY 更新完成" else echo "$DEPLOY 更新超时或失败,终止脚本" exit 1 fi done done echo "所有Deployment更新完成!"
这个脚本的核心是通过kubectl rollout status确保每个Deployment的滚动更新真的完成后,再处理下一个,严格控制并发数不超过设定的BATCH_SIZE。
二、CI/CD流水线层面控制
如果你的Deployment更新是通过CI/CD工具(比如Jenkins、GitLab CI、GitHub Actions)触发的,可以直接在流水线里设置并发限制:
- Jenkins:用
parallel步骤结合throttle插件,限制同时运行的更新任务数量;或者把更新逻辑做成流水线的阶段,每次只启动N个并行任务。 - GitLab CI:可以用
parallel: 10来设置单流水线内的并行任务数,或者用resource_group来全局限制同一时间运行的更新流水线数量。 - Argo CD(GitOps场景):如果用Argo CD管理应用同步,可以在
AppProject里设置syncPolicy的并行度,或者用同步窗口(Sync Windows)来控制特定时间段内的同步并发数,还能给应用分组,分批同步。
三、长期架构:自定义Operator或控制器
如果你的集群需要长期、自动化的Deployment并发更新限制,推荐写一个简单的Kubernetes Operator:
- 监控集群中所有Deployment的
status.conditions,识别处于“滚动更新中”的实例; - 维护一个全局计数器,当并发更新的Deployment数量超过阈值(比如10)时,暂停其他待更新的Deployment(通过设置
spec.paused: true); - 当某个Deployment更新完成后,计数器减1,自动恢复下一个待更新的Deployment。
可以用Kubebuilder或者Operator SDK快速搭建这类控制器,代码量不大,但能实现完全自动化的全局控制。
补充:结合单个Deployment的更新参数优化
除了全局并发限制,还可以给每个Deployment设置maxSurge和maxUnavailable参数,控制单个Deployment更新时的Pod波动范围:
spec: strategy: rollingUpdate: maxSurge: 25% # 更新时最多额外创建25%的Pod maxUnavailable: 0 # 更新期间确保0个Pod不可用(符合你100%正常运行的需求) type: RollingUpdate
把这个参数和全局并发限制结合,能进一步降低节点的瞬时压力。
内容的提问来源于stack exchange,提问作者Lindsay Landry




