跳到主要内容

日常运维与故障排查

排查 Rollout 时先判断问题发生在哪一层:Rollout Controller、Pod/ReplicaSet、流量路由、AnalysisRun、监控系统还是业务本身。不要在没有保存状态和事件前反复 abort、retry 或删除资源,否则会丢失最有价值的现场证据。

1. 发布窗口巡检​

# Rollout 当前步骤、暂停原因、稳定/金丝雀版本
kubectl argo rollouts get rollout <rollout-name> -n <namespace>

# Pod、ReplicaSet 和节点分布
kubectl get pods,replicasets -n <namespace> -l app=<app-name> -o wide

# 事件按时间排序
kubectl get events -n <namespace> --sort-by=.lastTimestamp | tail -80

# Controller 状态和最近日志
kubectl get pods -n argo-rollouts
kubectl logs -n argo-rollouts deploy/argo-rollouts --tail=300

发布开始前记录 Rollout 的 Git revision、镜像 digest、目标集群、流量入口、当前告警和回滚责任人。发布结束后记录实际开始时间、完成时间、停留时长和业务验证结果。

2. 常用控制命令​

# 暂停后保留现场,适合等待业务负责人确认
kubectl argo rollouts pause <rollout-name> -n <namespace>

# 继续当前步骤或跳过剩余人工暂停
kubectl argo rollouts promote <rollout-name> -n <namespace>

# 发现错误时终止当前发布并恢复稳定版本流量
kubectl argo rollouts abort <rollout-name> -n <namespace>

# 修复明显的临时问题后重试中止的 Rollout
kubectl argo rollouts retry <rollout-name> -n <namespace>

# 查看发布历史与 ReplicaSet
kubectl argo rollouts history rollout <rollout-name> -n <namespace>
kubectl argo rollouts list replicasets <rollout-name> -n <namespace>

promote 和 abort 都是有实际影响的操作,脚本化执行时应增加环境确认、审批号和操作者记录。生产环境不建议把 --full 或跳过等待作为默认参数。

3. 发布卡在暂停状态​

现象​

Rollout 长时间显示 Paused,没有继续增加权重。

排查​

kubectl argo rollouts get rollout <rollout-name> -n <namespace>
kubectl describe rollout <rollout-name> -n <namespace>
kubectl get events -n <namespace> --sort-by=.lastTimestamp

确认是预期的 pause: {}、AnalysisRun 尚未完成,还是 Controller 无法更新流量路由。若是人工暂停,先确认发布窗口和责任人,再执行 promote;不要看到 Paused 就直接重试。

4. AnalysisRun 失败或没有数据​

重点检查:

  1. AnalysisTemplate 的 Prometheus 地址是否可达;
  2. 查询标签是否能匹配金丝雀 Pod;
  3. 时间窗口内是否有足够真实请求;
  4. 查询返回空结果时,AnalysisRun 的处理策略是什么;
  5. Prometheus 是否限流、重启或发生远端存储延迟。
kubectl get analysisrun -n <namespace>
kubectl describe analysisrun <analysisrun-name> -n <namespace>
kubectl logs -n argo-rollouts deploy/argo-rollouts --tail=300 | rg -i 'analysis|prometheus|metric|error'

指标失败时不要直接修改阈值让发布变绿。先保存查询、原始结果和发布版本,再判断是应用问题、监控问题还是查询设计问题。

5. 流量权重没有变化​

如果 Rollout 的 setWeight 已更新,但真实流量仍全部进入稳定版本,通常是以下原因之一:

  • trafficRouting 引用的 VirtualService、Ingress 或 HTTPRoute 名称错误;
  • 入口流量没有经过配置的流量提供者;
  • Service selector、Pod hash 标签或 DestinationRule subset 不匹配;
  • Gateway/Ingress Controller 不支持当前 Rollouts 版本需要的权重更新方式;
  • 缓存、重试或长连接让短时间统计看起来没有变化。
# 查看 Rollout 状态与流量路由对象
kubectl argo rollouts get rollout <rollout-name> -n <namespace>
kubectl get virtualservice,httproute,ingress -n <namespace> -o yaml
kubectl get service -n <namespace> <stable-service> <canary-service> -o yaml

应结合入口访问日志、服务指标和压测结果验证真实流量,不要只看 Rollout YAML 中的权重字段。

6. Pod 不健康或新 ReplicaSet 无法扩容​

# 查看 Pod 状态、事件和探针失败原因
kubectl describe pod <pod-name> -n <namespace>
kubectl logs <pod-name> -n <namespace> --all-containers --tail=300

# 查看调度和资源容量
kubectl describe rs <replicaset-name> -n <namespace>
kubectl get nodes
kubectl get resourcequota,limitrange -n <namespace>

常见原因包括镜像拉取失败、Secret 不存在、ReadinessProbe 路径错误、端口不匹配、资源请求过高、PDB 或节点容量不足。先修复工作负载本身,再决定是否继续发布。

7. 证据采集与恢复顺序​

故障现场至少保存:

  • Rollout、ReplicaSet、Service、Ingress/VirtualService/HTTPRoute YAML;
  • Rollout、AnalysisRun 的 describe 输出;
  • Pod 事件、容器日志、Controller 日志;
  • 发布 Git commit、镜像 digest、指标查询和实际路由权重;
  • 执行过的 pause、promote、abort、retry 命令及操作者。

推荐恢复顺序:

  1. 停止继续放量,必要时执行 pause;
  2. 若新版本明显异常,执行 abort,确认流量回到稳定版本;
  3. 记录证据并隔离有问题的镜像或配置;
  4. 通过 Git 回退或修复后再执行新的发布;
  5. Analysis、路由和业务验证都通过后再恢复自动晋级。
不要删除 Rollout 作为第一反应

删除 Rollout 可能同时丢失发布状态、历史 ReplicaSet 和流量控制关系。除非已经制定资源接管方案,否则应先保留对象并通过 abort、Git 回退或修复配置恢复。