# Kubernetes 策略引擎对比：OPA/Gatekeeper vs Kyverno

Kubernetes 的 [Pod Security Policy（PSP）](https://kubernetes.io/docs/concepts/policy/pod-security-policy/)即将被[淘汰和移除](https://github.com/kubernetes/kubernetes/pull/97171)，所以需要找到一个替代方案来填补这个即将出现的空白。目前看来，Kubernetes 自身并没有准备相应的替代方案，因此需要在 Kubernetes 之外寻求解决之道。CNCF 的两个头部项目可能会成为首选的替代产品，它们分别是基于 [Open Policy Agent（OPA）](https://www.openpolicyagent.org/)的 [Gatekeeper](https://github.com/open-policy-agent/gatekeeper) 以及 [Kyverno](https://kyverno.io/)，两个产品各行有千秋，但是目前还没有对这两个产品进行过正式的比较，这就让面临选择的用户无从下手了。这两个项目都是全功能的 Kubernetes 策略引擎，因此其功能不仅限于替代 PSP。本文尝试对 Gatekeeper 和 Kyverno 进行一个中立客观的比较，让用户能够据此作出决策。这里仅从 Kubernetes 的视角来对这两个项目来进行评价。

> 因为本文仅仅涉及 Kubernetes，因此对后续对 OPA/Gatekeeper 项目会简称为 Gatekeeper。

为了透明起见，我想公开说明我个人的立场。我是 Kyverno 而不是 GateKeeper 的撰稿人。我在 Kyverno 上写过几篇博客，在 Gatekeeper 上则没有。我过去还曾对 OPA Rego 提出过一些批评。然而，我的目标是把所有这些和任何个人感情放在一边，并试图以全新的方式来对待这两个项目，没有任何偏见和偏爱。

在和 Kyverno 和 OPA 两个社区进行平等地沟通，让双方的管理者和贡献者公平地对比较标准和结果进行评论。在参与比较、评论等方面均没有偏向任何项目。

## 导言

### Kubernetes 策略是什么

Kubernetes 的 Pod Security Policy，正如其名字所暗示的，仅是针对 Pod 工作的，是一种用来验证和控制 Pod 及其属性的机制。另外 PSP 只能屏蔽非法 Pod 的创建，无法执行任何补救/纠正措施。而 Gatekeeper 和 Kyverno 的作用范围就不是局限在 Pod 上，并且也有更多更深入的功能，而不只是简单的验证功能。策略引擎是一种能对整个 Kubernetes 环境进行全局控制的方法。

### Gatekeeper 简介

Gatekeeper 是一个由 Google、微软等多个公司合作推出的开源项目，后来捐赠给了 CNCF。现已经历了三次迭代。Gatekeeper 是通用策略引擎 Open Policy Agent（OPA）的 Kubernetes 专用实现。由于 Open Policy Agent 与 Gatekeeper 之间的关系，该项目经常被写成“OPA Gatekeeper”来表明这层关系。Gatekeeper 实现了请求验证功能，最近还加入了变异能力。OPA 的一个主要特征是依赖于使用一种叫做 Rego 的专用编程语言，这种语言被用来实现策略决策的必要逻辑。通过 Rego，OPA 能够广泛适用于包括 Kubernetes 在内的多种不同的软件，实现高层次的逻辑操作。

### Kyverno 简介

Kyverno 是来自 Nirmata 的开源项目，后来也捐赠给了 CNCF。和 Gatekeeper一样，Kyverno 也是一个具有验证和变异能力的 Kubernetes 策略引擎，但是它还有生成资源的功能，最近还加入了 API 对象查询的能力。与 Gatekeeper 不同，Kyverno 原本就是为 Kubernetes 编写的。和 Gatekeeper 相比，Kyverno 除了对象生成功能之外，还无需专用语言即可编写策略，从实现语言的角度上来看，Kyverno 的模型更为简洁。

## 对比

下面的三个表格对两个项目的特征和质量进行分类，并试图以最客观的方式进行对比。这些维度分别是：

- 特征/功能维度用于描述技术属性；
- 社区/生态系统维度用于描述落地情况和组织属性；
- 杂项。

特征/功能|Gatekeeper|Kyverno
---|---|---
验证|✅|✅
变异|✅（Alpha）|✅
生成|❌|✅
原生策略对象|✅|✅
监控指标|✅|❌
OpenAPI 验证（`kubectl explain`）|❌|✅
高可用|✅|❌
API 对象查询|✅|✅（Alpha）
具备测试能力的 CLI 工具|✅ 独立的客户端|✅
策略审计|✅|✅

社区/生态系统|Gatekeeper|Kyverno
---|---|---
CNCF 状态|毕业（OPA）|沙箱
合作伙伴生态系统采用（注 1）|◗|◔
Github 状态（星，分叉、版本、提交）|1,543, 280, 38, 510|702, 72, 60, 3,034
社区认同（注 1）|◗|◔
策略样本库|✅|✅

> 注 1：无精确定义，Gatekeeper 看起来比 Kyverno 采用数量更多，但是并没有具体数字。
> 注 2：无客观标准，Gatekeeper 历史更长，社区认可度可能更高。

杂项|Gatekeeper|Kyverno
---|---|---
需要编程|✅|✅
可以在 Kubernetes 之外工作|✅|❌
诞生时间|2017 年 7 月| 2019 年 5 月
创始公司|Styra（OPA）|Nirmata
文档成熟度|◗（注 1）|◕

> 注 1：并没有统一的评判标准。这里的评价基于 Gatekeeper 的功能，而不是 Rego。

## 分析

根据前面的功能对比，我做了一个简单的归纳，列出两个产品的优劣，这里只写出了标题内容，并不够详尽。

### Gatekeeper 的优势

- 能够表达非常复杂的策略；
- 社区更为成熟；
- 支持多副本模式，更好的可用性和伸缩性。

### Gatekeeper 的劣势

- 需要编程语言支持，该语言的学习曲线较为陡峭，可能会产生大量技术债，并延长交付时间；
- 变异能力还处在萌芽期；
- 没有生成能力，意味着它的主要应用场景就在验证方面；
- 策略复杂冗长，需要多个对象协同实现。

### Kyverno 的优势

- Kubernetes 风格的策略表达方式，非常易于编写；
- 成熟的变异能力；
- 独特的生成和同步能力，扩展了应用场景；
- 快速交付，场景丰富。

### Kyverno 的劣势

- 受到语言能力的限制，难以实现复杂策略；
- 较为年轻，社区接受度不高；
- API 对象查询能力还很初级；
- 没有高可用能力（还在路线图阶段）。

> 警告：下面的内容是我根据前面的对比表和优势劣势列表，再加上自己对这两个工具的体验，以及在云原生社区的走访，综合起来的意见分析。如果你没有兴趣看我的观点，文章就到此为止了。

Kubernetes 是一个声明式的系统：用户向 Kubernetes 提出对状态的要求，Kubernetes 通过各种控制器，去协调观察到的状态，以使其与用户期望的状态一致。这就是云原生平台的核心价值主张。为了实现这一目标，逻辑实现的重任从用户身上转移到了平台本身。每个资源类型都存在一些内部逻辑，这些逻辑就是协调其状态所需的能力。对于 Gatekeeper 来说，到目前为止最大的弱点是它需要一种叫做 Rego 的专门的编程语言来实现这种逻辑，这种语言在其他地方都无法使用。这是一个现实，因为 OPA 是一个通用的策略引擎。只有通过 Gatekeeper 将其改编成 Kubernetes 形式，才能利用其能力。那么实际上，用户负责描述他们希望调和的对象（策略），以及提供必要的逻辑（Rego）来调和它。使用外部 DSL 来管理 Kubernetes 策略，在很多方面都会变得繁琐和复杂，并给项目增加技术债务。作为一种权衡，其明显的优势是可以实现非常强大的策略。毕竟，当一个人需要编写一种编程语言时，他只受限于该语言的能力及其输入。不过，如果可以在其他地方利用 OPA，就可以分摊这种费用。

相比 Gatekeeper 来说，Kyverno 的第一印象就是没有那么复杂的技术需求。因为它是专门为 Kubernetes 构建的，并且用声明式的方法来表达策略，所以它的心理模型与 Kubernetes 对象的描述和协调方式是相同的。执行策略决策所需的逻辑被从用户的负担中移除，成为工具本身的领域。这种模式导致策略的编写方式得到了极大的简化，全面的降低了策略引擎的使用难度。Kyverno 的编译和生成能力，使它从一个简单的准入控制器转变为一个真正的自动化工具。通过结合这三种能力，再加上最近增加的 API 查询能力，Kyverno 能够执行 Gatekeeper 所不能执行的任务，而且还能够消除可能在整个集群和/或组织中分散使用的其他和不同的工具。这种简单性加上它的自动化能力和对其他工具的整合，为新用户以及有经验的用户和操作者带来了巨大的价值。

根据所介绍的信息，我认为 Kyverno 应该是应用 Kubernetes 策略的一个比较自然的选择。但如果用户符合下面两个用例中的一种或两种，就更应该选择 Gatekeeper。

1. 有一种需求和具体意图，使用一致的核心工具将策略应用于组织内不同的系统（即，不仅仅是Kubernetes）。

    反对意见：根据我的经验，无论是在云原生社区内部还是外部，大多数组织目前已经在使用其他工具将策略应用于现有系统。这通常是因为这些系统以及为这些系统实施策略的软件在 Kubernetes 以及 OPA 和 Gatekeeper 之前就已经存在。此外，这些现有工具通常不要求使用编程语言来实现其策略。因此，考虑到现有的知识、运营和资本投资，大多数组织不太可能为了实现工具一致性带来的价值，选择放弃这些工具，转而使用技术负担较重的新工具。

    太长不看：如果你正在寻找一个跨 Kubernetes 和其他系统使用的单一策略引擎，Kyverno 不适合你。

1. 策略的复杂度很高。

    反对意见：根据我的经验，大多数 Kubernetes 用户都没有使用包括 PSP 在内的任何策略支持。而 2020 年对在 AWS 上运行容器化工作负载的客户的调查也得到了类似的结果，只有 49% 的客户使用策略。这些用户中的绝大多数都在做的是重复的策略——例如“容器不应该有特权”或“确保所有命名空间都带有给定的标签”或“验证 Pods 没有使用 hostPath 卷”等。“复杂”这个词是相对的，有点主观，但这样的策略表达方式绝对不复杂。Kyverno 允许以最简单的形式编写策略，这反过来又更容易推理和维护。如果要为一个更复杂、更困难的工具支付额外的价格，就应该尽量物尽其用，否则无法获得价值。

    太长不看：如果无需实现高度复杂的策略，Gatekeeper 不会带来好处。

## 结语

Gatekeeper 和 Kyverno 项目本身都是有价值、有能力的策略引擎，每个项目都有各自的优缺点。最终，用户应该根据自己的需求和限制条件进行评估并做出最明智的决定，但作为一般建议，所有生产用户都应该计划使用策略引擎来保护集群的安全并简化 Kubernetes 管理。
