使用 RabbitMQ Cluster Kubernetes Operator
如何使用 RabbitMQ Cluster Kubernetes Operator
使用此信息了解如何部署由 RabbitMQ Cluster Kubernetes Operator 管理的自定义资源对象。
如果此时未安装 RabbitMQ Cluster Kubernetes Operator,请参阅 安装 Kubernetes 集群中的 RabbitMQ Cluster Operator。有关快速入门的说明,请参阅 快速入门 信息。
以下信息分为以下几个部分
- 确认服务可用性
- 应用 Pod 安全策略
- 创建 RabbitMQ 实例
- 现有示例
- 配置 RabbitMQ 实例
- 更新 RabbitMQ 实例
- 设置 Pod 中断预算
- 配置 TLS
- 查找您的 RabbitmqCluster 服务名称和管理员凭据
- 使用 HashiCorp Vault
- 验证实例是否正在运行
- 在您的应用程序中使用 RabbitMQ 服务
- 监控 RabbitMQ 集群
- 使用网络策略限制流量
- 删除 RabbitMQ 实例
- 暂停 RabbitMQ 实例的协调
- 配置 Operator 的日志级别
有关在 Openshift 上使用 RabbitMQ Cluster Kubernetes Operator 的更多信息,请参阅 在 Openshift 上使用 RabbitMQ Kubernetes Operator。
确认服务可用性
在配置应用程序使用 RabbitMQ Cluster Kubernetes Operator 之前,请确保 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 文档。如果使用 Role 和 RoleBinding,则仅在部署了 RBAC 的命名空间中有效。
如果未启用 Pod 安全策略,请跳至下面的 创建 RabbitMQ 实例。
应在创建 RabbitmqCluster 实例之前创建 Role 和 RoleBinding。可以创建引用不存在的服务帐户或用户的绑定。Operator 会使用 INSTANCE-NAME-server 模式创建服务帐户。例如,名为“mycluster”的 RabbitmqCluster 将生成一个名为 mycluster-server 的服务帐户。为了允许服务帐户使用 PSP,必须将具有“use”动词的 Role 绑定到服务帐户。例如
# 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 Cluster Kubernetes Operator 在定义 RabbitmqCluster 的同一命名空间中创建必要的资源,如 Services 和 StatefulSet。
首先,创建一个 YAML 文件来定义一个名为 definition.yaml 的 RabbitmqCluster 资源。
YAML 文件可以有任何名称,但后续步骤假定其名称为 definition。
然后复制并粘贴以下片段到文件中并保存
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: definition
在 Openshift 上创建 RabbitmqClusters 时,所有 RabbitmqCluster manifest 都必须添加额外的参数。有关详细信息,请参阅 支持任意用户 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 文档指南。
内部标签和注释
Cluster Operator 创建的子资源始终具有以下一组标签
app.kubernetes.io/name- 该值是与资源关联的RabbitmqCluster名称。app.kubernetes.io/component- 所属的组件。目前始终设置为rabbitmq。app.kubernetes.io/part-of- 该资源所属的更高级别应用程序的名称。目前始终设置为rabbitmq。
相同的标签集应用于 StatefulSet 创建的 Pod。
现有示例
在 GitHub 仓库 中有一些常见用例的示例。一些有趣的用例包括
- 如何在 RabbitMQ 中使用 Operator 导入 definitions 文件
- 如何配置 RabbitMQ 的内存和 CPU 限制
- 生产环境就绪示例,已在 Google Cloud Platform 中测试,是一个很好的起点。
还有更多 可用示例。
配置 RabbitMQ 实例
要配置 RabbitMQ 实例,请打开 definition.yaml 或通过运行以下命令就地编辑配置
kubectl edit rabbitmqcluster definition
接下来,添加下面描述的任何属性及其值。下面列出的每个属性都是可选的。
Operator 仓库在 GitHub 上提供了 许多配置示例。
标签和注释
描述:RabbitmqCluster 元数据中的标签和注释会传播到 Operator 创建的资源。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
自 v2.16.0 起,可以缩减到零。无法向下缩减。只允许缩减到零,然后缩减回原始数量。一个潜在的用例是节省预期不活动时期(例如周末)的资源。缩减到零时,所有数据都会保留。
镜像
描述:指定 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 名称数组。如果注册表需要身份验证,此数组必须包含用于拉取镜像的 Secret 的名称。可以通过运行以下命令创建 Kubernetes Secret:
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 Cluster Kubernetes Operator 目前不支持 ExternalName 服务类型。
默认值:ClusterIP
示例
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
service:
type: LoadBalancer
Service Annotations
描述:为 RabbitmqCluster 服务指定 Kubernetes 服务注释。RabbitMQ Cluster Kubernetes Operator 创建的服务将具有这些注释。
默认值: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 服务的持久性设置。
如果您的集群没有默认的 StorageClass,则必须设置此属性,否则 RabbitMQ Pod 将不会被调度,因为它们需要持久卷。
可用设置包括
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
有关上面提到的概念的更多信息,请参阅
| 概念 | 更多信息请参阅… |
|---|---|
| StorageClass | Kubernetes 文档 |
| 持久卷容量 | The 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.6 倍(旧版 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 终止。
为防止这种情况发生,集群 Operator 会设置 20% 的内存余量(最大值为 2GB),通过配置 total_memory_available_override_value。这意味着 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 Tolerations
描述:为 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 附加配置
描述:附加的 RabbitMQ 配置选项,将写入 /etc/rabbitmq/conf.d/90-userDefinedConfiguration.conf。RabbitMQ Cluster Kubernetes Operator 会生成一个配置文件 /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 Operator 默认启用了 rabbitmq_peer_discovery_k8s、rabbitmq_prometheus 和 rabbitmq_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 并挂载到 RabbitMQ 容器中,路径为 /etc/rabbitmq/erl_inetrc。
此字段在 Cluster Operator 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 验证对等证书 against a provided CA certificate。客户端也可以这样做,因此对等验证可以是双向的(“mTLS”)。此证书必须存储在名为 spec.tls.caSecretName 的 Secret 中,位于与 RabbitmqCluster 对象相同的命名空间中。请注意,这可以是与 spec.tls.secretName 相同的 Secret。此 Secret 必须有一个名为 ca.crt 的键,其中包含 CA 证书。
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
自动启用功能标志(版本 2.15.0 中添加)
描述:设置为 true 时,Operator 将在每次更新集群时运行 rabbitmqctl enable_feature_flag all。这将自动启用所有 功能标志。请注意,一旦启用,功能标志就无法禁用。将此选项保留为 false 可以更好地控制何时启用功能标志,但需要 升级后的手动步骤。
默认值:false
示例
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmqcluster-sample
spec:
autoEnableAllFeatureFlags: true
跳过部署后步骤
描述:如果未设置或设置为 false,Operator 将在每次更新集群时运行 rabbitmq-queues rebalance all。设置为 true 时,Operator 将跳过运行 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
覆盖资源属性
描述:谨慎使用!通过覆盖属性或提供其他设置来定制 Operator 创建的资源。这是一个高级功能,允许您启用未明确支持的功能,但如果使用不当,很容易使 RabbitMQ 集群无法使用。您可以定制 StatefulSet 和客户端应用程序使用的 Service。spec.override.statefulSet 和 spec.override.service 的值应分别匹配 StatefulSet 对象 和 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_NAME、MY_POD_NAMESPACE 和 K8S_SERVICE_NAME 变量来访问容器元数据。例如
- name: MY_VARIABLE
value: test-$(MY_POD_NAME).$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE)
更新 RabbitMQ 实例
可以为现有 RabbitMQ 实例添加、更改或删除 RabbitmqCluster 对象中的属性。
如果移除一个属性,它将恢复到其默认值(如果存在)。要查看默认值,请参阅上面的 配置 RabbitMQ 实例。
配置项在下表中列出。
| 自定义资源属性 | 描述 |
|---|---|
metadata.labels | 这些是添加到每个子资源(如 StatefulSet 和 Service)的标签。以 |
metadata.annotations | 这些是添加到每个子资源(如 StatefulSet 和 Service)的注释。 |
spec.image | RabbitMQ 镜像引用。 |
spec.replicas | RabbitMQ 节点的副本数量。强烈不建议使用偶数,并强烈建议使用奇数。 |
spec.imagePullSecrets | 用于访问包含 RabbitMQ 镜像的注册表的 Kubernetes Secret 名称数组。仅当使用私有注册表时才需要。 |
spec.service.type | RabbitmqCluster 服务的 Kubernetes 服务类型。必须是 ClusterIP、NodePort 或 LoadBalancer。 |
spec.service.annotations | 这些是服务的注释。请注意,包含 |
spec.persistence.storage | 持久卷的容量,表示为 Kubernetes 资源数量。设置为 |
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 必须存在并包含 |
spec.tls.caSecretName | 用于配置 RabbitMQ mTLS(用于验证客户端证书)的 Secret 名称。Secret 必须存在并包含 |
spec.tls.disableNonTLSListeners | 设置为 |
spec.rabbitmq.additionalPlugins | 要在 RabbitMQ 中启用的插件列表。默认情况下,RabbitMQ Cluster Kubernetes Operator 启用 Prometheus、K8s Peer Discovery 和 Management 插件。 |
spec.rabbitmq.additionalConfig | 附加配置,将附加到集群生成的配置。请参阅 附加配置 部分,了解始终生成的配置列表。 |
spec.rabbitmq.advancedConfig | RabbitMQ |
spec.override | RabbitMQ Cluster Kubernetes Operator 创建的资源的任意覆盖。此功能应极其谨慎使用,因为覆盖关键属性可能会导致 RabbitMQ 集群无法供应用程序使用或无法被 Operator 访问。请参阅 覆盖部分 以了解更多信息。 |
有关 CPU 单位、Kubernetes 调度器和 CPU 时间可用性的更多信息,请参阅 Kubernetes 计算资源指南。
有关 Pod 亲和性和反亲和性规则的更多信息,请参阅 Kubernetes 亲和性规则指南。
要更新 RabbitMQ 实例
- 打开
definition.yaml。 - 添加或修改表中列出的任何属性。
- 保存对
definition.yaml的更改。 - 通过运行以下命令应用定义:
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
有关上面提到的概念的更多信息,请参阅
| 概念 | 更多信息请参阅… |
|---|---|
| PDBs | The Kubernetes 文档 |
| 自愿和非自愿中断 | The Kubernetes 文档 |
| 暂停少数模式 | RabbitMQ 文档 |
(可选) 配置 TLS
传输层安全 (TLS) 是一种用于加密网络流量的协议。RabbitMQ 支持 TLS,并且集群 Operator 简化了使用 TLS 或 双向 TLS (mTLS) 加密流量配置 RabbitMQ 集群的过程,并支持 使用 mTLS 加密 RabbitMQ 节点间流量。 TLS 基础概述 有助于理解本指南。
TLS 加密客户端与 RabbitMQ 之间的流量
为了加密客户端与 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.localmyrabbit-server-1.myrabbit-nodes.mynamespace.svc.cluster.localmyrabbit-server-2.myrabbit-nodes.mynamespace.svc.cluster.localmyrabbit.mynamespace.svc.cluster.local
请注意,最后一个 SAN 属性是客户端服务 DNS 名称。根据使用的服务类型 (spec.service.type),可能需要其他 SAN 属性。例如,如果使用 NodePort 服务类型,SAN 必须包含每个 Kubernetes 节点的外部 IP 地址。
要启用 TLS,请创建一个包含 PEM 编码的服务器证书 server.pem 和私钥 server-key.pem 的 Kubernetes Secret
kubectl create secret tls tls-secret --cert=server.pem --key=server-key.pem
或使用 Cert Manager 等工具生成 TLS Secret。
一旦此 Secret 存在,就可以按照 TLS 示例 部署 RabbitMQ 集群。
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: additional-port
spec:
replicas: 1
tls:
secretName: tls-secret
双向 TLS 加密客户端与 RabbitMQ 之间的流量
双向 TLS (mTLS) 通过要求服务器验证客户端的身份来增强 TLS,这与 TLS 加密中已发生的客户端验证服务器相反。为了进行这种双向验证,客户端和服务器都必须配置证书和密钥对,其中客户端对由服务器信任的 CA 签名,服务器对由客户端信任的 CA 签名。双向验证过程如下图所示

除了 支持 TLS 所需的配置 外,配置双向 TLS 还要求 RabbitMQ 集群配置用于签名客户端证书和密钥对的 CA 证书,即 ca.pem。创建一个包含此 Secret 的键 ca.crt 的 Kubernetes Secret
kubectl create secret generic ca-secret --from-file=ca.crt=ca.pem
或使用 Cert Manager 等工具创建此 Secret。
一旦此 Secret 和 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}'
其中 INSTANCE 是 RabbitmqCluster 资源的名称。
有关如何使用 Services 进行连接的更多信息,请参阅 Kubernetes 文档 中关于 Service DNS 的内容。
检索您的 RabbitMQ 管理员凭据
RabbitmqCluster 的管理员凭据存储在名为 INSTANCE-default-user 的 Kubernetes Secret 中,其中 INSTANCE 是 RabbitmqCluster 对象 的名称。Kubernetes 使用 base64 对 Secret 进行编码。
Secret 的名称和命名空间也存在于自定义资源状态中。要检索 Secret 名称,请运行 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 Cluster Operator 支持将 RabbitMQ 管理员凭据和 RabbitMQ 服务器证书存储在 HashiCorp Vault 中。
请注意,Operator 仅支持 Vault KV secrets engine version 2。
从 Vault 读取 RabbitMQ 管理员凭据
与让 Operator 创建 RabbitMQ 管理员凭据并将其放入 Kubernetes Secret 对象(如 检索您的 RabbitMQ 管理员凭据 中所述)不同,您可以配置 RabbitmqCluster 以从 Vault 读取 RabbitMQ 管理员凭据。为此,请遵循 vault-default-user 示例 并配置 Vault Secret 后端
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 Secret 对象(如 TLS 配置 中所述),您可以配置 RabbitmqCluster 以在每次 RabbitMQ Pod (重新)启动时向 Vault PKI Secrets Engine 请求新的短生命周期服务器证书。为此,请遵循 vault-tls 示例 并配置 vault secret 后端
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 的流量或从 Pod 传出的流量。在生产集群中这样做可能值得,例如,以确保只有 RabbitmqCluster 中的 Pod 才能访问 节点间通信端口(epmd 和集群),或限制消息流量仅允许来自已知受信任的客户端 Pod。
cluster-operator 仓库有 文档化的示例,其中包含几个示例网络策略,您可以将其作为定义自己的安全网络拓扑的指南。
删除 RabbitMQ 实例
要删除 RabbitMQ 服务实例,请运行
kubectl delete rabbitmqcluster INSTANCE
其中 INSTANCE 是您的 RabbitmqCluster 的名称,或者使用
kubectl delete -f INSTANCE.yaml
暂停 RabbitMQCluster 的协调
可以暂停 RabbitMQ 实例的协调:这将阻止集群 Operator 监视和更新实例。为此,请在您的 RabbitmqCluster 上设置特殊标签 "rabbitmq.com/pauseReconciliation=true"。
如果您想升级到新版本的集群 Operator,但又不想让 Operator 开始更新您的某些 RabbitmqCluster,则可以使用此功能。请注意,暂停协调意味着 Operator 将不会监视此 RabbitmqCluster,直到删除特殊标签为止。Operator 将忽略对暂停的 RabbitmqCluster 的任何更新,如果您不小心删除了 RabbitmqCluster 的子资源(例如 Stateful Set 或 Service 对象),则已删除的对象不会自动重新创建。除非绝对必要,否则我们不建议使用此功能。
要暂停协调,请通过运行以下命令设置标签
kubectl label rabbitmqclusters INSTANCE-NAME rabbitmq.com/pauseReconciliation=true
其中 INSTANCE 是您的 RabbitmqCluster 的名称。
要恢复协调,请通过运行以下命令删除标签
kubectl label rabbitmqclusters INSTANCE-NAME rabbitmq.com/pauseReconciliation-
配置 Operator 的日志级别
Operator 会记录协调结果和错误。可以通过 kubectl -n rabbitmq-system logs -l app.kubernetes.io/name=rabbitmq-cluster-operator 来检查 Operator 日志。它使用 zap logger,可以通过在 Operator 部署清单中传递命令行标志来配置。
例如,将日志级别配置为“debug”
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 logger 的其他可用命令行标志可以在 controller runtime 中找到。