亲眼看策略真的挡住了什么
本实验运行在真正的 Kyverno 上
VM 中实际运行着 k3s + Kyverno。准入 Webhook 已完成注册, 因此应用策略后,资源会真正被拒绝,字段会真正被注入,其他对象也会真正被创建。
早期的策略编写实验运行在只加载了 CRD 的模拟集群中。在那里,无论策略写得
多么正确,都不会发生任何事情——但 kubectl apply 会成功,所以只看界面会以为一切正常。
首次启动需要 4~5 分钟。系统需要安装 Kyverno 并等待 Webhook 完成注册。
预计学习时间为 70 分钟。初始会话时长为 60 分钟,请检查剩余时间并在 到期前延长。本实验固定使用 k3s 1.35.8 和 Kyverno 1.19.1。为了练习阅读 现有策略,这里使用 ClusterPolicy,但该 API 已在 Kyverno 1.19 中弃用,官方文档 说明计划在 1.20 中移除。不要原样复制到新项目,请先确认支持版本和新的策略 API。
目标
亲自验证策略的三种动作(validate、mutate、generate)分别在何时、如何发生,
理解 Enforce 与 Audit 的区别,并观察遗漏例外时会发生什么。
为什么重要
策略引擎中最危险的状态不是“策略写错了”,而是**“策略没有应用到任何地方”**。 因为后者悄无声息。
而且三种动作的发生时机不同。
| 动作 | 何时 | 做什么 |
|---|---|---|
mutate |
准入阶段,先于 validate | 修改对象 |
validate |
准入阶段 | 拒绝或放行 |
generate |
准入之后,由独立控制器执行 | 创建其他对象 |
不了解这个顺序,策略就可能彼此抵消。如果 mutate 注入标签,而 validate 要求 该标签存在,那么请求会因为这个顺序而通过。相反,generate 发生在准入流程之外, 所以需要单独的权限。
步骤
Pod 创建在 kca 命名空间中。
- 确认 Kyverno 是如何被调用的,并将结果写入
/root/kca/install.txt。必须已经注册 Webhook 配置。 - 用
require-teamClusterPolicy(Enforce)要求team标签,并将无标签 Pod 被拒绝以及具备标签的ok-pod成功启动的证据写入/root/kca/validate.txt。 - 使用
add-defaults策略向 Pod 注入owner标签,将该标签确实出现在mutatedPod 中的证据写入/root/kca/mutate.txt,并写明 mutate 与 validate 的顺序。 - 使用
gen-baseline策略在新命名空间中创建baselineConfigMap;创建tenant-x进行确认,并将结果写入/root/kca/generate.txt。 - 应用
warn-only策略并将其设为Audit模式,并将违规的violatorPod 仍被创建以及违规记录出现在PolicyReport中的证据写入/root/kca/audit.txt。 - 为
require-team添加例外以排除系统命名空间,并将必须这样做的原因写入/root/kca/exclude.txt。 - 创建
/root/kca/test-pod.yaml,使用kyvernoCLI 在提交到集群之前进行测试,并将结果写入/root/kca/cli.txt。 - 在
/root/kca/report.md中写入enforce_blocks=yes、audit_blocks=no、policies=三行以及说明。
参考
- 策略的执行方式由
spec.validationFailureAction(旧版本)或规则内的validate.failureAction(新版本)决定。请选择与集群 Kyverno 版本匹配的方式——可用kubectl explain clusterpolicy.spec确认。 - 策略刚应用后,**可能尚未生效。**WebHook 配置更新需要几秒钟,测试前请稍等。
generate不是由准入流程执行,而是由后台控制器执行。因此,该控制器的服务账号必须拥有权限。没有权限时,策略看起来完全正常,却不会创建任何对象。- CLI 命令为
kyverno apply <정책> --resource <매니페스트>。它不需要集群,因此可用于 CI。 - 常见错误 1:扩大目标范围时,没有检查系统工作负载的标签和恢复路径。违反该策略的系统 Pod 可能无法重建。规则的
exclude与 Webhook 的namespaceSelector是不同阶段的过滤器。 - 常见错误 2:以
Audit模式应用策略,却认为该策略会阻止请求。Audit 策略会允许违规并生成报告,而其他 Enforce 策略仍然可能拒绝请求。
策略是如何被调用的
确认 Kyverno 是如何被调用的,并将结果写入 /root/kca/install.txt。必须已经注册 Webhook 配置。
必须注册 ValidatingWebhookConfiguration,API 服务器才会向 Kyverno 发起检查。
拒绝违规请求
用 require-team ClusterPolicy(Enforce)要求 team 标签,并将无标签 Pod 被拒绝以及具备标签的 ok-pod 成功启动的证据写入 /root/kca/validate.txt。
只有 Enforce 才会阻止请求。请同时测试无标签 Pod 和具备标签的 Pod。
修改对象——并且存在执行顺序
使用 add-defaults 策略向 Pod 注入 owner 标签,将该标签确实出现在 mutated Pod 中的证据写入 /root/kca/mutate.txt,并写明 mutate 与 validate 的顺序。
mutate 先于 validate 执行。因此,validate 可以要求由 mutate 注入的值存在。
创建其他对象
使用 gen-baseline 策略在新命名空间中创建 baseline ConfigMap;创建 tenant-x 进行确认,并将结果写入 /root/kca/generate.txt。
generate 由后台控制器执行。因此该控制器必须拥有权限,而且对象不会立即创建。
不阻止,只记录
应用 warn-only 策略并将其设为 Audit 模式,并将违规的 violator Pod 仍被创建以及违规记录出现在 PolicyReport 中的证据写入 /root/kca/audit.txt。
即使违规,Audit 策略也会允许创建对象。结果会累积在 PolicyReport 中。
扩大策略范围时检查例外与恢复路径
为 require-team 添加例外以排除系统命名空间,并将必须这样做的原因写入 /root/kca/exclude.txt。
前面的步骤只针对 kca。本次扩大目标范围,但要用 exclude 排除系统命名空间。不要因为设置了策略例外,就认为 Webhook 调用也已被排除。
提交前先测试
创建 /root/kca/test-pod.yaml,使用 kyverno CLI 在提交到集群之前进行测试,并将结果写入 /root/kca/cli.txt。
kyverno apply <정책> --resource <매니페스트> 可以在没有集群的情况下测试策略,因此可用于 CI。
总结所学内容
在 /root/kca/report.md 中写入 enforce_blocks=yes、audit_blocks=no、policies= 三行以及说明。
除了 enforce_blocks=、audit_blocks=、policies= 三行,还要写明三种动作的发生时机以及例外。