模式定义导出和导入
概述
节点和集群存储的信息可以被视为模式、元数据或拓扑。用户、vhost、队列、交换器、绑定、运行时参数都属于此类。在 RabbitMQ 的术语中,这些元数据称为**定义 (definitions)**。
定义可以导出到一个文件,然后导入到另一个集群,或用于模式备份或数据初始化。
定义存储在内部数据库中,并在所有集群节点之间复制。集群中的每个节点都有所有定义的副本。当定义的一部分发生更改时,更新将在单个事务中对所有节点执行。这意味着,实际上,可以从任何集群节点导出定义,并获得相同的结果。
VMware Tanzu RabbitMQ 支持温备副本 (Warm Standby Replication) 到远程集群,这使得运行温备集群以进行灾难恢复变得很容易。
在节点启动时导入定义是在部署时预配置节点的推荐方式。
导出定义
定义以 JSON 文件格式导出,有多种方式。
rabbitmqctl export_definitions是唯一不需要启用管理插件 (management plugin) 的选项。rabbitmqadmin definitions export,它使用HTTP API。GET /api/definitionsAPI 端点- 概览页面上有一个定义面板。
定义可以针对特定的虚拟主机 (virtual host) 或整个集群(所有虚拟主机)导出。当仅为单个虚拟主机导出定义时,某些信息(其他虚拟主机的内容或对目标虚拟主机没有任何权限的用户)将从导出的文件中排除。
导出的用户数据包含密码哈希以及密码哈希函数信息。虽然使用 SHA-256 或 SHA-512 等哈希函数进行密码暴力破解并非易事,但用户记录应被**视为敏感信息**。
要使用rabbitmqctl 导出定义,请使用 rabbitmqctl export_definitions。
- 使用 rabbitmqctl (bash)
- 使用 rabbitmqctl (PowerShell)
# Does not require management plugin to be enabled
rabbitmqctl export_definitions /path/to/definitions.file.json
# Does not require management plugin to be enabled
rabbitmqctl.bat export_definitions /path/to/definitions.file.json
rabbitmqadmin export 非常相似,但它使用 HTTP API,并且与旧版本兼容。
- 使用 rabbitmqadmin (bash)
- 使用 rabbitmqadmin (PowerShell)
# Requires management plugin to be enabled
rabbitmqadmin definitions export /path/to/definitions.file.json
# Requires management plugin to be enabled
rabbitmqadmin.exe definitions export /path/to/definitions.file.json
在此示例中,直接使用 GET /api/definitions 端点来导出集群中所有虚拟主机的定义。
# Requires management plugin to be enabled,
# placeholders are used for credentials and hostname.
# Use HTTPS when possible.
curl -u {username}:{password} -X GET http://{hostname}:15672/api/definitions
来自上述 API 端点的响应可以被管道传输到jq 和类似的工具,以便获得更易读的格式。
# Requires management plugin to be enabled,
# placeholders are used for credentials and hostname.
# Use HTTPS when possible.
#
# jq is a 3rd party tool that must be available in PATH
curl -u {username}:{password} -X GET http://{hostname}:15672/api/definitions | jq
导出和转换定义
rabbitmqadmin v2 提供了一种导出定义并将一个或多个标准转换函数应用于结果的方法。
这有助于删除来自 3.13.x 节点的定义集中的经典队列镜像相关密钥(如 ha-mode),或混淆用户名和密码,或完全排除某些定义文件部分。
要指定应用哪些转换,请使用 --transformations 选项,它接受一个由支持的操作名称组成的逗号分隔列表。
下表解释了可用的转换及其作用。
| 转换名称 | 描述 |
|---|---|
strip_cmq_keys_from_policies | 从所有导出的策略中删除所有经典队列镜像相关的密钥(如 ha-mode)。必须紧随 drop_empty_policies,以删除在删除所有经典队列镜像相关的密钥后变得空的(从而在导入时无效)的策略。 |
drop_empty_policies | 在 strip_cmq_keys_from_policies 之后使用,以删除在删除所有经典队列镜像相关的密钥后变得空的(从而在导入时无效)的策略。 |
obfuscate_usernames | 将用户名和密码替换为占位符值。 对于用户名,使用的值是: obfuscated-username-1、obfuscated-username-2 等。对于密码,生成的值是: password-1、password-2 等。此转换会一致地更新用户和权限部分。 |
exclude_users | 从结果中删除所有用户。通常与 exclude_permissions 一起使用。 |
exclude_permissions | 从结果中删除所有权限。通常与 exclude_users 一起使用。 |
exclude_runtime_parameters | 从结果中删除所有运行时参数(包括 Tanzu RabbitMQ 中的联邦上游、Shovel、WSR 和 SDS 设置)。 |
exclude_policies | 从结果中删除所有策略。 |
no_op | 什么都不做。可以用作动态计算的转换列表中的默认值,例如在脚本中。 |
示例
以下命令应用了两个名为 strip_cmq_keys_from_policies 和 drop_empty_policies 的转换,它们将剥离 RabbitMQ 3.13 节点支持的所有经典队列镜像相关策略密钥,然后删除没有任何剩余密钥(导致定义为空)的策略。
# strips classic mirrored queue-related policy keys from the exported definitions, then prints them
# to the standard output stream
rabbitmqadmin definitions export --stdout --transformations strip_cmq_keys_from_policies,drop_empty_policies
以下示例导出了不包含用户和权限的定义。
# removes users and user permissions from the exported definitions, then prints them
# to the standard output stream
rabbitmqadmin definitions export --stdout --transformations exclude_users,exclude_permissions
要导出定义,并将用户名替换为占位符值(用户名:obfuscated-username-1、obfuscated-username-2 等;密码:password-1、password-2 等),请使用 obfuscate_usernames 转换。
rabbitmqadmin definitions export --file /path/to/definitions.file.json --transformations obfuscate_usernames
导入定义
要使用rabbitmqctl 导入定义,请使用 rabbitmqctl import_definitions。
- 使用 rabbitmqctl (bash)
- 使用 rabbitmqctl (PowerShell)
# Does not require management plugin to be enabled
rabbitmqctl import_definitions /path/to/definitions.file.json
# Does not require management plugin to be enabled
rabbitmqctl.bat import_definitions /path/to/definitions.file.json
rabbitmqadmin definitions import 是其 HTTP API 等效命令。
- 使用 rabbitmqadmin (bash)
- 使用 rabbitmqadmin (PowerShell)
# Requires management plugin to be enabled
rabbitmqadmin definitions import /path/to/definitions.file.json
# Requires management plugin to be enabled
rabbitmqadmin.exe definitions import /path/to/definitions.file.json
也可以直接使用 POST /api/definitions API 端点。
# Requires management plugin to be enabled,
# placeholders are used for credentials and hostname.
# Use HTTPS when possible.
curl -u {username}:{password} -H "Content-Type: application/json" -X POST -T /path/to/definitions.file.json http://{hostname}:15672/api/definitions
节点启动时导入定义
定义文件可以在节点启动期间或之后导入。在多节点集群中,启动时导入可能会,并且实际上会在节点启动时执行重复的工作。对于较小的定义文件来说,这不成问题,但对于较大的文件,建议在集群部署(形成)后在节点启动后导入定义。
要从节点启动时的本地文件导入定义,请将 definitions.local.path 配置键指向一个包含定义且已预先导出的 JSON 文件的路径。
# Does not require management plugin to be enabled.
definitions.import_backend = local_filesystem
definitions.local.path = /path/to/definitions/defs.json
定义可以从节点启动时可通过 HTTPS 访问的 URL 导入。将 definitions.import_backend 和 definitions.https.url 配置键设置为 https 和 JSON 定义所在位置的有效 URL。
# Does not require management plugin to be enabled.
definitions.import_backend = https
definitions.https.url = https://raw.githubusercontent.com/rabbitmq/sample-configs/main/queues/5k-queues.json
# client-side TLS options for definition import
definitions.tls.versions.1 = tlsv1.2
启动时定义导入的细微差别
定义导入发生在插件激活之后。这意味着与插件相关的定义(例如,动态 Shovel、自定义类型的交换器等)可以在启动时导入。
文件中的定义不会覆盖代理中已有的任何内容。
如果一个空白(未初始化的)节点导入定义文件,它不会创建默认的虚拟主机和用户。在**测试或 QA** 环境中,可以通过相同的定义文件创建等效的默认用户。
对于**生产**系统,必须创建一个具有唯一凭据的新用户并加以使用。
以下代码片段演示了如何修改定义文件以“重新创建”默认用户,该用户默认情况下只能从 localhost 连接。
"users": [
{
"name": "guest",
"password_hash": "9/1i+jKFRpbTRV1PtRnzFFYibT3cEpP92JeZ8YKGtflf4e/u",
"tags": ["administrator"]
}
],
"permissions":[
{
"user":"guest",
"vhost":"/",
"configure":".*",
"read":".*",
"write":".*"}
],
如果定义内容未更改,请避免启动时导入
默认情况下,每个集群节点都会无条件地导入定义。在许多环境中,定义文件很少更改。在这种情况下,仅在定义文件内容实际更改时执行导入是有意义的。
可以通过将 definitions.skip_if_unchanged 配置键设置为 true 来实现此目的。
# when set to true, definition import will only happen
# if definition file contents change
definitions.skip_if_unchanged = true
definitions.import_backend = local_filesystem
definitions.local.path = /path/to/definitions/defs.json
此功能适用于单个文件和目录。
# when set to true, definition import will only happen
# if definition file contents change
definitions.skip_if_unchanged = true
definitions.import_backend = local_filesystem
definitions.local.path = /path/to/definitions/conf.d/
HTTPS 端点导入机制也支持此功能。
# when set to true, definition import will only happen
# if definition file contents change
definitions.skip_if_unchanged = true
definitions.import_backend = https
definitions.https.url = https://some.endpoint/path/to/rabbitmq.definitions.json
definitions.tls.verify = verify_peer
definitions.tls.fail_if_no_peer_cert = true
definitions.tls.cacertfile = /path/to/ca_certificate.pem
definitions.tls.certfile = /path/to/client_certificate.pem
definitions.tls.keyfile = /path/to/client_key.pem
节点启动后导入定义
使用不提供内置定义导入的旧版本的安装,可以使用两个 CLI 命令的组合在节点启动后立即导入定义。
# await startup for up to 5 minutes
rabbitmqctl await_startup --timeout 300
# import definitions using rabbitmqctl
rabbitmqctl import_definitions /path/to/definitions.file.json
# OR, import using rabbitmqadmin
# Requires management plugin to be enabled
rabbitmqadmin definitions import /path/to/definitions.file.json