4. 第一个Kyverno策略:编写一个简单的验证策略(Validate)、阻止特权容器、测试策略生效
在掌握了 Kyverno 的安装与基础概念后,本章将带领你编写第一个实战策略。我们将从一个最常见的 Kubernetes 安全场景入手:阻止特权容器。通过这个简单的 Validate 策略,你将直观地理解策略即代码的编写、部署与生效流程。
4.1 策略目标与设计思路
特权容器拥有宿主机内核的全部能力,是容器逃逸攻击的主要入口。在大多数生产集群中,应严格禁止运行特权容器。我们的策略目标如下:
- 拦截对象:所有 Pod 创建请求(包括 Deployment、DaemonSet、Job 等控制器创建的 Pod)。
- 验证条件:检查 Pod 中每个容器的
securityContext.privileged字段是否为true。 - 执行动作:如果检测到特权容器,则拒绝该请求,并返回明确的错误信息。
设计原则:Kyverno 策略遵循“声明式拒绝”模式。我们只描述“什么是被禁止的”,而不是编写复杂的准入控制钩子。这大大降低了策略的编写和维护成本。
4.2 编写第一个 Validate 策略 YAML
创建一个名为 disallow-privileged-containers.yaml 的文件,内容如下:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged-containers
spec:
validationFailureAction: Enforce
background: true
rules:
- name: check-privileged
match:
any:
- resources:
kinds:
- Pod
validate:
message: "特权容器是不允许的。请将 securityContext.privileged 设置为 false 或移除该字段。"
pattern:
spec:
containers:
- securityContext:
privileged: "false"
4.3 策略关键字段解析
| 字段路径 | 值 | 说明 |
|---|---|---|
spec.validationFailureAction |
Enforce |
策略模式。Enforce 表示强制执行,违反策略的请求将被直接拒绝;Audit 模式仅记录告警,不阻止请求。 |
spec.background |
true |
是否对集群中已有的资源进行扫描。设为 true 后,Kyverno 会报告现有特权容器的违规情况。 |
spec.rules[0].match |
any: kinds: [Pod] |
匹配规则。这里匹配所有 Pod 资源。注意:Deployment 等控制器最终也会创建 Pod,因此匹配 Pod 即可覆盖所有场景。 |
spec.rules[0].validate.pattern |
privileged: "false" |
期望的模式。Kyverno 会检查请求中的 Pod 是否匹配此模式。如果容器的 privileged 字段不是 "false"(即 true 或缺失),则匹配失败,触发拒绝。 |
spec.rules[0].validate.message |
自定义错误信息 | 当策略被违反时,返回给 API 调用者的提示信息。信息应清晰、可操作。 |
4.4 策略执行流程(SVG)
下图展示了从用户提交 Pod 请求到策略生效的完整流程:
4.5 部署并测试策略
步骤1:应用策略
使用 kubectl apply 命令将策略部署到集群:
kubectl apply -f disallow-privileged-containers.yaml
步骤2:验证策略状态
检查策略是否成功创建并处于就绪状态:
kubectl get clusterpolicy disallow-privileged-containers -o wide
输出应显示 READY 列为 true。
步骤3:测试拒绝场景
尝试创建一个特权容器 Pod:
kubectl run privileged-pod --image=nginx --privileged
预期输出:
Error from server: admission webhook "validate.kyverno.svc" denied the request:
resource Pod/default/privileged-pod was blocked due to the following policies:
disallow-privileged-containers:
check-privileged: '特权容器是不允许的。请将 securityContext.privileged 设置为 false 或移除该字段。'
步骤4:测试允许场景
创建一个普通 Pod 验证策略不会误拦截:
kubectl run normal-pod --image=nginx
预期输出:Pod 创建成功。
常见问题:如果策略未生效,请检查 Kyverno Webhook 服务是否正常运行,以及
validationFailureAction 是否设置为 Enforce。在 Audit 模式下,策略只会记录告警,不会阻止请求。
4.6 策略即代码的版本管理
将策略 YAML 文件纳入 Git 仓库管理,是实现策略即代码的第一步。建议遵循以下规范:
- 目录结构:按策略类别组织文件,例如
policies/security/disallow-privileged.yaml。 - 命名规范:策略名称应体现其功能,如
disallow-privileged-containers。 - 注释说明:在 YAML 文件头部添加注释,说明策略目的、适用范围和例外情况。
- 版本标签:使用 Git tag 标记策略版本,便于回滚和审计。
4.7 本章小结
通过编写并测试第一个 Kyverno Validate 策略,你已经掌握了策略即代码的核心工作流:
- 定义:使用 YAML 声明式描述安全规则。
- 部署:通过 kubectl 将策略应用到集群。
- 验证:观察策略对 Pod 创建请求的拦截效果。
- 迭代:将策略文件纳入版本控制,持续优化。