bigywater.tech
Kubernetes · 107

kubectl wait 与 rollout status:怎么判断就绪

发布脚本里该用 kubectl wait 还是 rollout status?Available 条件为什么在滚动更新中间就是 True?资源还不存在时 wait 会怎样?Job 失败了 wait 会不会一直卡住?这篇逐个量出来。

0.2 秒 vs 20 秒
滚动更新期间 wait --for=condition=Available 与 rollout status 各自返回的时间
21 秒
progressDeadlineSeconds=20 时,卡住的滚动更新 rollout status 以退出码 1 结束
不会 Complete
失败的 Job 永远不会有 Complete 条件,wait --for=condition=complete 只能干等到超时

kubectl wait

实测 · 本机执行输出
  --for=condition=Ready(探针一直失败):退出码 1;['error: timed out waiting for the condition on pods/slow'];等了 5.1 秒
  --for=jsonpath={.status.phase}=Running:退出码 0;['pod/slow condition met'];用时 0.2 秒(phase 已经是 Running,而 Ready 条件还没好)
  让探针通过后再等 Ready:退出码 0;['pod/slow condition met'];用时 0.3 秒
  等一个不存在的 pod/nothing:退出码 1;['Error from server (NotFound): pods "nothing" not found'];用时 0.0 秒(没有等,立刻报错)
  --for=create 等一个 3 秒后才创建的 ConfigMap:退出码 0;['configmap/later condition met'];用时 3.5 秒
  --for=delete 等 pod/slow 被删掉:退出码 0;['pod/slow condition met'];用时 3.1 秒

Pod slow 的就绪探针一直失败:kubectl wait --for=condition=Ready --timeout=5s 等了 5.1 秒,退出码 1,error: timed out waiting for the condition on pods/slow;--for=jsonpath='{.status.phase}'=Running 0.2 秒就满足(phase 已是 Running,Ready 条件还没好)。探针通过后再等 Ready 只要 0.3 秒。等一个不存在的 pod/nothing 立刻报 NotFound(不会等待);--for=create 等一个 3 秒后才创建的 ConfigMap 用了 3.5 秒;--for=delete 等 pod/slow 被删掉用了 3.1 秒。

Available 与 rollout status

实测 · 本机执行输出
  首次创建 3 副本:rollout status 退出码 0,用时 10 秒;输出:
    Waiting for deployment "web" rollout to finish: 0 of 3 updated replicas are available...
    Waiting for deployment "web" rollout to finish: 1 of 3 updated replicas are available...
    Waiting for deployment "web" rollout to finish: 2 of 3 updated replicas are available...
    deployment "web" successfully rolled out
  改模板触发滚动更新(maxSurge 1 / maxUnavailable 0,新 Pod 要约 5 秒才就绪):
    kubectl wait --for=condition=Available 在 0.2 秒就返回了(退出码 0),因为更新过程中 Available 一直是 True(旧 Pod 还在服务)
    kubectl rollout status 等到 20.0 秒才结束(退出码 0),输出:
      Waiting for deployment "web" rollout to finish: 1 out of 3 new replicas have been updated...
      Waiting for deployment "web" rollout to finish: 1 out of 3 new replicas have been updated...
      Waiting for deployment "web" rollout to finish: 1 out of 3 new replicas have been updated...
      Waiting for deployment "web" rollout to finish: 2 out of 3 new replicas have been updated...
      Waiting for deployment "web" rollout to finish: 2 out of 3 new replicas have been updated...
      Waiting for deployment "web" rollout to finish: 2 out of 3 new replicas have been updated...
      Waiting for deployment "web" rollout to finish: 1 old replicas are pending termination...
      Waiting for deployment "web" rollout to finish: 1 old replicas are pending termination...
      deployment "web" successfully rolled out
  Progressing 条件:[('Available', 'True', 'MinimumReplicasAvailable'), ('Progressing', 'True', 'NewReplicaSetAvailable')]

Deployment web(3 副本,maxSurge 1 / maxUnavailable 0,新 Pod 要约 5 秒才就绪)改模板触发滚动更新:kubectl wait --for=condition=Available 0.2 秒就返回了,因为更新过程中旧 Pod 一直在服务,Available 始终是 True;kubectl rollout status 等到 20.0 秒才结束,输出依次是 1 out of 3 new replicas have been updated…、2 out of 3 …、1 old replicas are pending termination…,最后 deployment "web" successfully rolled out。判断“发布完成”要用 rollout status,不能用 Available。

卡住的发布

实测 · 本机执行输出
  把镜像改成拉不到的(progressDeadlineSeconds: 20):rollout status 用时 21 秒,退出码 1
    Waiting for deployment "web" rollout to finish: 1 out of 3 new replicas have been updated...
    error: deployment "web" exceeded its progress deadline
  Deployment 条件:[('Available', 'True', 'MinimumReplicasAvailable'), ('Progressing', 'False', 'ProgressDeadlineExceeded')];旧副本仍在服务(availableReplicas=3、readyReplicas=3)
  rollout undo 后再 status:['deployment "web" successfully rolled out'];退出码 0

把镜像改成拉不到的(progressDeadlineSeconds: 20):rollout status 21 秒后退出,退出码 1,error: deployment "web" exceeded its progress deadline;Deployment 条件 Progressing=False、reason=ProgressDeadlineExceeded,而 Available 仍是 True,旧副本照常服务(availableReplicas=3)。超时不会自动回滚,rollout undo 之后再 rollout status 又是 successfully rolled out。

Job

实测 · 本机执行输出
  --for=condition=complete job/ok:退出码 0;['job.batch/ok condition met'];用时 5.3 秒
  --for=condition=complete job/bad(这个 Job 会失败):退出码 1;['error: timed out waiting for the condition on jobs/bad'];等满 10.0 秒才超时——失败的 Job 永远不会 Complete
  --for=condition=failed job/bad:退出码 0;['job.batch/bad condition met'];用时 0.1 秒

--for=condition=complete job/ok 5.3 秒满足;--for=condition=complete job/bad(这个 Job 会失败)等满 10.0 秒超时——失败的 Job 永远不会 Complete;--for=condition=failed job/bad 0.1 秒满足。要同时处理成功和失败,需要同时等两个条件或轮询,并总是设 --timeout 兜底。

分步演示

就绪判断
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / kind(Docker 里的单节点或多节点真实集群,节点是 Docker Desktop 虚拟机里的容器)/ kubectl;用空的 kubeconfig 之外的独立 kubeconfig,不碰用户自己的集群;计时用 date +%s%N / kubectl 事件时间戳,数字每次运行会有小幅抖动。三节点 kind 集群 kx-main(Kubernetes v1.37.0,kubectl 1.36);用时是 kubectl 进程的墙钟时间;Deployment 的新 Pod 就绪探针让每个新 Pod 约 5 秒后才就绪,所以更新总时长约 20 秒;--for=create 的 3 秒由另一个线程延迟创建;每种情形各一次
    • 没有验证:kubectl wait 对自定义资源 condition 的用法;--for=condition=Ready=false 的取反写法;kubectl rollout status 对 StatefulSet / DaemonSet 的判据;watch 超过 timeout 时的重连;kubectl wait 在资源被删除又重建时的行为;progressDeadlineSeconds 默认 600 秒的实际表现
    京ICP备2026067502号-1京公网安备11010502063487号