3. 策略即代码与资源配额的结合:声明式策略、策略引擎(OPA/Kyverno)介绍

在 Kubernetes 原生环境中,资源配额(ResourceQuota、LimitRange)是静态的 YAML 配置,缺乏条件判断、跨资源关联和审计能力。策略即代码(Policy as Code, PaC)将配额规则从静态清单提升为可编程、可测试、可版本控制的逻辑单元。本节聚焦声明式策略模型与两大主流策略引擎——OPA(Open Policy Agent)和 Kyverno——在资源配额场景下的结合方式。

3.1 声明式策略模型

声明式策略的核心思想是:描述“应该是什么”,而非“如何执行”。在配额管理中,声明式策略定义集群或命名空间下资源使用的边界条件,由策略引擎自动评估并拒绝违规请求。

维度 传统配额(静态 YAML) 声明式策略(PaC)
规则表达 固定字段(max CPU / memory) 条件逻辑 + 变量 + 函数
跨资源关联 不支持 支持(如:Deployment 与 HPA 联动)
审计与回溯 无内置审计 策略执行日志 + Git 版本化
变更影响 直接修改集群状态 先评估再准入,可模拟(dry-run)
实践要点:声明式策略应遵循“单一职责”原则——每条策略只关注一个配额约束(如:最大 Pod 数、最小内存预留、禁止特权容器),便于组合与故障隔离。

3.2 策略引擎对比:OPA vs Kyverno

OPA 与 Kyverno 是 Kubernetes 生态中最主流的策略引擎,两者在架构、策略语言、集成方式上存在显著差异。下表从资源配额场景出发进行对比:

特性 OPA(Rego) Kyverno
策略语言 Rego(声明式查询语言) YAML 原生(类似 Kubernetes 资源)
学习曲线 中高(需理解 Rego 集合与迭代) 低(熟悉 K8s 即可上手)
配额场景适配 通过 data.kubernetes 数据源查询配额 内置 ResourceQuota 校验规则
准入控制模式 Admission Webhook(独立部署) Mutating / Validating Webhook(自动注入)
策略分发 Bundle API / ConfigMap ClusterPolicy / Policy CRD
故障排查工具 opa eval + opa test kyverno test + describe policy
选型建议:如果团队已有 Rego 经验或需要跨平台策略(如 Terraform、Envoy),优先选择 OPA;如果团队以 Kubernetes 为中心且追求低运维成本,Kyverno 的 YAML 原生策略更高效。资源配额场景下,Kyverno 的“策略即 CRD”模型能直接复用 kubectl 生态。

3.3 OPA 在资源配额中的实践

OPA 通过 Rego 策略评估 AdmissionReview 请求,判断 Pod 或 Namespace 的资源声明是否超出配额。以下是一个典型的 Rego 策略片段,用于限制命名空间内所有容器的 CPU 请求总和:

package kubernetes.admission

import data.kubernetes.namespaces

deny[msg] {
    input.request.kind.kind == "Pod"
    ns := input.request.namespace
    quota := namespaces[ns].resourcequota["cpu-request-quota"]
    total_cpu := sum([c | c := input.request.object.spec.containers[_].resources.requests.cpu])
    total_cpu > quota.spec.hard["requests.cpu"]
    msg := sprintf("命名空间 %v 的 CPU 请求总和 %v 超过配额 %v", [ns, total_cpu, quota.spec.hard["requests.cpu"]])
}
故障排查关键点:OPA 策略失败时,需检查 data.kubernetes 数据源是否完整同步、Rego 规则中集合迭代是否遗漏空值、以及 deny 规则是否被其他规则覆盖。使用 opa eval --data policy.rego --input input.json "data.kubernetes.admission" 可离线验证。

3.4 Kyverno 在资源配额中的实践

Kyverno 使用 YAML 定义策略,无需学习新语言。以下是一个 Kyverno ClusterPolicy,用于强制命名空间内所有 Pod 必须设置 resources.requests.memory 且不低于 256Mi:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-memory-request
spec:
  validationFailureAction: Enforce
  rules:
  - name: check-memory-request
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "所有容器必须设置 memory request,且不低于 256Mi"
      pattern:
        spec:
          containers:
          - resources:
              requests:
                memory: ">=256Mi"
调试技巧:Kyverno 提供 kyverno test . 命令,可基于本地策略文件和测试用例(kyverno-test.yaml)进行离线验证。在配额故障场景中,优先使用 kubectl describe clusterpolicy require-memory-request 查看策略状态与匹配计数。

3.5 策略即代码与资源配额的结合架构

下图展示了策略引擎在 Kubernetes 准入控制链中的位置,以及如何与 ResourceQuota 协同工作:

策略即代码与资源配额结合架构 策略即代码与资源配额结合架构 kubectl / API API Server 策略引擎 Webhook OPA / Kyverno 策略引擎内部 策略评估引擎 数据缓存层 ResourceQuota 策略存储(Git) 准入决策(Allow/Deny) etcd(持久化) 说明: 策略引擎在 API Server 的准入控制链中作为 Mutating / Validating Webhook 运行, 通过查询 ResourceQuota 对象和策略存储中的规则,生成 Allow/Deny 决策。

3.6 策略即代码的故障排查要点

  • 策略未生效:检查 Webhook 配置是否指向正确的 Service 和端口;使用 kubectl get validatingwebhookconfiguration 确认规则匹配范围。
  • 误拒绝(False Positive):在 OPA 中启用 print() 调试输出;在 Kyverno 中设置 validationFailureAction: Audit 观察策略匹配情况。
  • 性能瓶颈:策略引擎应配置资源限制(CPU/Memory),避免因复杂 Rego 循环导致 API Server 超时;建议将策略评估超时设为 3 秒。
  • 数据不一致:OPA 依赖 data.kubernetes 数据源,需确保 OPA 与 API Server 之间的缓存同步延迟在可接受范围内(通常 < 30 秒)。
生产建议:在 CI/CD 流水线中集成策略测试(opa test 或 kyverno test),将策略即代码纳入版本管理。每次变更配额策略前,先在预发环境以 Audit 模式运行,观察对现有工作负载的影响。