跳至主要内容

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

·阅读时长:4 分钟

许多组织对 RabbitMQ 的使用有自己的策略,希望能够执行这些策略。本博文将通过示例说明如何将 Open Policy Agent Gatekeeper 项目RabbitMQ 消息拓扑操作符 结合使用,通过扩展 Kubernetes API 来管理 Kubernetes 上的 RabbitMQ 资源并执行这些资源的策略。

RabbitMQ 消息拓扑操作符

消息拓扑操作符允许通过使用 自定义资源定义 (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 上。

如果开发人员被分配了允许他们创建队列资源的角色,那么他们就可以自由地创建任何他们想要的队列,并使用任何他们想要的配置。

假设我们有关于队列的策略,希望执行这些策略,例如以下策略列表

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

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

使用 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 块必须包含一个违规函数,当策略违规发生时该函数将评估为真,并附带一条解释策略违规的消息。

我们必须首先部署 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 以执行策略。与 RabbitMQ 消息拓扑操作符结合使用,可以通过 Kubernetes API 声明式地管理 RabbitMQ 对象并确保合规性。我们展示了一个简单的示例,但用于配置策略的 OPA 语言具有高度可扩展性,允许 Gatekeeper 执行高级策略管理。

© 2024 RabbitMQ. All rights reserved.