LabHub
学习 学习路径 课程

CNPE — 云原生平台工程师

门禁放在哪里

在 LabHub 中继续学习

一句话总结

部署流水线的 gate 应作用于渲染结果,而不是 source。因为进入 cluster 的不是文件,而是渲染后的 manifest;gate 没有看到的内容,也就无法阻止。

概念图: 渲染结果,而不是 source · 没有看到自己试图阻止的对象 · 把检查结果转换为退出码 · 实际放入应当被阻止的内容,确认红灯会亮起

为什么是渲染结果

在包含三个 kustomize overlay 的 repository 中,经常能看到这样的 gate。

grep -r "image:.*:latest" .   # latest 태그 금지

这个检查查看 base 后通过。但实际部署的是 overlay 覆盖 image 后的结果,而其中可能包含 latest。反过来也成立:即使 base 中有 latest,如果 overlay 用 digest 覆盖,真正部署的内容就是安全的,gate 却会亮红灯。

两种情况的原因相同:gate 没有看到自己试图阻止的对象。所以顺序只有一种。

kustomize build overlays/prod   →   렌더 결과
        ↓
스키마 검증 · 정책 검사          →   이 결과를 검사한다
        ↓
0 이 아닌 종료 코드면 배포 중단

工作原理

Gate 必须用退出码表达结果

有很多流水线运行 policy tool 后,只把结果打印到画面上便结束。日志中有红字,流水线却是绿灯。gate 的核心不只是检查,而是把检查结果转换为退出码

if ! kyverno apply policy/require-pinned.yaml --resource "$RENDER"; then
  echo "정책 위반으로 배포를 막습니다"; exit 3
fi

而且创建 gate 后,必须实际放入应当被阻止的内容,确认红灯会亮起。只验证通过情况的 gate,可能连续几个月什么都没有保护,却始终显示绿灯。

使用 digest,而不是 tag

checkout:1.4.0 是名称,checkout@sha256:... 是内容。tag 可以重新推送,因此昨天验证的内容可能不同于今天部署的内容。固定为 digest 后,才能说“通过 gate 的那个内容”与“进入 cluster 的那个内容”相同。这是审计追踪成立的最低条件。

Progressive delivery 的核心是暂停

如果把 canary 写成 setWeight: 10setWeight: 100,那就不是 canary,而只是稍慢一些的全面部署。weight 之间必须有 pause,才能给人或 analysis 留下判断空间。而且必须能够单独观察 canary,判断才有依据,因此要分开设置 canaryServicestableService

blue/green 是先通过 preview 路径检查新版本,再切换流量的方案。autoPromotionEnabled: false 会阻止自动 promotion。但 preview 版本也可能通过 startup task 或 background task 写入数据。对于 ledger 等需要 single writer 的服务,必须另行验证写入控制、schema compatibility 和 recovery procedure。blue/green 并不意味着能够阻止同时写入。

实际工作中的表现

某组织的 canary analysis 一直通过,最终却发生故障。原因是 analysis template 名称写错了。Rollout 引用了不存在的 template,而这个事实直到 promotion 前才暴露。因此,“引用的 template 是否确实存在”是部署前必须检查的事项。

另一个常见问题是 Argo CD Application 的 destination namespace 与 manifest 渲染出的 namespace 不一致。同步会成功并亮起绿灯,实际却没有在任何地方生效。

绿灯说谎的位置

前面的两个案例(不存在的 analysis template、错位的 destination namespace)有一个共同点: 同步成功,却什么都没有发生。 在 GitOps 中,绿灯表示“Git 与 cluster 一致”, 而不是“服务正常”。混淆两者,就会只看画面便放下心来。

绿灯会说谎的位置基本固定在以下几处。

什么都没创建,却声称一致。 如果 manifest 渲染结果为空,就会变成 “没有管理对象,因此也没有差异”,同步仍然成功。这可能是 overlay path 写错, 或者 selector 没有选中任何内容。同时查看受管对象数量是捕获此问题成本最低的方法。

已经应用,但被 controller 拒绝。 object 已创建,所以 Git 与 cluster 一致, 但读取它的 controller 拒绝相应值,只在 status 中记录错误。 Rollout、Certificate、ExternalSecret 等由其他 controller 处理的对象都属于这种情况。 因此需要把健康判断建立在 status field 而不是 object 是否存在之上。

ignore rule 连真正的差异也一并覆盖。 为了不把 autoscaling 改变 replica 数视为差异, 人们会加入 ignore rule;如果范围过宽,手动修改也会被一起覆盖。从那一刻起, 该 field 就处在 GitOps 之外。

所以要在绿灯旁边再放置另一项 signal:最后同步的是哪个 commit,以及当前运行 image 的 tag 是什么。 如果两者与预期不同,无论是否绿灯,都说明某处存在问题;这项对照只需几秒钟。

下个练习将做什么

创建 base 与 production overlay,对渲染结果设置 policy gate,确认该 gate 确实阻止违规内容,再决定分别把 canary 与 blue/green 应用于哪些服务。