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 请求到策略生效的完整流程:

Kyverno Validate 策略执行流程 用户提交 Pod API Server Kyverno Webhook 匹配策略规则 验证通过/拒绝 返回结果 关键点 • 策略在 API Server 处理请求 之前拦截 • 拒绝后 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 策略,你已经掌握了策略即代码的核心工作流:

  1. 定义:使用 YAML 声明式描述安全规则。
  2. 部署:通过 kubectl 将策略应用到集群。
  3. 验证:观察策略对 Pod 创建请求的拦截效果。
  4. 迭代:将策略文件纳入版本控制,持续优化。