4. 第一个准入策略:编写 Validate 规则禁止特权容器,测试准入拦截效果
本章将带领你编写第一条 Kyverno Validate 策略,用于禁止在集群中创建特权容器。通过该实践,你将掌握策略的 YAML 结构、规则匹配逻辑以及准入拦截的验证方法。
4.1 策略目标与设计思路
特权容器拥有宿主机内核的全部权限,是容器逃逸攻击的主要入口。本策略的目标是:
- 拦截:拒绝任何设置了
securityContext.privileged: true的 Pod 创建请求。 - 告警:对于违反规则的请求,返回明确的拒绝原因。
- 覆盖:同时适用于 Pod 和 Deployment、DaemonSet 等工作负载资源。
关键概念:Validate 策略在准入阶段对资源进行校验,如果规则条件不满足,则拒绝该资源进入集群。这是实现合规性基线最直接的手段。
4.2 编写 Validate 策略 YAML
以下是一个完整的 Kyverno ClusterPolicy,用于禁止特权容器:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged-containers
spec:
validationFailureAction: Enforce
background: true
rules:
- name: validate-privileged
match:
any:
- resources:
kinds:
- Pod
validate:
message: "特权容器是不允许的。请移除 securityContext.privileged: true。"
pattern:
spec:
containers:
- securityContext:
privileged: "false"
initContainers:
- securityContext:
privileged: "false"
ephemeralContainers:
- securityContext:
privileged: "false"
4.3 策略字段解析
| 字段 | 值 | 说明 |
|---|---|---|
validationFailureAction |
Enforce |
设置为 Enforce 表示直接拒绝违规请求;若设为 Audit 则仅记录告警。 |
background |
true |
启用后台扫描,对集群中已有资源进行合规检查。 |
match.any.resources.kinds |
["Pod"] |
匹配的资源类型。Kyverno 会自动处理 Deployment 等控制器生成的 Pod 模板。 |
validate.pattern |
嵌套字段 | 定义期望的资源状态模式。此处要求 privileged 字段必须为字符串 "false"。 |
validate.message |
自定义字符串 | 当规则被违反时,返回给用户的拒绝原因。 |
提示:Kyverno 使用 pattern 进行声明式匹配,而非编程式条件。当资源字段与 pattern 不一致时,即触发拦截。
4.4 策略工作流程
下图展示了 Kyverno 准入控制器在处理 Pod 创建请求时的完整流程:
4.5 部署策略到集群
将上述 YAML 保存为 disallow-privileged.yaml,然后执行以下命令:
kubectl apply -f disallow-privileged.yaml
验证策略是否成功创建:
kubectl get clusterpolicy disallow-privileged-containers -o wide
输出应显示 READY 状态为 true,表示策略已生效。
4.6 测试准入拦截效果
创建两个测试 Pod,一个合规,一个违规:
4.6.1 合规 Pod(应被允许)
kubectl run nginx-non-privileged --image=nginx --restart=Never
预期结果:Pod 创建成功。
4.6.2 违规 Pod(应被拒绝)
kubectl run nginx-privileged --image=nginx --restart=Never --privileged
预期结果:返回类似以下错误信息:
Error from server: admission webhook "validate.kyverno.svc" denied the request:
resource Pod/default/nginx-privileged was blocked due to the following policies
disallow-privileged-containers:
validate-privileged: '特权容器是不允许的。请移除 securityContext.privileged: true。'
注意:如果使用
--privileged 参数时命令未报错,请检查你的 kubectl 版本是否支持该参数。也可以直接使用 YAML 文件创建 Pod 进行测试。
4.7 使用 YAML 文件测试
创建违规 Pod 的 YAML 文件 privileged-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
spec:
containers:
- name: nginx
image: nginx
securityContext:
privileged: true
执行创建:
kubectl apply -f privileged-pod.yaml
此时应收到明确的拒绝消息,包含策略名称和自定义的拒绝原因。
4.8 策略效果对比
| 测试场景 | Pod 配置 | 预期结果 | 实际行为 |
|---|---|---|---|
| 合规容器 | 未设置 privileged 或显式设为 false | 创建成功 | Pod 正常运行 |
| 违规容器 | securityContext.privileged: true | 创建被拒绝 | 返回 Kyverno 拒绝消息 |
| 工作负载控制器 | Deployment 中设置 privileged: true | 创建被拒绝 | Deployment 创建失败,Pod 模板未通过校验 |
4.9 常见问题与排查
- 策略未生效:检查 Kyverno Pod 是否正常运行,以及 Webhook 配置是否正确。
- 误拦截合规 Pod:确认 pattern 中
privileged字段的值是否为字符串"false",而非布尔值false。 - 仅拦截 Pod 资源:如需拦截 Deployment 等控制器,可在
match中添加更多 kinds,或使用podControllers自动匹配。
最佳实践:在生产环境中,建议先将
validationFailureAction 设为 Audit,观察一段时间确认无误报后,再切换为 Enforce。
4.10 本章小结
通过本节的实践,你已经完成了以下关键任务:
- 编写了第一条 Kyverno Validate 策略,禁止特权容器。
- 理解了
pattern匹配机制和validationFailureAction的作用。 - 成功测试了准入拦截效果,验证了策略的合规性保障能力。