跳至主内容

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

·阅读时长4分钟

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

RabbitMQ 消息拓扑运算符 (Messaging Topology Operator)

消息拓扑运算符允许通过扩展 Kubernetes API 并使用 自定义资源定义 (CRD),以声明式方式管理 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

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

如果开发人员被分配了允许其创建队列 (Queue) 资源的权限,他们就可以随意创建任何配置的队列。

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

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

一种选择是限制开发人员的 Kubernetes 角色,禁止他们创建队列,改为采用手动工单系统,由 Kubernetes 管理员为他们创建队列对象。然而,这种策略执行方法是手动的,非常耗时,且无法满足开发人员的即时需求。

使用 Gatekeeper 执行策略

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

部署约束包含三个组件:

  1. Gatekeeper 配置:告知 Gatekeeper 我们想要监控哪些类型的资源。
  2. 约束模板 (Constraint Template):告知 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 以执行策略的运算符。结合 RabbitMQ 消息拓扑运算符,我们能够以声明方式管理 RabbitMQ 对象,并通过 Kubernetes API 确保合规性。虽然我们展示的是一个简单的示例,但用于配置策略的 OPA 语言具有高度的可扩展性,允许 Gatekeeper 执行高级的策略管理。

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