跳到主要内容

使用 OPA/Gatekeeper 和 RabbitMQ 消息拓扑资源

·4 分钟阅读

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

RabbitMQ Messaging Topology Operator

Messaging Topology Operator 允许通过使用 自定义资源定义 (CRD) 扩展 Kubernetes API,从而以声明方式管理 RabbitMQ 集群内的消息拓扑状态。这种消息拓扑状态包括虚拟主机、队列、交换机、绑定、策略、联邦、铲子、用户和权限。这些对象类型中的每一种都由 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

这个仲裁队列被命名为 my-queue,位于虚拟主机 my-vhost 和 RabbitMQ 集群 my-rabbit-cluster 上。

如果开发人员被分配了允许他们创建 Queue 资源的 roles,那么他们可以自由创建任何具有任何配置的队列。

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

  1. RabbitMQ 集群必须命名为 my-rabbit-cluster
  2. 队列必须在虚拟主机 my-vhost 上声明。

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

使用 Gatekeeper 执行策略

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

部署约束包括三个组件

  1. Gatekeeper 配置,通知 gatekeeper 我们想要监控的资源类型。
  2. 一个约束模板,让 gatekeeper 知道我们想要执行的约束类型,并包含 rego 策略配置。
  3. 约束的特定实例。

回到我们的示例,在 RabbitMQ 队列上执行策略所需的 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 集群名称和虚拟主机配置为参数。rego 代码确保 rabbitmqClusterReferencevhost 与指定的允许值匹配。更一般地,rego 代码块必须包含一个 violation 函数,当发生策略违规时,该函数评估为 true,并附带一条解释策略违规的消息。

我们必须首先部署 ConstraintTemplate 并允许 Gatekeeper 为类型 QueueValidator 创建 CRD,然后我们才能部署 QueueValidator 实例。

---
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

完成所有这些配置后,如果我们尝试创建一个不符合策略的队列,它将被 webhook 拒绝并显示错误。

结论

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

© 2025 rabbitmq.cn. All rights reserved.