使用 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 实例。
Role
和 RoleBinding
应该在创建 RabbitmqCluster
实例之前创建。 创建引用不存在的服务帐户或用户的绑定是可以的。 Operator 使用模式 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 Cluster Kubernetes Operator 在定义 RabbitmqCluster
的同一命名空间中创建必要的资源,例如服务和服务状态集。
首先,创建一个 YAML 文件来定义名为 definition.yaml
的 RabbitmqCluster
资源。
注意: YAML 文件可以有任何名称,但后续步骤假定其名为 definition
。
然后复制并粘贴以下代码段到文件中并保存
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: definition
注意: 在 Openshift 上创建 RabbitmqCluster 时,必须将额外的参数添加到所有 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 文档指南。
内部标签和注解
Cluster Operator 创建的子资源始终具有以下标签集
app.kubernetes.io/name
- 该值是与资源关联的RabbitmqCluster
名称。app.kubernetes.io/component
- 它所属的组件。 当前始终设置为rabbitmq
。app.kubernetes.io/part-of
- 此组件所属的更高级别应用程序的名称。 当前始终设置为rabbitmq
。
相同的标签集也应用于 StatefulSet 创建的 Pod。
现有示例
GitHub 存储库中提供了针对一些常见用例的示例。 一些有趣的用例是
- 如何在使用 Operator 的 RabbitMQ 中导入定义文件
- 如何配置 RabbitMQ 的内存和 CPU 限制
- 生产就绪示例,已在 Google Cloud Platform 中测试,是良好的起点。
还有更多示例可用。
配置 RabbitMQ 实例
要配置 RabbitMQ 实例,请打开 definition.yaml
或通过运行就地编辑配置
kubectl edit rabbitmqcluster definition
接下来,添加下面描述的任何属性及其值。 下面列出的每个属性都是可选的。
配置示例在 GitHub 上的 Operator 存储库中可用。
标签和注解
描述: 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
镜像
描述: 指定 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
服务注解
描述: 指定 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 服务的持久性设置。 可用设置为
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 文档 |
持久卷容量 | Kubernetes 文档 |
Kubernetes 资源数量 | GitHub 中的 Kubernetes 资源模型文档 |
注意: 使用 local-path provisioner 不会强制执行磁盘大小。 这意味着 RabbitMQ 将报告比 .spec.peristence.storage
中配置的更多的可用磁盘空间。 发生这种情况是因为持久磁盘创建为 Kubernetes 节点中托管 Pod 的本地文件夹。
资源要求
描述: 指定 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 终止。 为了防止这种情况发生,集群 operator 通过配置 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 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
。
也可以使 RabbitMQ 针对提供的 CA 证书验证对等证书。 客户端也可以这样做,因此对等验证可以是相互的(“mTLS”)。 此证书必须存储在名为 spec.tls.caSecretName
的 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,则 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 和客户端应用程序使用的服务。 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 | Kubernetes secrets 的名称数组,用于访问包含 RabbitMQ 镜像的注册表。 这仅对于私有注册表是必需的。 |
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 | 用于计算每个 100 毫秒可供 RabbitMQ 容器使用的 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 对等发现和管理插件。 |
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 配置的停机时间,这些配置通常以牺牲可用性为代价来换取数据一致性,例如分区容忍的 pause-minority 模式。
创建 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
有关上述概念的更多信息,请参阅
概念 | 更多信息请参阅… |
---|---|
PDB | Kubernetes 文档 |
自愿和非自愿干扰 | Kubernetes 文档 |
pause-minority 模式 | 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.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 secret,其中包含 PEM 编码的服务器证书 server.pem
和私钥 server-key.pem
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
客户端和 RabbitMQ 之间的相互 TLS 加密
相互 TLS (mTLS) 通过要求服务器验证客户端的身份来增强 TLS,此外客户端验证服务器(这已经在 TLS 加密中发生)。 为了进行此相互验证,必须使用证书和密钥对配置客户端和服务器,其中客户端对由服务器信任的 CA 签名,服务器对由客户端信任的 CA 签名。 相互验证过程如下图所示
除了支持 TLS 所需的配置之外,配置相互 TLS 还需要使用用于签署客户端证书和密钥对的 CA 证书 ca.pem
来配置 RabbitMQ 集群。 创建一个 Kubernetes secret,其键 ca.crt
包含此 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 配置为拒绝不提供证书的客户端。 这可以通过在附加配置中启用 TLS 对等验证 使用 ssl_options.fail_if_no_peer_cert
选项来完成
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
资源的名称。
有关如何使用服务连接的更多信息,请查看有关服务 DNS 的 Kubernetes 文档。
检索您的 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 管理员凭据
您可以配置 RabbitmqCluster 从 Vault 读取 RabbitMQ 管理员凭据,而不是让 Operator 创建 RabbitMQ 管理员凭据并将它们放入 Kubernetes Secret 对象中,如 检索您的 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,您可以配置 RabbitmqCluster 以从 Vault PKI Secrets Engine 请求新的短期服务器证书,而不是像 TLS 配置 中所述提供包含 RabbitMQ 服务器私钥、证书和证书颁发机构的 Kubernetes Secret 对象。为此,请按照 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 的流量。这可能值得在生产集群上执行,例如,以确保只有 RabbitmqCluster 中的 Pod 可以访问 节点间通信端口 (epmd 和集群),或者限制消息流量仅允许来自已知的受信任客户端 Pod。
cluster-operator 仓库中有一个 有文档记录的示例,其中包含多个示例 NetworkPolicy,您可以将其用作定义您自己的安全网络拓扑的指南。
删除 RabbitMQ 实例
要删除 RabbitMQ 服务实例,请运行
kubectl delete rabbitmqcluster INSTANCE
其中 INSTANCE
是您的 RabbitmqCluster 的名称,或者使用
kubectl delete -f INSTANCE.yaml
暂停 RabbitMQCluster 的协调
可以暂停 RabbitMQ 实例的协调:这将阻止 cluster operator 监视和更新实例。为此,请在您的 RabbitmqCluster 上设置一个特殊的标签 "rabbitmq.com/pauseReconciliation=true"。
如果您希望升级到新版本的 cluster 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 中记录的内容。