3. Kyverno 核心机制:策略引擎架构、准入控制流程、资源配额(ResourceQuota)策略编写基础
Kyverno 是一个为 Kubernetes 设计的云原生策略引擎,其核心机制围绕“策略即代码”的理念构建。本章将深入剖析 Kyverno 的策略引擎架构、准入控制流程,并重点讲解资源配额(ResourceQuota)策略的编写基础,为后续与 eBPF 协同的故障排查打下坚实的理论基础。
3.1 策略引擎架构
Kyverno 的策略引擎采用模块化设计,主要由以下几个核心组件构成,它们协同工作以实现策略的声明、加载、匹配与执行。
- 策略控制器(Policy Controller): 引擎的主循环,负责监听 Kubernetes 资源变化,触发策略评估。
- 策略缓存(Policy Cache): 将集群中的 ClusterPolicy/Policy 资源加载到内存,加速匹配与检索。
- 准入 Webhook 服务器(Admission Webhook Server): 接收 API Server 的准入请求,执行策略验证与变更。
- 规则引擎(Rule Engine): 解析策略中的规则(rules),执行匹配、验证、变更(mutate)与生成(generate)操作。
- 报告控制器(Report Controller): 生成策略执行报告(PolicyReport),记录策略的合规状态。
下图展示了 Kyverno 策略引擎的内部组件及其交互关系:
3.2 准入控制流程
Kyverno 作为动态准入控制器,其核心工作流程发生在 Kubernetes 资源创建、更新或删除的请求被持久化到 etcd 之前。该流程确保了所有资源操作都符合预定义的策略。
| 步骤 | 组件 | 动作描述 |
|---|---|---|
| 1 | kube-apiserver | 收到用户或控制器的资源操作请求(如 kubectl apply)。 |
| 2 | 准入链 | API Server 对请求进行认证、鉴权,然后进入准入控制链。 |
| 3 | MutatingWebhookConfiguration | API Server 根据配置,向 Kyverno 的变更 Webhook 发送 AdmissionReview 请求。 |
| 4 | Kyverno 规则引擎 | 执行所有匹配的 mutate 规则,对资源对象进行修改(如注入 Sidecar)。 |
| 5 | 对象模式验证 | API Server 对变更后的对象进行基本的 Schema 验证。 |
| 6 | ValidatingWebhookConfiguration | API Server 向 Kyverno 的验证 Webhook 发送 AdmissionReview 请求。 |
| 7 | Kyverno 规则引擎 | 执行所有匹配的 validate 规则,检查资源是否合规。 |
| 8 | 准入响应 | Kyverno 返回允许(Allowed)或拒绝(Denied)的响应。若拒绝,API Server 会向客户端返回错误。 |
| 9 | etcd | 若允许,API Server 将资源对象持久化到 etcd 中。 |
下图展示了从请求发起 to 资源持久化的完整准入控制流程:
3.3 资源配额(ResourceQuota)策略编写基础
ResourceQuota 是 Kubernetes 内置的用于限制命名空间资源消耗的对象。Kyverno 可以生成(generate)或验证(validate)ResourceQuota 对象,确保每个命名空间都有合理的资源上限。编写 Kyverno 策略来管理 ResourceQuota 是配额治理的基础。
3.3.1 策略类型:Generate 策略
Generate 策略用于在满足特定条件时自动创建 ResourceQuota 对象。例如,当创建一个新的命名空间时,自动为其生成一个默认的 ResourceQuota。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: generate-default-resourcequota
spec:
rules:
- name: generate-quota
match:
any:
- resources:
kinds:
- Namespace
generate:
apiVersion: v1
kind: ResourceQuota
name: default-quota
namespace: "{{request.object.metadata.name}}"
synchronize: true
data:
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
persistentvolumeclaims: "10"
pods: "50"
match: 定义触发策略的资源类型,这里是 Namespace。generate: 定义要生成的资源模板。namespace: "{{request.object.metadata.name}}": 使用 JMESPath 表达式动态获取新命名空间的名称。synchronize: true: 确保生成的 ResourceQuota 与策略定义保持同步,如果策略更新,生成的资源也会被更新。data.spec.hard: 定义资源配额的具体硬限制。
3.3.2 策略类型:Validate 策略
Validate 策略用于检查现有的 ResourceQuota 对象是否符合预期。例如,确保所有命名空间的 ResourceQuota 都设置了 CPU 和内存限制。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: validate-resourcequota-exists
spec:
rules:
- name: check-quota-exists
match:
any:
- resources:
kinds:
- Namespace
preconditions:
all:
- key: "{{ request.object.metadata.name }}"
operator: NotEquals
value: kube-system
validate:
message: "命名空间 {{ request.object.metadata.name }} 必须包含一个 ResourceQuota 对象。"
deny:
conditions:
all:
- key: "{{ length({{ request.object.metadata.name | resourcequotas(@, 'v1') }}) }}"
operator: Equals
value: 0
{{ request.object.metadata.name | resourcequotas(@, 'v1') }} 会查询当前命名空间下的 ResourceQuota 列表。如果列表长度为 0,则拒绝该命名空间的创建(或更新,取决于 match 的配置)。这种策略对于强制实施配额标准非常有用。
3.3.3 策略编写对比
| 特性 | Generate 策略 | Validate 策略 |
|---|---|---|
| 主要目的 | 自动创建 ResourceQuota | 检查 ResourceQuota 是否存在或合规 |
| 触发时机 | 匹配资源创建时 | 匹配资源创建或更新时 |
| 对现有资源的影响 | 不直接影响,除非 synchronize 为 true |
可以拒绝不合规的请求 |
| 典型用例 | 为新命名空间提供默认配额 | 确保所有命名空间都有配额,或配额值在允许范围内 |
| 复杂度 | 中等,需要定义资源模板 | 中等,需要编写条件表达式 |
通过组合使用 Generate 和 Validate 策略,可以构建一个强大的、自动化的资源配额治理体系。Generate 策略负责“播种”,Validate 策略负责“守护”,两者共同确保了集群资源使用的有序性和可控性。