3. 策略即代码(Policy as Code)概述:OPA/Gatekeeper、Kyverno、策略引擎在K8s中的角色
在云原生环境中,传统的手动审批和静态配置文件已无法满足安全、合规与运维效率的要求。策略即代码(Policy as Code, PaC) 将治理规则、安全约束和运维最佳实践以声明式代码的形式表达,并通过策略引擎在 Kubernetes 集群中自动执行。本章聚焦三大主流策略引擎:OPA/Gatekeeper、Kyverno 以及通用策略引擎在 K8s 中的核心角色。
3.1 为什么 K8s 需要策略即代码?
Kubernetes 的声明式 API 和动态准入控制为策略执行提供了天然接口。PaC 解决了以下关键问题:
- 安全基线:禁止特权容器、限制 hostPath 挂载、强制只读根文件系统。
- 合规审计:确保所有命名空间包含指定标签(如
cost-center、environment)。 - 资源治理:强制设置 CPU/内存 limits 和 requests,防止资源争抢。
- 运维护栏:禁止使用
latest镜像标签、限制镜像仓库来源。 - 多租户隔离:确保非管理员用户无法修改集群关键组件。
核心价值:策略即代码将治理从“人治”转变为“代码治”,实现可版本控制、可审计、可自动测试的合规体系。
3.2 策略引擎在 K8s 中的工作角色
策略引擎通常以 动态准入 Webhook 的形式集成到 K8s API 请求链路中。当用户提交资源(如 Pod、Deployment、Service)时,API Server 在持久化之前调用 Webhook,策略引擎评估请求并返回 allowed 或 denied。
3.3 三大策略引擎对比
| 特性 | OPA / Gatekeeper | Kyverno | 通用策略引擎 |
|---|---|---|---|
| 策略语言 | Rego(声明式查询语言) | YAML 清单(无新语言) | 多种(CEL、Lua、自定义) |
| 学习曲线 | 中高(需学习 Rego) | 低(K8s 原生 YAML 风格) | 视引擎而定 |
| 部署方式 | Gatekeeper 作为 Webhook | 单个 Pod 作为 Webhook | 独立服务或 Sidecar |
| 策略模板 | ConstraintTemplate + Constraint | ClusterPolicy / Policy | 自定义 CRD |
| 突变能力 | 有限(需额外配置) | 原生支持(Mutate 规则) | 视引擎而定 |
| 社区生态 | CNCF 毕业项目,生态丰富 | CNCF 孵化项目,增长迅速 | 较分散 |
| 适用场景 | 复杂逻辑、跨集群策略 | K8s 原生团队、快速上手 | 异构环境、自定义需求 |
3.4 OPA / Gatekeeper 深度解析
开放策略代理(OPA) 是一个通用的策略引擎,使用 Rego 语言表达策略。Gatekeeper 是 OPA 在 K8s 上的原生集成实现,作为准入 Webhook 运行。
3.4.1 核心组件
- ConstraintTemplate:定义策略逻辑(Rego 代码)和参数 schema。
- Constraint:实例化模板,传入具体参数(如允许的镜像仓库列表)。
- Gatekeeper Webhook:拦截 API 请求,执行所有匹配的 Constraint。
3.4.2 示例:禁止特权容器
# ConstraintTemplate: 定义 Rego 逻辑
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8spspprivilegedcontainer
spec:
crd:
spec:
names:
kind: K8sPSPPrivilegedContainer
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8spspprivilegedcontainer
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
container.securityContext.privileged
msg := sprintf("Privileged container %v is not allowed", [container.name])
}
---
# Constraint: 应用策略
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
name: no-privileged-containers
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
注意:Rego 语法对新手有一定门槛。建议从 Gatekeeper 内置的
k8spsp 模板库开始,逐步自定义。
3.5 Kyverno 深度解析
Kyverno 是专为 Kubernetes 设计的策略引擎,策略使用纯 YAML 编写,无需学习新语言。它同时支持 验证(Validate)、突变(Mutate) 和 生成(Generate) 三种策略类型。
3.5.1 策略类型
| 类型 | 作用 | 示例 |
|---|---|---|
| Validate | 拒绝不符合规则的资源 | 禁止 latest 镜像标签 |
| Mutate | 自动修改资源字段 | 自动添加 app.kubernetes.io/name 标签 |
| Generate | 根据规则创建新资源 | 为每个命名空间自动创建 NetworkPolicy |
3.5.2 示例:强制镜像标签不为 latest
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
spec:
validationFailureAction: Enforce
rules:
- name: require-image-tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Using 'latest' tag for image is not allowed."
pattern:
spec:
containers:
- image: "!*:latest"
最佳实践:Kyverno 的
validationFailureAction 可设置为 Audit 模式,先观察策略影响,再切换为 Enforce 强制执行。
3.6 策略引擎选型建议
3.7 策略即代码的 SRE 视角
从 SRE 角度看,策略引擎是 回滚护栏 和 错误预算 的底层执行者:
- 回滚护栏:策略可以禁止回滚到不符合安全基线的旧版本镜像,或强制回滚时必须保留审计日志。
- 错误预算:策略可以限制变更频率(如每天最多 5 次 Deployment 更新),防止过度消耗错误预算。
- SLO 保护:策略可以拒绝可能影响 SLO 的配置(如移除健康检查探针、降低副本数至 1)。
关键结论:策略即代码不是安全团队的专属工具,而是 SRE 实现自动化治理、减少人为失误、保障服务等级目标的核心基础设施。