使用 RabbitMQ 消息拓扑 Kubernetes 运算符
使用此信息了解如何部署将由消息拓扑运算符管理的自定义资源对象。
如何使用 RabbitMQ 消息拓扑运算符
如果未安装 RabbitMQ 消息拓扑运算符,请参阅快速入门信息以部署它。
此信息包括以下部分
- 集群运算符要求
- 跨多个命名空间的范围
- 非运算符管理的 RabbitMQ
- 自定义连接 URI
- 队列和策略
- 用户和用户权限
- 交换机和绑定
- 虚拟主机
- 联合
- 转储
- 更新资源
- 删除资源
- 限制
- TLS
- 使用 HashiCorp Vault
- 配置运算符的日志级别
- 基于时间协调
注意:有关在 Openshift 上使用运算符的其他信息,请参阅在 Openshift 上使用 RabbitMQ Kubernetes 运算符。
RabbitMQ 集群运算符要求
- 消息拓扑运算符可与使用 Kubernetes 集群运算符部署的 RabbitMQ 集群一起使用。集群运算符所需的最低版本为
1.7.0
。 - 消息拓扑运算符自定义资源只能在与 RabbitMQ 集群部署相同的命名空间中创建。对于在命名空间“my-test-namespace”中部署的 RabbitmqCluster,此 RabbitMQ 集群的所有消息拓扑自定义资源(例如
queues.rabbitmq.com
和users.rabbitmq.com
)只能在命名空间“my-test-namespace”中创建。
跨多个命名空间的范围
消息拓扑运算符可以在任何命名空间中协调其对象。但是,默认情况下,它会将其交互限制在与拓扑对象(例如 Queue
)相同的命名空间中的 RabbitmqCluster
对象中。换句话说,消息拓扑运算符将协调命名空间 default
中的 Queue
对象,仅当 RabbitmqCluster
对象也在命名空间 default
中时。
这是默认行为,可以对其进行自定义以允许特定的命名空间列表进行协调。要创建允许的命名空间列表,必须使用键 rabbitmq.com/topology-allowed-namespaces
和值(一个逗号分隔的命名空间名称列表,不带空格)注释 RabbitmqCluster
对象;例如 default,ns1,my-namespace
。值星号 *
可用于允许所有命名空间。
任何拓扑对象都可以声明为使用 .spec.rabbitmqClusterReference.namespace
针对不同命名空间中的 RabbitmqCluster
。与 RabbitmqCluster
相同命名空间内的拓扑对象始终被允许。
以下 YAML 声明了一个允许来自命名空间 my-app
的拓扑对象的 RabbitmqCluster
对象
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: example-rabbit
namespace: rabbitmq-service
annotations:
rabbitmq.com/topology-allowed-namespaces: "my-app"
spec:
replicas: 1
请注意,以上 YAML 指定了命名空间 rabbitmq-service
。然后,以下 YAML 将从命名空间 my-app
针对上述 RabbitMQ。
apiVersion: rabbitmq.com/v1beta1
kind: Queue
metadata:
name: test # name of this custom resource; does not have to the same as the actual queue name
namespace: my-app
spec:
name: test-queue # name of the queue
rabbitmqClusterReference:
name: example-rabbit
namespace: rabbitmq-service
关于禁止跨命名空间对象的重要信息
如果拓扑对象(例如 Queue
)针对 RabbitmqCluster
,并且此类 RabbitmqCluster
不允许来自拓扑对象命名空间的请求,则会创建带有错误消息的状态条件,并且该对象不会被协调,直到它被更新。
例如,命名空间 ns1
中的 RabbitmqCluster
允许来自 my-app
的拓扑,并且命名空间 not-allowed
中的拓扑对象 Queue
针对上述 RabbitmqCluster
,消息拓扑运算符将记录错误消息,更新 Queue
对象中的状态条件,并放弃协调 Queue
对象。如果 RabbitmqCluster
对象更新为允许来自命名空间 not-allowed
的拓扑对象,则必须手动更新 Queue
对象以触发协调;例如,通过向 Queue
对象添加标签。
非运算符管理的 RabbitMQ
- 对于任何不是由集群运算符部署的 RabbitMQ,都可以提供连接密钥以创建 RabbitMQ 拓扑对象。
- 此功能自消息拓扑运算符
1.4.0
起发布。
请注意,spec.rabbitmqClusterReference
是一个不可变字段。例如,一旦创建,就不能更新 connectionSecret
名称
以下清单创建了一个队列,并使用 kubernetes 密钥 my-rabbit-creds
中的凭据连接到 RabbitMQ 服务器
---
apiVersion: v1
kind: Secret
metadata:
name: my-rabbit-creds
type: Opaque
stringData:
# has to be an existing user
username: a-user
password: a-secure-password
# uri for the management api; when no scheme is provided in the uri, 'http' will be used by default
uri: https://my.rabbit:15672
---
apiVersion: rabbitmq.com/v1beta1
kind: Queue
metadata:
name: qq-example
spec:
name: my-queue
rabbitmqClusterReference:
connectionSecret:
# has to be an existing secret in the same namespace as this Queue object
name: my-rabbit-creds
- 如果设置了
rabbitmqClusterReference.namespace
,则将使用该命名空间中的密钥
---
apiVersion: v1
kind: Secret
metadata:
name: my-rabbit-creds
namespace: rabbitmq-system
annotations:
# has to be "*" or match namespace name(s) where RabbitMQ objects are deployed
rabbitmq.com/topology-allowed-namespaces: "qq-namespace"
type: Opaque
stringData:
# has to be an existing user
username: a-user
password: a-secure-password
# uri for the management api; when no scheme is provided in the uri, 'http' will be used by default
uri: https://my.rabbit:15672
---
apiVersion: rabbitmq.com/v1beta1
kind: Queue
metadata:
name: qq-example
namespace: qq-namespace
spec:
name: my-queue
rabbitmqClusterReference:
namespace: rabbitmq-system
connectionSecret:
# has to be an existing secret in the namespace specified in rabbitmqClusterReference.namespace
name: my-rabbit-creds
请注意,spec.rabbitmqClusterReference
是一个不可变字段。例如,一旦创建,就不能更新 connectionSecret
名称。
自定义连接 URI
- 对于无法通过其 Kubernetes 服务对象连接的 RabbitmqClusters(例如,如果 TLS 证书是为自定义域而不是 Kubernetes 服务生成的),您可以使用自定义连接 URI 注释 Rabbitmqclusters。消息拓扑运算符将使用提供的信息进行连接,而不是 Kubernetes dns。
- 此功能自消息拓扑运算符
1.12.0
起发布。
要注释 RabbitmqClusters,
kubectl annotate rmq RMQ-NAME rabbitmq.com/operator-connection-uri=https://test:1234
队列和策略
消息拓扑运算符可以在 RabbitMQ 集群中声明队列和策略。
以下清单将在默认 vhost 中创建一个名为“test”的队列
apiVersion: rabbitmq.com/v1beta1
kind: Queue
metadata:
name: test # name of this custom resource; does not have to the same as the actual queue name
namespace: rabbitmq-system
spec:
name: test # name of the queue
autoDelete: false
durable: true
rabbitmqClusterReference:
name: example-rabbit
以下清单将在默认虚拟主机中创建一个名为“lazy-queue”的策略
apiVersion: rabbitmq.com/v1beta1
kind: Policy
metadata:
name: policy-example # name of this custom resource
namespace: rabbitmq-system
spec:
name: lazy-queue
pattern: "^lazy-queue-" # matches any queue begins with "lazy-queue-"
applyTo: "queues"
definition:
queue-mode: lazy
rabbitmqClusterReference:
name: example-rabbit
请注意,不建议直接在队列上设置可选队列参数。一旦设置,队列属性将无法更改。请改用策略。
交换机和绑定
消息拓扑运算符可以管理交换机和绑定。以下清单将创建一个扇出交换机
apiVersion: rabbitmq.com/v1beta1
kind: Exchange
metadata:
name: fanout
namespace: rabbitmq-system
spec:
name: fanout-exchange # name of the exchange
type: fanout # default to 'direct' if not provided; can be set to 'direct', 'fanout', 'headers', and 'topic'
autoDelete: false
durable: true
rabbitmqClusterReference:
name: example-rabbit
以下清单将在交换机和队列之间创建一个绑定
apiVersion: rabbitmq.com/v1beta1
kind: Binding
metadata:
name: binding
namespace: rabbitmq-system
spec:
source: test # an existing exchange
destination: test # an existing queue
destinationType: queue # can be 'queue' or 'exchange'
rabbitmqClusterReference:
name: example-rabbit
用户和用户权限
您可以使用消息拓扑运算符创建 RabbitMQ 用户并分配用户权限。在访问控制指南中了解有关用户管理的更多信息。
消息拓扑运算符默认情况下使用生成的凭据创建用户。
以下清单将创建一个用户,并使用生成的用户名和密码,可以通过 Kubernetes 密钥对象访问生成的用户名和密码
apiVersion: rabbitmq.com/v1beta1
kind: User
metadata:
name: user-example
namespace: rabbitmq-system
spec:
tags:
- policymaker
rabbitmqClusterReference:
name: example-rabbitmq
要获取包含生成的用户名和密码的 kubernetes 密钥对象的名称,请运行以下命令
kubectl get users.rabbitmq.com user-example -o jsonpath='{.status.credentials.name}'
请注意,运算符不监视生成的密钥对象,更新密钥对象不会更新凭据。作为解决方法,请向 users.rabbitmq.com
对象添加标签或注释以触发运算符进行协调。
运算符还支持使用提供的凭据创建 RabbitMQ 用户。在使用提供的用户名和密码创建用户时,请创建一个 kubernetes 密钥对象,在其 Data 字段中包含键 username
和 password
。运算符不监视提供的密钥对象,更新密钥对象不会更新凭据。作为解决方法,请向 users.rabbitmq.com
对象添加标签或注释以触发运算符进行协调。
以下清单将使用来自密钥“my-rabbit-user”的用户名和密码创建一个用户
apiVersion: rabbitmq.com/v1beta1
kind: User
metadata:
name: import-user-sample
spec:
tags:
- policymaker
- monitoring # other available tags are 'management' and 'administrator'
rabbitmqClusterReference:
name: rabbit-example
importCredentialsSecret:
name: my-rabbit-user # name of the secret
要在现有用户上设置用户权限,请创建 permissions.rabbitmq.com
资源。以下示例将向用户 rabbit-user-1
分配权限
apiVersion: rabbitmq.com/v1beta1
kind: Permission
metadata:
name: rabbit-user-1-permission
namespace: rabbitmq-system
spec:
vhost: "/"
user: "rabbit-user-1" # name of the RabbitMQ user
permissions:
write: ".*"
configure: ".*"
read: ".*"
rabbitmqClusterReference:
name: sample
虚拟主机
消息拓扑运算符可以创建虚拟主机。
以下清单将在名为“example-rabbit”的 RabbitmqCluster 中创建一个名为“test”的 vhost
apiVersion: rabbitmq.com/v1beta1
kind: Vhost
metadata:
name: test-vhost # name of this custom resource
namespace: rabbitmq-system
spec:
name: test # name of the vhost
rabbitmqClusterReference:
name: example-rabbit
联合
消息拓扑运算符可以定义联合上游。
因为联合上游 URI 包含凭据,所以它是通过 Kubernetes 密钥对象提供的。密钥 uri
对密钥对象是必需的。其值可以是单个 URI 或 URI 的逗号分隔列表。
以下清单将在名为“example-rabbit”的 RabbitmqCluster 中定义一个名为“origin”的上游
apiVersion: rabbitmq.com/v1beta1
kind: Federation
metadata:
name: federation-example
namespace: rabbitmq-system
spec:
name: "origin"
uriSecret:
# secret must be created in the same namespace as this Federation object; in this case 'rabbitmq-system'
name: {secret-name}
ackMode: "on-confirm"
rabbitmqClusterReference:
name: example-rabbit
更多联合示例。
转储
消息拓扑运算符可以声明动态转储。
转储源和目标 URI 通过 Kubernetes 密钥对象提供。密钥对象必须包含两个键“srcUri”和“destUri”,每个键的值可以是单个 URI 或 URI 的逗号分隔列表。
以下清单将在名为“example-rabbit”的 RabbitmqCluster 中创建一个名为“my-shovel”的转储
apiVersion: rabbitmq.com/v1beta1
kind: Shovel
metadata:
name: shovel-example
namespace: rabbitmq-system
spec:
name: "my-shovel"
uriSecret:
# secret must be created in the same namespace as this Shovel object; in this case 'rabbitmq-system'
name: {secret-name}
srcQueue: "the-source-queue"
destQueue: "the-destination-queue"
rabbitmqClusterReference:
name: example-rabbit
更多转储示例。
更新资源
某些自定义资源属性是不可变的。消息拓扑操作符实现了验证 Webhook 以防止更新不可变字段。禁止的更新将被拒绝。例如
kubectl apply -f test-queue.yaml
Error from server (Forbidden):
...
Resource: "rabbitmq.com/v1beta1, Resource=queues", GroupVersionKind: "rabbitmq.com/v1beta1, Kind=Queue"
Name: "example", Namespace: "rabbitmq-system"
for: "test-queue.yaml": admission webhook "vqueue.kb.io" denied the request: Queue.rabbitmq.com "example" is forbidden: spec.name: Forbidden: updates on name, vhost, and rabbitmqClusterReference are all forbidden
无法更新的属性在消息拓扑操作符 API 文档中进行了说明。
删除资源
删除自定义资源将删除 RabbitMQ 集群中的相应资源。消息拓扑操作符在所有自定义资源上设置 Kubernetes 终结器。如果对象已在 RabbitMQ 集群中删除,或者 RabbitMQ 集群已被删除,消息拓扑操作符将删除自定义资源,而不会尝试删除 RabbitMQ 对象。
限制
消息拓扑操作符不适用于使用导入定义部署的 RabbitmqCluster。操作符读取 RabbitmqCluster 状态status.binding
中设置的默认用户密钥,如果 RabbitmqCluster 使用导入定义部署,则定义将覆盖默认用户凭据,并可能导致消息拓扑操作符无法访问 RabbitmqCluster。要解决此问题,您可以创建一个不使用导入定义的 RabbitmqCluster,或者您可以手动将默认用户 Kubernetes 密钥更新为定义中设置的实际用户凭据。
TLS
如果由消息拓扑操作符管理的 RabbitmqClusters 配置为通过 HTTPS 提供管理服务,则需要执行一些其他步骤来配置消息拓扑操作符。请遵循此TLS 专用指南来配置操作符。
(可选) 使用 HashiCorp Vault
如果由消息拓扑操作符管理的 RabbitmqClusters 配置为将其默认用户凭据存储在 Vault 中,则需要执行一些其他步骤来配置消息拓扑操作符。请遵循此Vault 专用指南来配置操作符。
配置操作符的日志级别
消息拓扑操作符记录协调结果和错误。可以通过kubectl -n rabbitmq-system logs -l app.kubernetes.io/name=messaging-topology-operator
检查操作符日志。它使用 zap 日志记录器,可以通过在操作符部署清单中传递命令行标志来配置。
例如,要将日志级别配置为“调试”
apiVersion: apps/v1
kind: Deployment
metadata:
name: messaging-topology-operator
namespace: rabbitmq-system
spec:
template:
spec:
containers:
- args:
- --zap-log-level=debug
command:
- /manager
zap 日志记录器的其他可用命令行标志在控制器运行时中进行了说明。
基于时间的协调
默认情况下,消息拓扑操作符在特定自定义资源存在创建/更新/删除事件时协调拓扑对象。从版本1.6.0
开始,您可以通过在操作符部署中设置环境变量来配置操作符以特定频率对所有拓扑对象执行协调
apiVersion: apps/v1
kind: Deployment
metadata:
[...]
name: messaging-topology-operator
namespace: rabbitmq-system
spec:
template:
spec:
containers:
- command:
- /manager
env:
- name: SYNC_PERIOD
value: 5m # needs to be in a format that's readable by golang time.ParseDuration(), e.g. “1000s”, “5.3h” or “20h35m”
...
重新创建已删除的队列**不会恢复任何消息**。
请注意,此频率适用于操作符管理的所有拓扑对象。根据您使用拓扑操作符创建的对象数量,以特定频率协调所有对象可能会对操作符和 RabbitMQ 服务器造成不必要的负载。仅当您的用例需要基于时间的协调时才使用此功能。