跳至主内容

将 OPA/Gatekeeper 与 RabbitMQ Messaging Topology Operator 结合使用

·阅读时长4分钟

许多组织都有关于 RabbitMQ 使用的策略,并希望强制执行这些策略。这篇博文通过示例解释了如何将 Open Policy Agent Gatekeeper 项目RabbitMQ Messaging Topology Operator 结合使用,以在 Kubernetes 上管理 RabbitMQ 资源,并通过扩展 Kubernetes API 来强制执行对这些资源的策略。

RabbitMQ 消息拓扑运算符

消息拓扑运算符通过使用自定义资源定义 (CRD) 扩展 Kubernetes API,可以声明式地管理 RabbitMQ 集群内的消息拓扑状态。这种消息拓扑状态包括 vhosts、队列、交换器、绑定、策略、联邦、Shovel、用户和权限。这些对象类型中的每一种都由一个 Kubernetes CRD 表示,并且可以在文档中找到这些自定义资源 (CR) 的示例。

为了具体说明,我们考虑一个队列

---
apiVersion: rabbitmq.com/v1beta1
kind: Queue
metadata:
name: my-queue
spec:
name: my-queue
vhost: my-vhost
type: quorum
rabbitmqClusterReference:
name: my-rabbit-cluster

这个仲裁队列(quorum queue)名为 my-queue,位于 my-vhost vhost 上,属于 RabbitMQ 集群 my-rabbit-cluster

如果开发人员被授予创建 Queue 资源的权限,那么他们可以自由地创建任何他们想要的、具有任何配置的队列。

假设我们有一些关于队列的策略需要强制执行,例如,以下策略列表

  1. RabbitMQ 集群的名称必须是 my-rabbit-cluster
  2. 队列必须在 my-vhost vhost 上声明。

一种选择是限制开发人员的 Kubernetes 角色,以阻止他们创建队列,而是建立一个手动票务系统,由 Kubernetes 管理员为他们创建 Queue 对象。然而,这种策略强制执行方法是手动的、耗时的,并且阻碍了开发人员满足自身需求。

使用 Gatekeeper 强制执行策略

Gatekeeper 以不同的方式扩展 Kubernetes API,允许我们创建 Webhook 以确保 Kubernetes API 对象符合通过OPA Rego 语言定义的策略。一旦我们在 Kubernetes 集群中部署了 Gatekeeper,我们就可以强制执行我们选择的任何策略。特别是,我们可以创建一个约束来强制执行上述策略。

部署约束包括三个组件

  1. Gatekeeper 配置,告知 Gatekeeper 我们希望监视哪些类型的资源。
  2. 约束模板,让 Gatekeeper 知道我们希望强制执行哪种类型的约束,并包含 Rego 策略配置。
  3. 约束的具体实例。

以我们的示例为例,强制执行 RabbitMQ Queue 策略所需的 Gatekeeper 配置是

---
apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
name: config
namespace: gatekeeper-system
spec:
sync:
syncOnly:
- group: rabbitmq.com
version: v1beta1
kind: Queue

为了强制执行上述策略,我们创建了以下 ConstraintTemplate

---
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: queuevalidator
spec:
crd:
spec:
names:
kind: QueueValidator
validation:
openAPIV3Schema:
properties:
rabbit:
type: string
vhost:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package queuevalidator
violation[{"msg":msg}] {
allowedRabbit := input.parameters.rabbit
givenRabbit := input.review.object.spec.rabbitmqClusterReference.name
givenRabbit != allowedRabbit
allowedVhost := input.parameters.vhost
givenVhost := input.review.object.spec.vhost
givenVhost != allowedVhost
msg := sprintf("Rabbit Cluster must be %v, queues must be declared on vhost %v", [allowedRabbit, allowedVhost])
}

从这个 ConstraintTemplate 开始,Gatekeeper 将创建一个名为 QueueValidator 的自定义资源种类,它接受两个属性:rabbitvhost,均为字符串。这允许我们在部署约束实例时,将允许的 RabbitMQ 集群名称和 vhost 作为参数进行配置。Rego 代码确保 rabbitmqClusterReferencevhost 与指定的允许值匹配。更一般地说,rego 块必须包含一个违规函数,当发生策略违规时该函数评估为 true,并附带一条解释策略违规的消息。

在部署 QueueValidator 实例之前,我们必须先部署 ConstraintTemplate 并允许 Gatekeeper 创建 QueueValidator 种类的 CRD。

---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: QueueValidator
metadata:
name: queue-validator
spec:
match:
kinds:
- apiGroups: ["rabbitmq.com"]
kinds: ["Queue"]
parameters:
- rabbit: my-rabbit-cluster
- vhost: my-vhost

在所有这些配置到位后,如果我们尝试创建一个不符合策略的 Queue,它将被 webhook 拒绝并报错。

结论

Gatekeeper 是一个扩展 Kubernetes API 以强制执行策略的运算符。与 RabbitMQ Messaging Topology Operator 结合使用,可以声明式地管理 RabbitMQ 对象并通过 Kubernetes API 确保合规性。我们已经展示了一个简单的例子,但是用于配置策略的 OPA 语言是高度可扩展的,允许 Gatekeeper 执行高级策略管理。

© . This site is unofficial and not affiliated with VMware.