You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes部署新版本后,如何确保kubectl exec进入正确Pod?

解决Kubernetes部署更新后kubectl exec仍进入旧Pod的问题

问题背景

使用kubectl set image将Deployment更新至v2.0.0版本后,kubectl rollout status返回部署成功,但执行kubectl exec deploy/myapp -- show_version时,始终进入处于Terminating状态的旧v1 Pod,需等待20-30秒后才能进入新Pod执行验证。

解决方法

1. 等待旧Pod完全终止后再执行测试

kubectl rollout status仅确保新Pod就绪,不会等待旧Pod终止。可通过以下命令等待所有旧Pod被清理:

方式一:通过旧ReplicaSet等待

先获取目标Deployment的旧ReplicaSet名称:

OLD_RS=$(kubectl get rs -l app=myapp -o jsonpath='{range .items[?(@.metadata.generation!='$(kubectl get deploy myapp -o jsonpath='{.metadata.generation}')')]}{.metadata.name}{"\n"}')

等待该ReplicaSet下的所有Pod被删除:

kubectl wait --for=delete pod -l replicaset=$OLD_RS --timeout=120s

方式二:直接筛选Terminating状态的Pod

循环检查直到没有处于Terminating状态的目标Pod:

until [ $(kubectl get pods -l app=myapp --field-selector=status.phase=Terminating --no-headers | wc -l) -eq 0 ]; do
  sleep 2
done

2. 直接指定新Pod执行kubectl exec

跳过Deployment的随机Pod选择逻辑,直接定位到新ReplicaSet下的Pod:

先获取新Pod的名称:

NEW_POD=$(kubectl get pods -l app=myapp,pod-template-hash=$(kubectl get deploy myapp -o jsonpath='{.spec.template.metadata.labels.pod-template-hash}') -o jsonpath='{.items[0].metadata.name}')

然后执行验证命令:

kubectl exec $NEW_POD -- show_version

3. 调整Deployment的终止宽限期(可选)

如果旧Pod终止速度过慢,可以缩短terminationGracePeriodSeconds(默认30秒),让旧Pod更快被清理。修改Deployment配置:

spec:
  template:
    spec:
      terminationGracePeriodSeconds: 10  # 根据应用实际优雅终止需求调整

注意:需确保应用能在设定时间内完成资源释放与连接关闭,避免数据丢失或服务异常。

原因说明

kubectl rollout status的判断逻辑是:当新ReplicaSet的Pod数量达到Deployment的replicas配置,且所有新Pod处于就绪状态时,即返回部署成功。但此时旧Pod可能仍在执行终止流程(如处理剩余请求),仍属于Deployment的Pod集合,因此kubectl exec会随机选中这些未完全终止的旧Pod。

内容的提问来源于stack exchange,提问作者Marc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:50:22