3. 第一个Kyverno策略:编写最简单的validate策略(禁止privileged容器)、策略YAML结构解析

在开始编写第一个Kyverno策略之前,我们需要理解策略引擎的核心工作模式。Kyverno作为Kubernetes原生的策略引擎,通过监听API Server的资源变更事件,在资源创建、更新或删除时触发策略校验。本节将从零开始编写一个最简单的validate策略,并深入解析策略YAML的每一层结构。

前置条件:确保集群已安装Kyverno v1.10+,并且kubectl能够正常访问集群。如果尚未安装,可以使用kubectl create -f https://raw.githubusercontent.com/kyverno/kyverno/main/config/install.yaml快速部署。

3.1 策略目标:禁止特权容器

特权容器是Kubernetes安全中最常见的风险点之一。当容器以privileged: true运行时,它将拥有宿主机内核的全部能力,可以访问所有设备、加载内核模块、绕过命名空间隔离。我们的第一个策略将拦截所有尝试创建特权容器的Pod。

安全基线要求:根据CIS Kubernetes Benchmark和NSA Kubernetes Hardening Guide,生产环境必须禁止特权容器。Kyverno策略可以确保这一要求在集群级别强制执行。

3.2 策略YAML完整示例

下面是一个完整的Kyverno validate策略,用于禁止创建包含特权容器的Pod:

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"
注意:上述策略中的privileged: "false"使用了字符串形式的"false",这是因为Kyverno的pattern字段在匹配布尔值时,需要使用字符串表示。如果直接写false(不带引号),Kyverno会将其解析为布尔类型,可能导致匹配行为不符合预期。

3.3 策略YAML结构逐层解析

为了深入理解策略的组成,我们将上述YAML拆解为四个核心层级,每一层都有其特定的职责和配置选项。

层级 字段路径 作用 关键配置项
策略元数据 apiVersion / kind / metadata 定义策略的API版本、资源类型和标识信息 kyverno.io/v1、ClusterPolicy、name
策略行为 spec.validationFailureAction / spec.background 控制策略的生效模式和扫描范围 Enforce / Audit、true / false
规则定义 spec.rules[].match / spec.rules[].exclude 指定策略适用的资源范围和排除条件 any / all、resources.kinds、namespaces
校验逻辑 spec.rules[].validate 定义具体的校验规则和失败时的提示信息 message、pattern、anyPattern、deny

3.4 核心字段详解

3.4.1 validationFailureAction:策略的两种模式

这个字段决定了策略在匹配失败时的行为:

  • Enforce(强制执行):当资源不符合策略时,Kyverno会直接拒绝该资源的创建或更新请求。这是生产环境推荐的模式。
  • Audit(审计模式):当资源不符合策略时,Kyverno不会拒绝请求,但会在策略报告中生成一条违规记录。适用于策略上线前的灰度验证。
最佳实践:在CI/CD流水线中,建议先在Audit模式下运行策略,观察违规报告,确认无误后再切换为Enforce模式。这样可以避免因策略配置错误导致生产服务中断。

3.4.2 background:存量资源扫描

当设置为true时,Kyverno会在策略创建后,对集群中已有的所有匹配资源进行扫描,并在策略报告中标记违规项。这对于发现历史遗留的安全问题非常有用。

3.4.3 match:资源匹配规则

match字段支持两种逻辑运算符:

  • any:只要满足任意一个条件即匹配。适用于多资源类型或多种标签场景。
  • all:必须满足所有条件才匹配。适用于需要同时满足资源类型和命名空间等复合条件。

在我们的示例中,any下只定义了一个条件,即匹配所有Pod类型的资源。如果需要排除某些命名空间,可以在exclude字段中配置。

3.4.4 validate.pattern:声明式校验

pattern字段使用声明式语法定义资源的期望状态。Kyverno会将待校验的资源与pattern进行对比:

  • 如果资源中的字段值等于pattern中指定的值,则校验通过。
  • 如果资源中的字段值不等于pattern中指定的值,则校验失败。
  • 如果资源中缺少pattern中指定的字段,则校验通过(因为缺失字段意味着该字段未被设置,符合“非特权”的期望)。

在我们的策略中,privileged: "false"表示期望所有容器的securityContext.privileged字段要么不存在,要么被显式设置为false。任何设置为true的容器都会触发校验失败。

3.5 策略执行流程SVG

下图展示了Kyverno策略从创建到生效的完整执行流程,以及Enforce和Audit两种模式的分支路径:

Kyverno策略执行流程(Enforce vs Audit) 用户/CI提交Pod YAML API Server 接收请求 Kyverno Webhook 拦截校验 校验结果? 允许创建 / 更新 Enforce: 拒绝请求 Audit: 记录违规报告 用户/CI API Server Kyverno 通过 Enforce拒绝 Audit记录

3.6 部署与验证策略

将上述策略保存为disallow-privileged.yaml,然后执行以下命令部署到集群:

kubectl apply -f disallow-privileged.yaml

验证策略是否成功创建:

kubectl get clusterpolicy disallow-privileged-containers -o wide

输出应显示策略状态为Ready: true。

3.7 测试策略效果

创建一个测试Pod来验证策略是否生效:

kubectl run test-privileged --image=nginx --privileged=true

如果策略处于Enforce模式,你会看到类似以下的拒绝消息:

Error from server: admission webhook "validate.kyverno.svc" denied the request:

resource Pod/default/test-privileged was blocked due to the following policies:

disallow-privileged-containers:
  validate-privileged: '特权容器是不允许的。请移除 ''securityContext.privileged: true'' 配置。'
验证成功:Kyverno成功拦截了特权容器的创建请求,并返回了我们在策略中定义的message字段内容。这表明策略的validate逻辑和pattern匹配规则都正确工作。

3.8 策略结构总结SVG

下图以树形结构展示了Kyverno策略YAML的完整层级关系,帮助你在编写复杂策略时快速定位各字段的位置:

Kyverno ClusterPolicy YAML 结构树 ClusterPolicy apiVersion kind metadata spec validationFailureAction background rules[] name match exclude validate message pattern 根资源 元数据 核心逻辑 策略行为 规则数组 匹配/排除

3.9 常见问题与避坑指南

问题 原因 解决方案
策略创建后状态为Ready: false YAML语法错误或引用了不存在的API版本 使用kubectl describe clusterpolicy <name>查看错误详情,检查apiVersion和字段拼写
策略未拦截特权容器 validationFailureAction设置为Audit,或match规则未正确匹配Pod 确认策略模式为Enforce,检查match中的kinds是否包含Pod
策略报告中没有违规记录 background设置为false,或存量资源已通过其他策略 将background改为true,等待几分钟后重新查看策略报告
布尔值匹配异常 在pattern中直接使用true/false而非字符串 将布尔值用引号包裹,如privileged: "false"
调试技巧:如果策略行为不符合预期,可以使用kubectl kyverno test命令在本地测试策略。该命令会模拟Kyverno的校验逻辑,无需实际部署到集群。例如:kubectl kyverno test . --test-case=test.yaml,其中test.yaml包含待测试的Pod YAML和期望结果。

通过本节的学习,你已经掌握了Kyverno validate策略的完整编写流程和YAML结构。这个禁止特权容器的策略可以作为安全基线策略的起点,后续可以在此基础上扩展更多安全规则,如禁止宿主机网络、限制容器用户ID、强制只读根文件系统等。