1. 概述

在 Kubernetes 集群中,策略引擎可以简化策略的管理和执行。在本教程中,我们将介绍一个开源的 Kubernetes 策略引擎 —— Kyverno

需要说明的是,本文旨在对 Kyverno 做一个友好的入门介绍。因此,我们使用的示例会相对简单,远未达到 Kyverno 实际能力的上限。这种取舍是为了让文章更简洁,便于读者快速上手。

2. Kyverno 简介

Kyverno 是一个开源的 Kubernetes 策略引擎,它提供了一种基于代码的策略框架,用于在 Kubernetes 集群中实施自定义策略。它通过作为 Kubernetes 的动态准入控制器(Admission Controller)运行来实现策略的自动执行。

kube-apiserver 接收到请求时,它会将请求数据传递给准入控制器。此时,Kyverno 控制器就可以检查请求内容,并根据已定义的策略决定是否允许该请求通过。

Kyverno 相较于其他 Kubernetes 策略引擎的一大优势在于:我们可以使用 Kubernetes 原生资源(如 CRD)来编写策略,而无需学习新的策略语言

在用户数量较少的集群中,策略引擎的作用可能并不明显,因为此时的策略管理通常依赖于用户之间的沟通。然而,当集群用户数量增多时,沟通变得困难,策略执行也更难统一。此时,有了策略引擎,集群管理员只需部署合适的策略,引擎即可确保所有资源都符合规范。

3. 安装方式

Kyverno 提供了多种方式将必要的组件安装到 Kubernetes 集群中。最简单的方式是使用 kubectl create 命令加载 manifest YAML 文件

$ kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.10.0/install.yaml
namespace/kyverno created
serviceaccount/kyverno-admission-controller created
serviceaccount/kyverno-background-controller created
...

上述命令使用 kubectl create 加载远程的 install.yaml 文件,从而在集群中创建所需资源。

虽然这种方式简单,但不建议在生产环境中使用。相反,推荐使用 Kyverno 的 Helm Chart 进行安装。Helm Chart 的优势在于便于后续的升级和回滚,同时支持灵活的自定义配置,这对于生产环境尤为重要。

如需 Helm Chart 的详细安装步骤,请参考 官方文档

4. 创建第一个策略

为了更好地理解 Kyverno 的工作原理,我们来创建一个简单的策略并应用到集群中。该策略是一个验证规则,用于确保集群中所有的 Deployment 资源都必须包含 owner 标签。

在 Kyverno 中,我们通过创建 ClusterPolicy 对象来定义策略。**ClusterPolicy 是 Kyverno 中定义策略的核心资源类型**。

下面是一个强制要求 Deployment 必须包含 owner 标签的 ClusterPolicy 示例:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: mandatory-ownership-info-policy
spec:
  validationFailureAction: Enforce
  rules:
  - name: verify-owner-label
    match:
      any:
      - resources:
          kinds:
          - Deployment
    validate:
      message: "Every deployment must label an 'owner'"
      pattern:
        metadata:
          labels:
            owner: "?*"

我们创建了一个名为 mandatory-ownership-info-policy 的策略。在 spec 部分,我们定义了一个规则数组,用于指定策略的匹配条件和验证逻辑。

4.1. 验证策略的实际效果

为了验证策略是否生效,我们尝试创建一个没有 owner 标签的 Deployment

$ kubectl create deployment redis --image=redis
error: failed to create deployment: admission webhook "validate.kyverno.svc-fail" denied the request:

resource Deployment/default/redis was blocked due to the following policies

mandatory-ownership-info-policy:
  verify-owner-label: 'validation error: Every deployment must label an ''owner''.
    rule verify-owner-label failed at path /metadata/labels/team/'

如预期,创建失败,并提示错误信息:Every deployment must label an 'owner'。这是因为 Kyverno 拦截了该请求,并根据策略规则拒绝了它。

4.2. 验证失败时的处理方式

在策略定义中,validationFailureAction 字段用于指定当资源不满足策略时的处理方式。其取值可以是:

  • Enforce:拒绝不合规的请求(默认行为)
  • Audit:仅记录违规,允许请求通过

使用 Audit 模式可以在策略上线初期用于观察和调试,而不影响正常部署。

4.3. 策略规则类型

Kyverno 的 ClusterPolicy 支持三种主要的规则类型:

validate:验证资源是否符合指定的模式。不符合时根据 validationFailureAction 的设置决定是否拒绝请求。

示例:确保 Deployment 必须有 owner 标签

validate:
  message: "Every deployment must label an 'owner'"
  pattern:
    metadata:
      labels:
        owner: "?*"

mutate:在资源创建时自动修改其配置。适用于为资源添加默认配置或修改特定字段。

例如:当容器镜像标签为 latest 时,自动设置 imagePullPolicyAlways

mutate:
  patchStrategicMerge:
    spec:
      containers:
        - (image): "*:latest"
          imagePullPolicy: "Always"

这里的 (image) 表示一个条件锚点(Conditional Anchor),类似 if 语句。

generate:根据条件自动生成其他资源。适用于自动创建 ConfigMap、Secret 等辅助资源。

例如:当创建新命名空间时,自动生成一个 API Key 的 Secret:

generate:
  synchronize: true
  apiVersion: v1
  kind: Secret
  name: metric-server-api-key
  namespace: "{{request.object.metadata.name}}"
  data:
    .api-key: c3VwZXJzZWNyZXQ=

此外,该策略还包含 exclude 字段,用于排除特定命名空间(如 kube-system, default 等),防止策略在这些命名空间中生效。

5. 总结

本文介绍了为什么在 Kubernetes 集群中使用策略引擎是很有必要的,并重点讲解了 Kyverno 这一开源策略引擎。

我们演示了如何创建一个简单的策略来强制所有 Deployment 必须包含 owner 标签,并详细解释了 Kyverno 支持的三种策略规则类型:

  • validate:用于验证资源是否合规
  • mutate:用于修改资源定义
  • generate:用于根据条件自动生成资源

这些功能使得 Kyverno 成为一个强大而灵活的 Kubernetes 策略管理工具。


原始标题:Introduction to Kyverno