声明与实际动作之间
一句话总结
Argo object 只是写下意图,真正把意图变为现实的是 controller。没有 controller,甚至无法知道 YAML 是否正确。
为什么必须有 controller
前面的模块编写了多个 Workflow 与 Rollout,但由于实验环境中没有 controller,无法确认这些 YAML 实际会做什么。
Argo 的四个项目都只有在存在 controller 时才有意义。object 只是写下意图,controller 才把意图变成现实。
Workflows 컨테이너를 실제로 돌린다 없으면 단계가 진행되지도 실패하지도 않는다
Rollouts 파드를 실제로 띄우고 나눈다 없으면 카나리가 몇 퍼센트인지 볼 수 없다
Analysis Job 을 띄워 판정한다 없으면 자동 롤백이 통째로 빠진다
回滚的是流量,不是声明
这是最有价值的陷阱。即使 analysis 失败并发生自动回滚,spec.template 中的 image 仍然是新版本。
- 如果保持不变,下次修复其他内容并部署时,该 image 会一并发布
- 使用 GitOps 时,repository 仍指向新 image,因此会再次尝试同一部署,形成无限回滚循环
要修复它,必须回滚声明——提交一个恢复 repository image tag 的 commit。
limit 表示重试次数
Workflows 的 retryStrategy.limit 表示重试次数,不包含首次尝试。limit: 2 意味着实际尝试 3 次。
运行期间修改 template 也不会变化
controller 会把启动时的定义写入 status.storedTemplates,以保证可复现性。这就是“已经修改 template,为什么仍然没变”的答案;变更会从下一个 workflow 开始生效。
Canary weight 实际做什么
setWeight: 20 究竟表示“20% 的请求”还是“20% 的 Pod”,取决于配置。这种差异会让实测结果偏离预期。
| trafficRouting | weight 的含义 | 精度 |
|---|---|---|
| 无 | Pod 数量比例 | 粗略。replicas 为 5 时,20% 就是 1 个 Pod |
| Istio、Gateway API | 真实请求比例 | 精确 |
| NGINX Ingress | 真实请求比例(annotation) | 精确 |
没有 trafficRouting 时,controller 会按 Pod 数量近似。replicas: 3 时设置 setWeight: 10,无法创建 0 个 Pod,所以会创建 1 个,实际约为 33%。如果要从较小 weight 开始,就必须有足够大的 replicas,或者配置 trafficRouting。
Analysis 根据什么做出判断
AnalysisTemplate 向 metric provider 发起 query,并依据结果决定是否继续。
metrics:
- name: error-rate
interval: 1m
count: 5 # 5번 재고
failureLimit: 2 # 2번 실패하면 롤백
successCondition: result[0] < 0.05
provider:
prometheus:
address: http://prometheus.monitoring.svc:9090
query: |
sum(rate(http_requests_total{status=~"5..",version="{{args.version}}"}[2m]))
/ sum(rate(http_requests_total{version="{{args.version}}"}[2m]))
常见错误是 query 没有只筛选 canary。如果上述 query 没有 version label,就会把 stable 与 canary 合并计算。即使 canary 100% 失败,整体错误率也可能只升到 20%,未超过 threshold,导致糟糕的部署通过。
还有一个低流量陷阱。如果 canary 只收到 3 个请求,其中 1 个失败,错误率就是 33%。因此还必须设置最小 sample size 条件。
successCondition: result[0] < 0.05 || result[1] < 20 # 요청이 20건 미만이면 통과
选择部署策略的标准
| Canary | Blue-green | |
|---|---|---|
| 资源 | 略多(按阶段增加) | 两倍 |
| 回滚速度 | 把 weight 降到 0——很快 | 切换 Service selector——最快 |
| DB schema | 两个版本长期共存 | 两个版本短暂共存 |
| 适用场景 | 流量充足,可通过指标判断 | 需要人工验证,或流量较少 |
低流量内部服务使用 canary 时,会因样本不足而使 analysis 失去意义。此时更适合使用 blue-green,由人工检查 preview 后再 promote。
实务中真正重要的事
自动回滚后,必须提交一个回滚声明的 commit。 回滚只恢复流量,spec.template 仍保留新版本。使用 GitOps 时,repository 仍指向新 image,会无限重复尝试同一部署。
部署判定不应使用 Healthy,而应使用 status.stableRS。 promote 完成并显示 Healthy 后,旧 Pod 仍可能短暂停留在 Terminating,按 image 统计会看到两个版本。指向 stable 版本的 hash 是唯一稳定标准。
retryStrategy.limit 不是总尝试次数。 首次尝试不计入该值,因此 limit: 2 实际运行 3 次。计算 timeout budget 时,经常会漏算一次。
接下来的两项实验将让你在真实 controller 上亲自验证这些内容。