跳至主要内容

使用 RabbitMQ 集群 Kubernetes 运算符

如何使用 RabbitMQ 集群 Kubernetes 运算符

使用此信息了解如何部署自定义资源对象,这些对象随后由RabbitMQ 集群 Kubernetes 运算符管理。

如果此时未安装 RabbitMQ 集群 Kubernetes 运算符,请参阅在 Kubernetes 集群中安装 RabbitMQ 集群运算符。有关快速入门的说明,请参阅快速入门信息。

以下信息按以下部分结构化

有关在 Openshift 上使用 RabbitMQ 集群 Kubernetes 运算符的其他信息,请参阅在 Openshift 上使用 RabbitMQ Kubernetes 运算符

确认服务可用性

在将您的应用配置为使用 RabbitMQ 集群 Kubernetes 运算符之前,请确保 RabbitmqCluster 自定义资源已部署到您的 Kubernetes 集群中并且可用。

要确认此可用性,请运行

kubectl get customresourcedefinitions.apiextensions.k8s.io

然后验证 rabbitmqclusters.rabbitmq.com 是否在列表中,如下例所示

kubectl get customresourcedefinitions.apiextensions.k8s.io
# NAME CREATED AT
# rabbitmqclusters.rabbitmq.com 2019-10-23T10:11:06Z

如果不是,请按照安装指南中的步骤进行安装。

(可选) 应用 Pod 安全策略

如果在 Kubernetes 集群中启用了Pod 安全策略,则必须创建 [Cluster]Role[Cluster]RoleBinding 以启用 Pod 调度。有关 Pod 安全策略的更多信息,请参阅Kubernetes 文档。如果使用 RoleRoleBinding,它将仅在部署 RBAC 的命名空间中有效。

如果未启用 Pod 安全策略,请跳至下面创建 RabbitMQ 实例

必须在创建 RabbitmqCluster 实例之前创建 RoleRoleBinding。可以创建引用不存在的服务帐户或用户的绑定。运算符使用模式 INSTANCE-NAME-server 创建服务帐户。例如,名为“mycluster”的 RabbitmqCluster 将生成名为 mycluster-server 的服务帐户。为了允许服务帐户使用 PSP,必须将具有动词“use”的角色绑定到服务帐户。例如

# Assuming RabbitmqCluster name is 'mycluster'

kubectl create role rabbitmq:psp:unprivileged \
--verb=use \
--resource=podsecuritypolicy \
--resource-name=some-pod-security-policy
# role "rabbitmq:psp:unprivileged" created

kubectl create rolebinding rabbitmq-mycluster:psp:unprivileged \
--role=rabbitmq:psp:unprivileged \
--serviceaccount=some-namespace:mycluster-server
# rolebinding "rabbitmq-mycluster:psp:unprivileged" created

Kubernetes 文档 中有一个创建 RBAC 规则和策略的示例。

创建 RabbitMQ 实例

要创建 RabbitMQ 实例,必须创建和应用 RabbitmqCluster 资源定义。RabbitMQ 集群 Kubernetes 运算符在定义 RabbitmqCluster 的相同命名空间中创建必要的资源,例如服务和 StatefulSet。

首先,创建一个 YAML 文件以定义名为 definition.yamlRabbitmqCluster 资源。

注意:YAML 文件可以具有任何名称,但后续步骤假定其名称为 definition

然后将下面的代码段复制粘贴到文件中并保存

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: definition

注意:在 Openshift 上创建 RabbitmqClusters 时,必须将其他参数添加到所有 RabbitmqCluster 清单中。有关详细信息,请参阅对任意用户 ID 的支持

接下来,通过运行以下命令应用定义

kubectl apply -f definition.yaml

然后通过运行以下命令验证该过程是否成功

kubectl get all -l app.kubernetes.io/name=definition

如果成功,将有一个正在运行的 Pod 和一个公开该实例的服务。例如

kubectl get all -l app.kubernetes.io/name=definition
# NAME READY STATUS RESTARTS AGE
# pod/definition-server-0 1/1 Running 0 112s
#
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# service/definition-nodes ClusterIP None None 4369/TCP 113s
# service/definition ClusterIP 10.103.214.196 None 5672/TCP,15672/TCP,15692/TCP 113s

现在可以使用 RabbitMQ 集群了。继续了解更高级的配置选项。有关更多信息,请参阅RabbitMQ 文档指南

内部标签和注释

集群运算符创建的子资源始终具有以下标签集

  • app.kubernetes.io/name - 值是与资源关联的 RabbitmqCluster 名称。
  • app.kubernetes.io/component - 它所属的组件。目前始终设置为 rabbitmq
  • app.kubernetes.io/part-of - 此应用程序所属的更高级别应用程序的名称。目前始终设置为 rabbitmq

StatefulSet 创建的 Pod 也应用了相同的标签集。

现有示例

GitHub 存储库中有一些常见用例的示例。一些有趣的用例是

还有更多可用示例

配置 RabbitMQ 实例

要配置 RabbitMQ 实例,请打开 definition.yaml 或通过运行以下命令就地编辑配置

kubectl edit rabbitmqcluster definition

接下来,添加下面列出的任何属性及其值。下面列出的每个属性都是可选的。

在 GitHub 上的运算符存储库中提供了许多配置示例

标签和注释

描述:RabbitmqCluster 元数据中的标签和注释会传播到运算符创建的资源。Pod **不会**继承这些标签和/或注释。

默认值:N/A - 空

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
labels:
app: rabbitmq
annotations:
some: annotation
name: rabbitmqcluster-sample

副本数

描述:指定 RabbitmqCluster 的副本数。强烈建议不要使用偶数个副本。必须使用奇数(1、3、5、7 等)使用

默认值 1

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
replicas: 3

镜像

描述:指定 RabbitMQ 镜像引用。如果使用私有注册表,则此属性是必需的。

默认值:社区带有管理插件的 RabbitMQ 镜像

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
image: my-private-registry/rabbitmq:my-custom-tag

imagePullSecrets

描述:要作为 RabbitMQ 镜像的 imagePullSecrets 使用的 Secret 名称数组。如果注册表需要身份验证,则此数组必须包含用于拉取镜像的密钥的名称。可以通过运行以下命令创建 Kubernetes 密钥

kubectl -n rabbitmq-system create secret docker-registry

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
image: my-private-registry/rabbitmq:3.10
imagePullSecrets:
- name: some-secret

服务类型

描述:指定 RabbitmqCluster 服务的 Kubernetes 服务类型。可用的类型为

  • ClusterIP
  • NodePort
  • LoadBalancer

RabbitMQ 集群 Kubernetes 运算符目前不支持 ExternalName 服务类型。

默认值:ClusterIP

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
service:
type: LoadBalancer

服务注释

描述:指定 RabbitmqCluster 服务的 Kubernetes 服务注释。RabbitMQ 集群 Kubernetes 运算符创建的服务将具有这些注释。

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
service:
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0

持久化

描述:指定 RabbitmqCluster 服务的持久化设置。可用的设置为

  • storageClassName:要使用的 Kubernetes StorageClass 的名称。

    注意:如果您的集群没有默认的 StorageClass,则必须设置此属性,否则 RabbitMQ Pod 将无法调度,因为它们需要持久卷。

  • storage:持久卷的容量,以 Kubernetes 资源数量表示。设置为 0 以完全停用持久化(这在应该始终从头开始的 CI/CD 和测试部署中可能很方便)。

默认值

  • storageClassName:默认情况下未设置。如果您未设置值,则使用 Kubernetes 集群的默认 StorageClass
  • storage:10Gi

要查看默认的 StorageClass,请运行 kubectl get storageclasses

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
persistence:
storageClassName: fast
storage: 20Gi

有关上面提到的概念的更多信息,请参阅

概念更多信息在…
StorageClassKubernetes 文档
持久卷容量Kubernetes 文档
Kubernetes 资源数量GitHub 上的Kubernetes 资源模型文档

注意:使用local-path provisioner 不会强制执行磁盘大小。这意味着 RabbitMQ 报告的可用磁盘空间将多于 .spec.peristence.storage 中配置的磁盘空间。发生这种情况是因为持久磁盘是在托管 Pod 的 Kubernetes 节点中作为本地文件夹创建的。

资源需求

描述:指定 RabbitmqCluster Pod 的资源请求和限制。CPU 请求必须以 CPU 单位表示。内存请求必须以字节为单位。这两个值都必须表示为 Kubernetes 资源数量。

如果提供了这些配置但无效,则 RabbitMQCluster 不会部署。

默认值

  • 内存限制:2 Gi
  • CPU 限制:2000 毫核
  • 内存请求:2 Gi
  • CPU 请求:1000 毫核

RabbitMQ 高水位标记设置为内存限制的 0.4 倍。建议将内存请求和限制设置为相同的值。

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 1000m
memory: 2Gi

注意:RabbitMQ 和 Erlang 可能会暂时超过可用内存总量,这可能导致立即出现 OOM 终止。为了防止这种情况发生,集群操作员通过配置 total_memory_available_override_value 设置了 20% 的内存裕量(最大值为 2GB)。这意味着在 RabbitMQ 中设置的实际内存限制比指定的资源需求少 20%。

有关上面提到的概念的更多信息,请参阅

概念更多信息在…
资源请求和限制要求Kubernetes 文档请参考此处
CPU 度量Kubernetes 文档请参考此处
高水位标记RabbitMQ 文档请参考此处

亲和性和反亲和性规则

描述:亲和性和反亲和性规则的结构方式与Kubernetes 亲和性规则相同。

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node-1

Pod 容忍度

描述:为 RabbitmqCluster Pod 添加容忍度

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "rabbitmq"
effect: "NoSchedule"

RabbitMQ 附加配置

描述:将写入 /etc/rabbitmq/conf.d/90-userDefinedConfiguration.conf 的其他 RabbitMQ 配置选项。RabbitMQ Cluster Kubernetes 运算符会生成一个包含以下属性的配置文件 /etc/rabbitmq/conf.d/10-operatorDefaults.conf

queue_master_locator = min-masters
disk_free_limit.absolute = 2GB
cluster_partition_handling = pause_minority
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_k8s
cluster_formation.k8s.host = kubernetes.default
cluster_formation.k8s.address_type = hostname
cluster_formation.target_cluster_size_hint = ${number-of-replicas}
cluster_name = ${instance-name}

附加配置中的所有值都将在此列表之后应用。如果任何属性指定了两次,则最新的属性将生效。要详细了解 RabbitMQ 配置选项和格式,请查看专门的配置文档

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
rabbitmq:
additionalConfig: |
channel_max = 1050

RabbitMQ 高级配置

描述:将写入 /etc/rabbitmq/advanced.config 文件的高级配置。

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
rabbitmq:
advancedConfig: |
[
{ra, [
{wal_data_dir, '/var/lib/rabbitmq/quorum-wal'}
]}
].

RabbitMQ 环境配置

描述:RabbitMQ 使用 rabbitmq-env.conf 覆盖 RabbitMQ 脚本和 CLI 工具中内置的默认值。spec.rabbitmq.envConfig 的值将写入 /etc/rabbitmq/rabbitmq-env.conf

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
rabbitmq:
envConfig: |
RABBITMQ_DISTRIBUTION_BUFFER_SIZE=some_value

有关自定义环境的其他方法,请参阅spec.override 属性

RabbitMQ 附加插件

描述:在 RabbitMQ 中启用的附加插件。RabbitMQ Cluster Kubernetes 运算符默认启用了 rabbitmq_peer_discovery_k8srabbitmq_prometheusrabbitmq_management。此列表中的插件也将启用。

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
rabbitmq:
additionalPlugins:
- rabbitmq_top
- rabbitmq_shovel

如果需要预配社区插件,则应将其包含在自定义镜像中或在节点启动时下载。后者通常不推荐,因为它违反了不可变镜像和可重复构建的理念。

Erlang INET 配置

描述:与网络相关的运行时配置。所有受支持的设置都在此 Erlang 文档指南中进行了说明。这对于配置节点以使用 IPv6 很有用。

此字段的内容将复制到 ConfigMap 中,并在路径 /etc/rabbitmq/erl_inetrc 中的 RabbitMQ 容器中挂载。

此字段是在集群操作员 2.6.0 中引入的。

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
rabbitmq:
erlangInetConfig: |
{inet6, true}.
envConfig: |
SERVER_ADDITIONAL_ERL_ARGS="-kernel inetrc '/etc/rabbitmq/erl_inetrc' -proto_dist inet6_tcp"
RABBITMQ_CTL_ERL_ARGS="-proto_dist inet6_tcp"

TLS 配置

描述:配置 RabbitMQ 以使用 Secret spec.tls.secretName 提供的证书。Secret 必须已存在于与 RabbitmqCluster 对象相同的命名空间中。预计 Secret 包含私钥的 tls.key 和公钥证书的 tls.crt

默认情况下,启用客户端连接的 TLS不会禁用非 TLS 侦听器。因此,仍然会接受未加密的连接。要禁用非 TLS 侦听器并仅接受 TLS 连接,请将 spec.tls.disableNonTLSListeners: true 设置为 true。

也可以使 RabbitMQ针对提供的 CA 证书验证对等证书。客户端也可以通过相同的方式进行操作,因此对等验证可以是双向的(“mTLS”)。此证书必须存储在名称为 spec.tls.caSecretName 的 Secret 中,该 Secret 与 RabbitmqCluster 对象位于相同的命名空间中。请注意,这可以与 spec.tls.secretName 相同的 Secret。此 Secret **必须**具有一个包含 CA 证书的键 ca.crt

RabbitMQ 节点可以在不重启节点的情况下重新加载 TLS 证书。要轮换 TLS 证书,请使用新证书直接更新 TLS Secret 对象,RabbitMQ Pod 会在几分钟内获取此更改。如果需要加快此过程,可以通过运行以下命令强制 RabbitMQ 立即重新加载证书:

kubectl exec -it INSTANCE-server-0 -- rabbitmqctl eval "ssl:clear_pem_cache()."

或直接从节点 Pod 中运行:

rabbitmqctl eval "ssl:clear_pem_cache()."

由于每个节点都有自己的缓存,因此如果您决定运行此命令,则应在所有集群节点上执行它。

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
tls:
secretName: rabbitmq-server-certs
caSecretName: rabbitmq-ca-cert
disableNonTLSListeners: true

跳过部署后操作

描述:如果未设置或设置为 false,则运算符将在每次更新集群时运行 rabbitmq-queues rebalance all。如果设置为 true,则运算符将跳过运行 rabbitmq-queues rebalance all。有关更多信息,请参阅rabbitmq-queues rebalance all

默认值:false

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
skipPostDeploySteps: true

终止宽限期超时

描述:TerminationGracePeriodSeconds 是每个 rabbitmqcluster pod 必须运行容器 preStop 生命周期挂钩以确保优雅终止的超时时间。生命周期挂钩会在安全终止 pod 之前检查现有仲裁队列的仲裁状态和镜像队列的同步状态。有关详细信息,请参阅rabbitmq-queues check_if_node_is_quorum_critical。默认值为 604800 秒(一周),以确保挂钩可以完成运行。如果在生命周期挂钩完成运行之前终止 pod,可能会导致数据丢失。

默认值 604800

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
terminationGracePeriodSeconds: 60

覆盖资源属性

描述:谨慎使用!通过覆盖其属性或提供其他设置来自定义运算符创建的资源。这是一项高级功能,允许您启用未明确支持但如果使用不当很容易使 RabbitMQ 集群无法使用 的功能。您可以自定义有状态集和客户端应用程序使用的服务。spec.override.statefulSetspec.override.service 的值应分别与有状态集对象服务对象规范匹配。

默认值:N/A

示例

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: additional-port
spec:
replicas: 1
override:
service:
spec:
ports:
- name: additional-port # adds an additional port on the service
protocol: TCP
port: 12345
statefulSet:
spec:
template:
spec:
containers:
- name: rabbitmq
ports:
- containerPort: 12345 # opens an additional port on the rabbitmq server container
name: additional-port
protocol: TCP

在自定义容器的环境变量(env 属性)时,您可以参考 MY_POD_NAMEMY_POD_NAMESPACEK8S_SERVICE_NAME 变量来访问容器元数据。例如:

- name: MY_VARIABLE
value: test-$(MY_POD_NAME).$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE)

更新 RabbitMQ 实例

可以为现有的 RabbitMQ 实例添加、更改或删除 RabbitmqCluster 对象中的属性。

如果删除了属性,它将恢复为其默认值(如果存在)。要查看默认值,请参阅上面配置 RabbitMQ 实例

配置列在下面的表格中。

自定义资源属性描述
metadata.labels

这些是添加到每个子资源(例如有状态集和服务)的标签。以 app.kubernetes.io 开头的标签会被忽略,因为这些标签保留供内部使用。标签不会应用于 Pod。

metadata.annotations

这些是添加到每个子资源(例如有状态集和服务)的注释。
包含 kubernetes.iok8s.io 的注释会被忽略,因为这些注释保留供 Kubernetes 核心组件使用。当指定 spec.service.annotations 时,服务的注释将在 spec.service.annotationsmetadata.annotations 之间合并。
如果两个配置中都指定了相同的键,则应用 spec.service.annotations 中的值。

spec.image

RabbitMQ 镜像引用。

spec.replicas

RabbitMQ 节点的副本数。偶数强烈不建议使用,强烈建议使用奇数。

spec.imagePullSecrets

用于访问包含 RabbitMQ 镜像的注册表的Kubernetes 密钥名称的数组。这仅在私有注册表中需要。

spec.service.type

RabbitmqCluster 服务的 Kubernetes 服务类型。这必须是 ClusterIP、NodePort 或 LoadBalancer。

spec.service.annotations

这些是服务上的注释。请注意,包含 kubernetes.iok8s.io 的注释在此级别不会被过滤。

spec.persistence.storage

持久卷的容量,表示为 Kubernetes 资源数量。设置为 0 以完全停用持久性(这在应该始终全新启动的 CI/CD 和测试部署中可能很方便)。

spec.persistence.storageClassName

将用于请求持久卷的 Kubernetes StorageClass 的名称。

spec.resources.requests.cpu

Kubernetes 调度程序为运行 RabbitMQ 的容器所需的 CPU 单位。

spec.resources.requests.memory

Kubernetes 调度程序为运行 RabbitMQ 的容器所需的内存单位。

spec.resources.limits.cpu

用于计算 RabbitMQ 容器每 100 毫秒可用的 CPU 时间份额的 CPU 单位。

spec.resources.limits.memory

RabbitMQ 容器允许使用的内存限制。容器将不允许使用超过此限制的内存。

spec.affinity

Pod 亲和性和反亲和性规则。

spec.tolerations

将应用于 RabbitMQ Pod 的 Pod 容忍度。

spec.tls.secretName

用于配置 RabbitMQ TLS 的 Secret 名称。Secret 必须存在,并且包含密钥 tls.keytls.crt

spec.tls.caSecretName

用于配置 RabbitMQ mTLS 的 Secret 名称(用于验证客户端证书)。Secret 必须存在,并且包含密钥 ca.crt

spec.tls.disableNonTLSListeners

设置为 true 时,仅允许 TLS 连接(禁用非 TLS 监听器)。

spec.rabbitmq.additionalPlugins

要在 RabbitMQ 中启用的插件列表。默认情况下,RabbitMQ 集群 Kubernetes 运算符启用 Prometheus、K8s 对等发现和管理插件。

spec.rabbitmq.additionalConfig

要附加到集群生成的配置的附加配置。有关始终生成的配置列表,请查看附加配置部分。

spec.rabbitmq.advancedConfig

RabbitMQ advanced.config。请参阅RabbitMQ 高级配置以获取示例。

spec.override

对 RabbitMQ 集群 Kubernetes 运算符创建的资源进行任意覆盖。此功能应谨慎使用,因为覆盖基本属性可能会导致 RabbitMQ 集群无法用于应用程序或无法访问运算符。请参阅覆盖部分以了解更多信息。

有关 CPU 单位、Kubernetes 调度程序和 CPU 时间可用性的更多信息,请参阅Kubernetes 计算资源指南

有关 Pod 亲和性和反亲和性规则的更多信息,请参阅Kubernetes 亲和性规则指南

更新 RabbitMQ 实例

  1. 打开 definition.yaml
  2. 添加或修改上表中列出的任何属性。
  3. 将更改保存到 definition.yaml
  4. 通过运行以下命令应用定义:kubectl apply -f definition.yaml

(可选) 设置 Pod 中断预算

Pod 中断预算 (PDB) 限制由于自愿中断而同时停机的 Pod 副本数量。

例如,PDB 可以帮助

  • 在维护事件(例如 Kubernetes API 升级或内核升级)期间维护基于仲裁的分布式工作负载的可用性。
  • 减少通常为了数据一致性而牺牲可用性的 RabbitMQ 配置的停机时间,例如暂停少数模式以实现分区容错。

创建 PodDisruptionBudget 对象

要创建和设置 PodDisruptionBudget 对象,首先创建一个名为 rabbitmq-pdb.yaml 的文件,其中包含

    apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: pdb-rabbitmq
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: YOUR-RABBITMQ-CUSTOM-RESOURCE-NAME

然后运行

kubectl apply -f rabbitmq-pdb.yaml

有关上面提到的概念的更多信息,请参阅

概念更多信息在…
PDBKubernetes 文档
自愿和非自愿中断Kubernetes 文档
暂停少数模式RabbitMQ 文档

(可选) 配置 TLS

传输层安全 (TLS) 是一种用于加密网络流量的协议。RabbitMQ 支持 TLS,集群运算符简化了使用TLS相互 TLS (mTLS)配置 RabbitMQ 集群的过程,在客户端和集群之间加密流量,以及支持使用 mTLS 加密 RabbitMQ 节点间流量。有关此指南的理解,TLS 的基本概述很有帮助。

客户端和 RabbitMQ 之间的 TLS 加密流量

为了加密客户端和 RabbitMQ 集群之间的流量,必须使用由客户端信任的证书颁发机构 (CA) 签名的服务器证书和密钥对配置 RabbitMQ 集群。这允许客户端验证服务器是否受信任,并且在客户端和服务器之间发送的流量使用服务器的密钥进行加密。

证书的主题备用名称 (SAN) 必须包含至少以下属性

  • *.<RabbitMQ 集群名称>-nodes.<命名空间>.svc.<K8s 集群域名>
  • <RabbitMQ 集群名称>.<命名空间>.svc.<K8s 集群域名>

如果不允许通配符,则证书必须为 RabbitMQ 集群中的每个 RabbitMQ 节点提供 SAN 属性。例如,如果您在名为 mynamespace 的命名空间中部署了一个名为 myrabbit 的 3 节点 RabbitMQ 集群,且 Kubernetes 集群域名默认为 cluster.local,则 SAN 必须至少包含以下属性

  • myrabbit-server-0.myrabbit-nodes.mynamespace.svc.cluster.local
  • myrabbit-server-1.myrabbit-nodes.mynamespace.svc.cluster.local
  • myrabbit-server-2.myrabbit-nodes.mynamespace.svc.cluster.local
  • myrabbit.mynamespace.svc.cluster.local

请注意,最后一个 SAN 属性是客户端服务的 DNS 名称。根据使用的服务类型 (spec.service.type),可能需要其他 SAN 属性。例如,如果使用服务类型 NodePort,则 SAN 必须包含每个 Kubernetes 节点的外部 IP 地址。

要启用 TLS,请创建一个 Kubernetes 密钥,其中包含 PEM 编码的服务器证书 server.pem 和私钥 server-key.pem

kubectl create secret tls tls-secret --cert=server.pem --key=server-key.pem

或使用 Cert Manager 等工具生成 TLS 密钥。

此密钥存在后,可以按照TLS 示例部署 RabbitMQ 集群。

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: additional-port
spec:
replicas: 1
tls:
secretName: tls-secret

客户端和 RabbitMQ 之间的相互 TLS 加密

相互 TLS (mTLS) 通过要求服务器验证客户端的身份来增强 TLS,此外客户端还验证服务器,这在 TLS 加密中已经发生。为了进行这种相互验证,客户端和服务器都必须配置证书和密钥对,客户端对由服务器信任的 CA 签名,服务器对由客户端信任的 CA 签名。相互验证过程如下图所示

Mutual verification process

除了支持 TLS 所需的配置之外,配置相互 TLS 还要求 RabbitMQ 集群配置用于签署客户端证书和密钥对的 CA 证书 ca.pem。使用密钥 ca.crt 创建一个包含此密钥的 Kubernetes 密钥

kubectl create secret generic ca-secret --from-file=ca.crt=ca.pem

或使用 Cert Manager 等工具创建此密钥。

此密钥和 tls-secret 存在后,可以按照mTLS 示例部署 RabbitMQ 集群。

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: mtls
spec:
replicas: 1
tls:
secretName: tls-secret
caSecretName: ca-secret

为了强制执行客户端验证,RabbitMQ 必须配置为拒绝未提供证书的客户端。这可以通过在附加配置中使用 ssl_options.fail_if_no_peer_cert 选项启用TLS 对等验证来完成

spec:
rabbitmq:
additionalConfig: |
ssl_options.fail_if_no_peer_cert = true

查找您的 RabbitmqCluster 服务名称和管理员凭据

如果应用程序部署在与 RabbitMQ 相同的 Kubernetes 集群中,则可以使用 RabbitmqCluster 服务名称和管理员凭据将此类应用程序连接到 RabbitMQ。建立该连接所需的步骤因部署而异,并且超出本文档的范围。

请按照以下步骤查找您的 RabbitmqCluster 服务名称和管理员凭据。

查找您的 RabbitmqCluster 服务名称

用于访问 RabbitMQ Pod 的服务显示在自定义资源状态字段中,作为 status.serviceReference。此字段显示服务名称和命名空间。以下命令显示了如何获取此信息

kubectl get rabbitmqcluster INSTANCE \
-ojsonpath='Name: {.status.admin.serviceReference.name} -- Namespace: {.status.admin.serviceReference.namespace}'

其中 INSTANCERabbitmqCluster 资源的名称。

有关如何使用服务连接的更多信息,请查看Kubernetes 文档中关于服务 DNS 的内容。

检索您的 RabbitMQ 管理员凭据

RabbitmqCluster 的管理员凭据存储在名为 INSTANCE-default-user 的 Kubernetes 密钥中,其中 INSTANCERabbitmqCluster 对象的名称。Kubernetes 使用 base64 编码密钥。

密钥的名称和命名空间也存在于自定义资源状态中。要检索密钥名称,请运行 kubectl get rabbitmqcluster INSTANCE -ojsonpath='{.status.defaultUser.secretReference.name}'

要检索凭据并以明文显示它们,首先通过运行以下命令显示用户名

kubectl -n NAMESPACE get secret INSTANCE-default-user -o jsonpath="{.data.username}" | base64 --decode

其中

  • INSTANCE 是您的 RabbitmqCluster 的名称
  • NAMESPACE 是包含 RabbitmqCluster 的 Kubernetes 命名空间

接下来,通过运行以下命令显示密码

kubectl -n NAMESPACE get secret INSTANCE-default-user -o jsonpath="{.data.password}" | base64 --decode

(可选) 使用 HashiCorp Vault

RabbitMQ 集群运算符支持将 RabbitMQ 管理员凭据和 RabbitMQ 服务器证书存储在HashiCorp Vault中。

请注意,运算符仅适用于 Vault KV 密钥引擎版本 2

从 Vault 读取 RabbitMQ 管理员凭据

您可以配置 RabbitmqCluster 从 Vault 读取 RabbitMQ 管理员凭据,而不是让运算符创建 RabbitMQ 管理员凭据并将它们放入 Kubernetes 密钥对象中,如检索您的 RabbitMQ 管理员凭据中所述。为此,请按照vault-default-user 示例配置 Vault 密钥后端

spec:
secretBackend:
vault:
role: rabbitmq
# Optionally, set Vault annotations as listed in
# https://www.vaultproject.io/docs/platform/k8s/injector/annotations
annotations:
vault.hashicorp.com/template-static-secret-render-interval: "15s"
defaultUserPath: secret/data/rabbitmq/config

在创建 RabbitmqCluster 之前,必须已将凭据写入 Vault。如示例中所述,RabbitMQ 管理员密码轮换受支持,无需重新启动 RabbitMQ 服务器。

从 Vault 发行 RabbitMQ 服务器证书

要配置 TLS,而不是提供包含 RabbitMQ 服务器私钥、证书和证书颁发机构的 Kubernetes 密钥对象,如TLS 配置中所述,您可以配置 RabbitmqCluster 以在每次 RabbitMQ Pod(重新)启动时从Vault PKI 密钥引擎请求新的短期服务器证书。为此,请按照vault-tls 示例配置 vault 密钥后端

spec:
secretBackend:
vault:
role: rabbitmq
tls:
pkiIssuerPath: pki/issue/cert-issuer

RabbitMQ 服务器私钥永远不会存储在 Vault 中。

验证实例正在运行

部署 RabbitMQ 吞吐量测试工具 PerfTest 以快速验证您的实例是否正常运行。有关更多信息,请参阅 GitHub 上的PerfTest

注意:如果以下命令从创建 RabbitmqCluster 对象的命名空间外部执行,请将 -n NAMESPACE 添加到以下 kubectl 命令中。

要安装并运行 PerfTest,请运行以下命令

instance=INSTANCE-NAME
username=$(kubectl get secret ${instance}-default-user -o jsonpath="{.data.username}" | base64 --decode)
password=$(kubectl get secret ${instance}-default-user -o jsonpath="{.data.password}" | base64 --decode)
service=${instance}
kubectl run perf-test --image=pivotalrabbitmq/perf-test -- --uri "amqp://${username}:${password}@${service}"

要验证 PerfTest 是否正在通过运行发送和接收消息

kubectl logs -f perf-test

日志显示如下例所示

kubectl logs -f perf-test
# id: test-104555-858, starting consumer #0
# id: test-104555-858, starting consumer #0, channel #0
# id: test-104555-858, starting producer #0
# id: test-104555-858, starting producer #0, channel #0
# id: test-104555-858, time: 1.000s, sent: 19057 msg/s, received: 11768 msg/s, min/median/75th/95th/99th consumer latency: 4042/140608/190841/251618/258979 micro-s
# id: test-104555-858, time: 2.000s, sent: 24020 msg/s, received: 16283 msg/s, min/median/75th/95th/99th consumer latency: 222998/507432/642110/754038/776600 micro-s

要删除 PerfTest 实例,请使用

kubectl delete pod perf-test

在您的应用中使用 RabbitMQ 服务

有关如何开始使用您的应用程序的信息,请参阅RabbitMQ 教程以及有关连接发布者消费者的指南。

监控 RabbitMQ 集群

对于生产系统,启用 RabbitMQ 集群监控至关重要。

请参阅在 Kubernetes 中监控 RabbitMQ,了解 Kubernetes 部署的集群的推荐监控选项。

使用网络策略限制流量

网络策略类似于防火墙,允许您在 IP 地址或端口级别限制对 RabbitmqCluster 中 Pod 的流量。这在生产集群中可能值得一做,例如,确保只有 RabbitmqCluster 中的 Pod 可以访问节点间通信端口(epmd 和集群),或限制消息传递流量仅允许来自已知可信客户端 Pod。

集群操作符存储库具有一个有文档记录的示例,其中包含几个示例 NetworkPolicies,您可以将其用作定义您自己的安全网络拓扑的指南。

删除 RabbitMQ 实例

要删除 RabbitMQ 服务实例,请运行

kubectl delete rabbitmqcluster INSTANCE

其中 INSTANCE 是您的 RabbitmqCluster 的名称,或使用

kubectl delete -f INSTANCE.yaml

暂停 RabbitMQCluster 的协调

可以暂停 RabbitMQ 实例的协调:这将阻止集群操作符监视和更新实例。为此,请在您的 RabbitmqCluster 上设置一个特殊的标签“rabbitmq.com/pauseReconciliation=true”。

如果您希望升级到新版本的集群操作符,但又不想让操作符开始更新某些 RabbitmqCluster,则可以使用此功能。请注意,暂停协调意味着操作符将不会监视此 RabbitmqCluster,直到删除特殊标签。操作符将忽略对已暂停的 RabbitmqCluster 的任何更新,并且如果您意外删除了 RabbitmqCluster 的子资源(例如 Stateful Set 或 Service 对象),则不会自动重新创建已删除的对象。除非绝对必要,否则我们不建议使用此功能。

要暂停协调,请通过运行设置标签

kubectl label rabbitmqclusters INSTANCE-NAME rabbitmq.com/pauseReconciliation=true

其中 INSTANCE 是您的 RabbitmqCluster 的名称。

要恢复协调,请通过运行删除标签

kubectl label rabbitmqclusters INSTANCE-NAME rabbitmq.com/pauseReconciliation-

配置操作符的日志级别

操作符记录协调结果和错误。操作符日志可以通过 kubectl -n rabbitmq-system logs -l app.kubernetes.io/name=rabbitmq-cluster-operator 进行检查。它使用 zap 日志记录器,可以通过在操作符部署清单中传递命令行标志来配置。

例如,要将日志级别配置为“调试”

apiVersion: apps/v1
kind: Deployment
metadata:
name: rabbitmq-cluster-operator
namespace: rabbitmq-system
spec:
template:
spec:
containers:
- args:
- --zap-log-level=debug
command:
- /manager

zap 日志记录器的其他可用命令行标志可以在控制器运行时中找到。

© 2024 RabbitMQ. All rights reserved.