云原生安全入门:使用 OPA 和 Kyverno 实现 Kubernetes 策略即代码
云原生安全入门:使用 OPA 和 Kyverno 实现 Kubernetes 策略即代码
随着云原生技术的普及,Kubernetes 已成为容器编排的事实标准。然而,集群的复杂性和动态性也给安全治理带来了巨大挑战。传统的安全配置和审计方式难以跟上快速变化的部署节奏。"策略即代码"(Policy as Code)应运而生,它将安全策略、合规性要求和最佳实践以代码的形式进行定义、管理和自动化执行,是实现云原生安全左移和持续合规的关键范式。
本文将深入探讨两个在 Kubernetes 策略即代码领域占据主导地位的工具:开放策略代理(OPA) 和 Kyverno。我们将通过实际示例,展示如何利用它们来加固你的集群安全。
为什么需要策略即代码?
在动态的 Kubernetes 环境中,手动检查配置、确保合规几乎是不可能的。策略即代码带来了以下核心优势:
- 自动化与一致性:策略在资源创建或更新时自动执行,确保所有部署都符合既定规则。
- 可审计性:策略本身是版本控制的代码,所有决策都有迹可循。
- 开发与运维协作:策略可以作为代码在 CI/CD 管道中共享和执行,实现安全左移。
- 灵活性:可以定义从简单(如“所有 Pod 必须有标签”)到复杂(如“镜像必须来自受信任的仓库且已扫描”)的各种规则。
OPA:通用的策略引擎
开放策略代理(OPA)是一个开源的、通用的策略引擎,它使用一种名为 Rego 的声明性语言来定义策略。OPA 不局限于 Kubernetes,但其 kube-mgmt 或 OPA Gatekeeper 项目专门用于 K8s 集成。
OPA Gatekeeper 核心概念
- ConstraintTemplate:定义策略的逻辑结构(使用 Rego)和输入参数。
- Constraint:基于 ConstraintTemplate 创建的具体策略实例,为其提供参数。
示例:使用 OPA Gatekeeper 禁止特权容器
首先,你需要安装 OPA Gatekeeper。然后,创建一个 ConstraintTemplate 来定义“禁止特权容器”的规则逻辑。
# privileged-containers-template.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sprivilegedcontainers
spec:
crd:
spec:
names:
kind: K8sPrivilegedContainers
validation:
openAPIV3Schema:
properties:
message:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sprivilegedcontainers
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
container.securityContext.privileged
msg := sprintf("容器 %v 以特权模式运行,被禁止。", [container.name])
}
接着,创建一个 Constraint 来应用这个模板。
# require-non-privileged.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPrivilegedContainers
metadata:
name: require-non-privileged
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
message: "特权容器是不允许的。"
应用上述配置后,任何尝试创建包含 securityContext.privileged: true 的 Pod 的请求都会被 Gatekeeper 准入控制器拒绝。
Kyverno:Kubernetes 原生的策略引擎
Kyverno(希腊语意为“治理”)是专为 Kubernetes 设计的策略引擎。它的最大特点是策略也使用 YAML 编写,并且可以直接引用和操作 Kubernetes 资源,学习曲线相对 OPA/Rego 更为平缓。
Kyverno 核心概念
- ClusterPolicy:定义策略规则的主要资源。
- 规则类型:包括
validate(验证)、mutate(变更)、generate(生成)和verifyImages(镜像验证)。
示例:使用 Kyverno 为所有命名空间添加默认网络策略
安装 Kyverno 后,你可以创建一个策略,自动为每个新创建的命名空间生成一个默认的“拒绝所有入站流量”的 NetworkPolicy。
# generate-default-netpol.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: generate-default-netpol
spec:
rules:
- name: generate-default-network-policy
match:
any:
- resources:
kinds:
- Namespace
generate:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
name: default-deny-ingress
namespace: "{{request.object.metadata.name}}"
synchronize: true
data:
spec:
podSelector: {}
policyTypes:
- Ingress
这个策略会在每个命名空间创建时,自动生成一个名为 default-deny-ingress 的 NetworkPolicy,作为安全基线。
OPA 与 Kyverno 如何选择?
| 特性 | OPA/Gatekeeper | Kyverno |
|---|---|---|
| 语言 | 专用的 Rego 语言,功能强大灵活 | Kubernetes YAML,易于上手 |
| 适用场景 | 跨平台、逻辑极其复杂的策略 | Kubernetes 原生场景,特别是变更和生成操作 |
| 策略能力 | 强于验证(Validate) | 验证(Validate)、变更(Mutate)、生成(Generate)、镜像验证(VerifyImages) |
| 社区与生态 | 更成熟,通用性强 | 发展迅速,K8s 社区集成度高 |
简单建议:如果你的团队熟悉声明式语言且策略需求复杂多变,或者需要跨非 K8s 环境统一策略,OPA 是强大选择。如果你希望快速上手,专注于 K8s 内部安全,并充分利用变更、生成等原生操作,Kyverno 可能是更佳选择。许多组织也会同时使用两者,取长补短。
将策略集成到 CI/CD 与工作流
策略即代码的真正威力在于将其集成到整个软件生命周期中。
- 开发阶段:开发者可以在本地使用
kyverno apply或conftest(用于 OPA)测试策略,提前发现问题。 - CI 管道:在 CI 阶段(如 GitHub Actions, GitLab CI)中,对 Kubernetes 清单文件进行策略校验,防止不安全的配置进入版本库。
- CD/部署阶段:通过 Kubernetes 准入控制器(Admission Controller)进行最终、强制的校验,这是最后的安全防线。
在设计和测试这些策略时,清晰的管理和文档至关重要。例如,团队可以使用 dblens SQL编辑器 来管理和查询策略执行的审计日志(如果存储在关系型数据库中),通过高效的 SQL 查询快速定位违规事件,分析策略效果。
总结
OPA 和 Kyverno 是实现 Kubernetes 策略即代码的两大利器。它们将安全与合规要求从滞后的人工检查转变为可编程、自动化、持续执行的保障机制。
- OPA 以其强大的通用性和灵活性,适合处理复杂策略逻辑。
- Kyverno 凭借其 Kubernetes 原生和易用性,让策略定义和管理变得直观高效。
无论选择哪一个,核心都是将安全思维和策略定义融入到开发运维流程中。开始实践时,建议从关键的少数策略(如禁止特权模式、要求资源限制、镜像来源检查)入手,逐步构建你的策略库。
最后,策略的维护和优化是一个持续过程。团队可以利用像 QueryNote 这样的协作笔记工具,来记录策略决策的原因、例外情况以及优化思路,确保安全知识在团队内得以沉淀和共享,让策略即代码不仅是一套自动化规则,更是一种可持续的安全文化。
通过拥抱策略即代码,你的云原生之旅将建立在更稳固、透明和自动化的安全基础之上。
本文来自博客园,作者:DBLens数据库开发工具,转载请注明原文链接:https://chuna2.787528.xyz/dblens/p/19566818
浙公网安备 33010602011771号