把黄金路径的遵循度做成诊断给出去
目标
把黄金路径规则定义为数据,制作能够实际判定这些规则的检查器,统计采用率,并一直集成到提交前门禁,一次完成整个流程。
为什么重要
如果只在准入阶段阻止违规,开发者要到 30 分钟后才知道一个本可用 1 分钟修好的问题;如果在最前端阻止一切,人们又会绕过平台。因此,实际工作中的护栏分为两类:违反后会影响他人的规则必须阻止,只影响服务自身的规则则仅作提示。为此,每条规则都需要有标识符、严重级别和修复方法。检查器还必须从相反方向进行测试。什么都检测不出来的检查器会让采用率看起来是 100%,比没有检查器更糟。
步骤
- 在
/root/cnpa-devex/rules.json中以数组形式写入五条规则。每个元素包含id、title、severity、fix。PR001(固定镜像标签)和PR002(声明资源请求)的severity为block;PR003(标准标签app.kubernetes.io/name和app.kubernetes.io/part-of)、PR004(readinessProbe)、PR005(replicas 至少为 2)为warn。fix至少写 8 个字符。 - 创建
/root/cnpa-devex/check-paved-road.sh并赋予执行权限。读取参数指定的清单,每行输出一个违反的规则 id。本步骤只需判定PR001和PR002。对于PR001,第一个容器的镜像没有标签或标签为latest时判定违规;对于PR002,第一个容器缺少resources.requests.cpu或resources.requests.memory时判定违规。 - 补齐其余三条规则。对于
PR003,检查metadata.labels中是否缺少app.kubernetes.io/name或app.kubernetes.io/part-of;对于PR004,检查第一个容器是否缺少readinessProbe;对于PR005,检查spec.replicas是否不存在或小于 2。没有任何违规时退出码必须为 0,只要存在一项违规就必须以 1 结束。 - 在
/root/cnpa-devex/services/checkout.yaml中编写遵守全部五条规则的 Deploymentcheckout。文件中只能包含一个 Deployment。 - 在
/root/cnpa-devex/services/reports.yaml中编写 Deploymentreports,它只能违反PR001和PR005。在/root/cnpa-devex/services/billing.yaml中编写 Deploymentbilling,且只能违反PR004。 - 为检查器增加
--json模式。check-paved-road.sh --json <파일>输出一个形如{"file": "<받은 경로>", "violations": ["PR001", ...], "pass": true 또는 false}的 JSON 对象。pass必须是不带引号的布尔值;没有违规时,violations是空数组。 - 对
/root/cnpa-devex/services/中的所有清单运行检查器,生成/root/cnpa-devex/adoption.json。键包括total(检查的文件数)、passing(无违规的文件数)、rate_pct(采用率,保留一位小数)、by_rule(五条规则各自的违规文件数,违规数为 0 的规则也必须保留键)。 - 在
/root/cnpa-devex/repo创建 git 仓库,并建立services/目录。创建.git/hooks/pre-commit并赋予执行权限,使其用检查器检查已暂存的services/*.yaml。如果有文件违反block规则,输出规则 id,并以非零状态码结束以阻止提交;如果只违反warn规则,则仅输出提示并允许提交。尝试一次会被阻止的提交,并把输出保存到/root/cnpa-devex/blocked-commit.txt。
参考
- 用 yq 读取不存在的值时会得到字符串
null,可直接把它作为判定条件。 - 对于包含点号的标签键,应像
.metadata.labels."app.kubernetes.io/name"一样使用引号括起来。 - 评分器会把自己创建的样例清单交给检查器,并核对判定结果。规则 id 必须严格按指定名称输出。
- 第 8 步的钩子会在学生仓库的副本中测试,不必让仓库保持干净状态。
把规则定义为数据
在 /root/cnpa-devex/rules.json 中以数组形式写入五条规则。每个元素包含 id、title、severity、fix。PR001(固定镜像标签)和 PR002(声明资源请求)的 severity 为 block;PR003(标准标签 app.kubernetes.io/name 和 app.kubernetes.io/part-of)、PR004(readinessProbe)、PR005(replicas 至少为 2)为 warn。fix 至少写 8 个字符。
每条规则都需要标识符、标题、严重级别和修复方法。判断严重级别的标准是“违反后是否会影响他人”。
检查器框架与两条规则
创建 /root/cnpa-devex/check-paved-road.sh 并赋予执行权限。读取参数指定的清单,每行输出一个违反的规则 id。本步骤只需判定 PR001 和 PR002。对于 PR001,第一个容器的镜像没有标签或标签为 latest 时判定违规;对于 PR002,第一个容器缺少 resources.requests.cpu 或 resources.requests.memory 时判定违规。
使用 yq 读取清单值。不存在的值会显示为字符串 null,可将其用于判定条件。不要忘记执行权限。
判定全部五条规则
补齐其余三条规则。对于 PR003,检查 metadata.labels 中是否缺少 app.kubernetes.io/name 或 app.kubernetes.io/part-of;对于 PR004,检查第一个容器是否缺少 readinessProbe;对于 PR005,检查 spec.replicas 是否不存在或小于 2。没有任何违规时退出码必须为 0,只要存在一项违规就必须以 1 结束。
标签键包含点号,因此在 yq 中必须用引号括起来。副本数既要捕获值不存在的情况,也要捕获值为 1 的情况。
符合规则的样例
在 /root/cnpa-devex/services/checkout.yaml 中编写遵守全部五条规则的 Deployment checkout。文件中只能包含一个 Deployment。
创建一个遵守全部五条规则的 Deployment。检查器应不输出任何内容,并以 0 结束。
故意违规的样例
在 /root/cnpa-devex/services/reports.yaml 中编写 Deployment reports,它只能违反 PR001 和 PR005。在 /root/cnpa-devex/services/billing.yaml 中编写 Deployment billing,且只能违反 PR004。
只能违反明确指定的规则。如果还违反其他规则,即使检查器判断正确,也无法通过评分。
机器可读的输出
为检查器增加 --json 模式。check-paved-road.sh --json <파일> 输出一个形如 {"file": "<받은 경로>", "violations": ["PR001", ...], "pass": true 또는 false} 的 JSON 对象。pass 必须是不带引号的布尔值;没有违规时,violations 是空数组。
把同一判定也输出为一个 JSON 对象。pass 必须是不带引号的布尔值;没有违规时,violations 必须是空数组。
计算采用率
对 /root/cnpa-devex/services/ 中的所有清单运行检查器,生成 /root/cnpa-devex/adoption.json。键包括 total(检查的文件数)、passing(无违规的文件数)、rate_pct(采用率,保留一位小数)、by_rule(五条规则各自的违规文件数,违规数为 0 的规则也必须保留键)。
遍历服务目录,对每个文件运行检查器并统计结果。不要手工填写数字,应写入计算所得的值。
接入提交前门禁
在 /root/cnpa-devex/repo 创建 git 仓库,并建立 services/ 目录。创建 .git/hooks/pre-commit 并赋予执行权限,使其用检查器检查已暂存的 services/*.yaml。如果有文件违反 block 规则,输出规则 id,并以非零状态码结束以阻止提交;如果只违反 warn 规则,则仅输出提示并允许提交。尝试一次会被阻止的提交,并把输出保存到 /root/cnpa-devex/blocked-commit.txt。
钩子必须具有执行权限。git 会给出已暂存文件清单;只有出现 block 规则时,钩子才应以非零值结束。