在自管理副本集中更改主机名
对于大多数对于大多数副本集,在members[n].host
字段中的主机名永远不会更改。然而,如果组织需求发生变化,您可能需要迁移一些或所有主机名。
注意
始终在副本集配置中为members[n].host
字段的值使用可解析的主机名,以避免混淆和复杂性。
重要
为了避免因IP地址更改而导致的配置更新,请使用DNS主机名而不是IP地址。在配置副本集成员或分片集群成员时,使用DNS主机名而不是IP地址尤为重要。
使用主机名而不是IP地址来配置跨越分割网络视域的集群。从MongoDB 5.0开始,仅配置IP地址的节点将失败启动验证并且不会启动。
概述
本文档提供了两种更改members[n].host
字段主机名的独立程序。使用以下任一方法
无中断更改主机名。此方法确保您的应用程序始终能够读取和写入副本集数据,但此方法可能需要很长时间,并且可能在应用层引起停机。
如果您使用第一种方法,则必须配置您的应用程序以同时在旧的和新的位置连接到副本集,这通常需要在应用层重启和重新配置,这可能会影响应用程序的可用性。重新配置应用程序超出了本文档的范围。
同时停止所有在旧主机名上运行的成员。此方法有更短的维护窗口,但在操作期间副本集将不可用。
假设
给定一个包含三个成员的副本集
database0.example.com:27017
(主节点)database1.example.com:27017
database2.example.com:27017
并且具有以下rs.conf()
输出
{ "_id" : "rs", "version" : 3, "members" : [ { "_id" : 0, "host" : "database0.example.com:27017" }, { "_id" : 1, "host" : "database1.example.com:27017" }, { "_id" : 2, "host" : "database2.example.com:27017" } ] }
以下过程将成员的主机名更改为以下内容
mongodb0.example.net:27017
(主节点)mongodb1.example.net:27017
mongodb2.example.net:27017
使用最适合您的部署的过程。
在保持副本集可用性的同时更改主机名
此过程使用上述假设。
对于副本集中的每个次要节点,执行以下操作序列
停止次要节点。
在新位置重新启动次要节点。
使用
mongosh
连接到副本集的主节点。在我们的示例中,主节点在端口27017
上运行,因此您将发出以下命令mongosh --port 27017 使用
rs.reconfig()
更新包含新主机名的副本集配置文档。例如,以下命令序列更新副本集配置文档中成员数组(即
members[1]
)中索引为1
的次要节点的主机名cfg = rs.conf() cfg.members[1].host = "mongodb1.example.net:27017" rs.reconfig(cfg) 有关更新配置文档的更多信息,请参阅示例。
确保您的客户端应用程序能够访问新位置的集合,并且副本能有机会赶上集合中的其他成员。
为集合中的每个非主成员重复上述步骤。
连接到主实例,并使用
rs.stepDown()
方法降级主实例rs.stepDown() 副本集选举另一位成员成为主实例。
当降级成功后,关闭旧的主实例。
在新位置启动将成为新主实例的
mongod
实例。连接到刚刚被选为当前主实例的实例,并使用该节点的hostname更新副本集配置文档。
例如,如果旧主实例位于位置
0
,而新主实例的hostname是mongodb0.example.net:27017
,您将运行cfg = rs.conf() cfg.members[0].host = "mongodb0.example.net:27017" rs.reconfig(cfg) 连接到新主实例
您的输出应类似于
{ "_id" : "rs", "version" : 4, "members" : [ { "_id" : 0, "host" : "mongodb0.example.net:27017" }, { "_id" : 1, "host" : "mongodb1.example.net:27017" }, { "_id" : 2, "host" : "mongodb2.example.net:27017" } ] }
同时更改所有hostname
此过程使用上述假设。
先决条件
以下过程读取并更新本地数据库中的system.replset
集合。
如果您的部署强制实施访问控制,则执行此过程的用户必须在system.replset
集合上具有find
和update
权限。
为了创建提供必要权限的角色
以具有管理用户和角色权限的用户身份登录,例如具有
userAdminAnyDatabase
角色的用户。以下步骤使用在 在自托管部署中启用访问控制 中创建的myUserAdmin
。mongosh --port 27017 -u myUserAdmin --authenticationDatabase 'admin' -p 在
local
数据库的system.replset
集合中创建一个提供必要权限的用户角色db.adminCommand( { createRole: "systemreplsetRole", privileges: [ { resource: { db: "local", collection: "system.replset" }, actions: ["find","update"] } ], roles: [] } ); 将此角色授予将执行重命名过程的用户。例如,以下假设在
admin
数据库中存在一个现有用户"userPerformingRename"
。use admin db.grantRolesToUser( "userPerformingRename", [ { role: "systemreplsetRole", db: "admin" } ] );
过程
停止复制集的所有成员。
在每个成员上重启,使用不同的端口号,并且不要使用
--replSet
运行时选项。在维护期间更改端口号可以防止客户端在您进行维护时连接到此主机。使用成员的常规--dbpath
,在本例中为/data/db1
。使用类似于以下命令的命令警告
在将实例绑定到公开可访问的IP地址之前,您必须确保您的集群免受未经授权的访问。有关安全建议的完整列表,请参阅 自托管部署的安全清单。至少考虑 启用身份验证 和 加强网络基础设施。
mongod --dbpath /data/db1/ --port 37017 --bind_ip localhost,<hostname(s)|ip address(es)> 重要
为了避免因IP地址更改而导致的配置更新,请使用DNS主机名而不是IP地址。在配置副本集成员或分片集群成员时,使用DNS主机名而不是IP地址尤为重要。
使用主机名而不是IP地址来配置跨越分割网络视域的集群。从MongoDB 5.0开始,仅配置IP地址的节点将失败启动验证并且不会启动。
对于复制集的每个成员,执行以下操作序列
将
mongosh
连接到在新的临时端口上运行的mongod
。例如,对于在临时端口37017
上运行的成员,您将发出此命令mongosh --port 37017 如果使用访问控制,则以具有适当权限的用户连接。见 先决条件。
mongosh --port 37017 -u userPerformingRename --authenticationDatabase=admin -p 手动编辑复制集配置。复制集配置是
local
数据库中system.replset
集合中的唯一文档。要更改主机名,编辑复制集配置以提供复制集所有成员的新主机名和端口。
切换到
local
数据库。use local 为配置文档创建一个JavaScript变量。将
_id
字段的值修改为与您的副本集匹配。cfg = db.system.replset.findOne( { "_id": "rs0" } ) 为副本集的每个成员提供新的主机名和端口。将主机名和端口修改为与您的副本集匹配。
cfg.members[0].host = "mongodb0.example.net:27017" cfg.members[1].host = "mongodb1.example.net:27017" cfg.members[2].host = "mongodb2.example.net:27017" 更新
system.replset
集合中的主机名和端口。db.system.replset.updateOne( { "_id": "rs0" }, { $set: cfg } ) 验证更改
db.system.replset.find( {}, { "members.host": 1 } )
停止成员上的
mongod
进程。
在重新配置集的所有成员后,以正常方式启动每个
mongod
实例:使用常规端口号,并使用--replSet
选项。例如警告
在将实例绑定到公开可访问的IP地址之前,您必须确保您的集群免受未经授权的访问。有关安全建议的完整列表,请参阅 自托管部署的安全清单。至少考虑 启用身份验证 和 加强网络基础设施。
mongod --dbpath /data/db1/ --port 27017 --replSet rs0 --bind_ip localhost,<hostname(s)|ip address(es)> 使用
mongosh
连接到其中一个mongod
实例。例如mongosh --port 27017 您的输出应类似于
{ "_id" : "rs0", "version" : 4, "members" : [ { "_id" : 0, "host" : "mongodb0.example.net:27017" }, { "_id" : 1, "host" : "mongodb1.example.net:27017" }, { "_id" : 2, "host" : "mongodb2.example.net:27017" } ] }