此过程使用常规 MongoDB 复制将 MongoDB Ops Manager 或 Cloud Manager 托管的任何副本集迁移到 Kubernetes 下的 Kubernetes Operator 中。这包括在虚拟机或裸机上运行的部署,以及已由其他 Kubernetes Operator 实例托管的部署。迁移是实时且增量的:将副本集扩展到 Kubernetes,提升 Kubernetes 节点,然后修剪外部节点。不涉及快照恢复和 mongosync。
开始之前
在迁移副本集之前,请确认以下事项:
一个 MongoDB Ops Manager 或 Cloud Manager 连接
ConfigMap,具有密钥baseUrl、orgId和projectName。一个 API 密钥
Secret具有密钥publicKey和privateKey。Kubernetes 操作符
ServiceAccount具有batch/jobs权限 (create、get、list、watch和delete) 用于 dry-run connectivity 作业。该项目包含恰好一个部署。
您还需要:
一个由 MongoDB Ops Manager 或 Cloud Manager 托管的现有副本集。
MongoDB Ops Manager 或 Cloud Manager 项目中只有一个部署。
安装了 Kubernetes 操作符的 Kubernetes 集群。
与 Kubernetes 操作符版本匹配的
kubectl mongodb插件。Kubernetes 操作符在每次协调时实施此匹配,包括演练运行。虚拟机托管与 Kubernetes Pod 之间的双向网络连接和主机名解析。
如果部署使用 TLS,则提供涵盖所有 SAN 的预配置 TLS 证书。
手头有 SCRAM 用户密码。您无法从自动化配置中恢复它们。
开始前的备份。
一个处于健康状态并达到目标状态的部署。
始终至少保持 3 个投票节点。Kubernetes 操作符拒绝超过 7 名投票节点。如果超过 7,请添加无投票权的 Kubernetes 节点,或删除具有投票权的外部节点。
一次只进行一种更改:添加 Kubernetes 节点、精简外部节点,或一次仅更改一个节点的投票和优先级。一旦迁移开始,准入验证将拒绝混合更改,并拒绝在迁移过程中删除 Kubernetes 节点或添加外部节点。
仅当部署达到目标状态时才执行操作。
最后迁移主节点 (primary node in the replica set)。将选票和优先级转移到节点上可以 trigger 一次选举,并且在副本集选举新的主节点 (primary node in the replica set)期间,写入可能会短暂失败。最后迁移主节点 (primary node in the replica set)可以避免触发该选举,以及它导致的写入停机时间,直到最后一步。
注意
您还可以通过提高 Kubernetes 中节点的优先级来 trigger 重新选举。
当
spec.externalMembers不为空时,Kubernetes 操作符强制一个节点一次的扩展。这就是为什么每个变更都需要各自等待目标状态。
步骤
生成 MongoDB 自定义资源。
运行 kubectl mongodb migrate-to-mck mongodb 命令:
kubectl mongodb migrate-to-mck mongodb \ --config-map-name <configmap> \ --secret-name <secret> \ --namespace <namespace> \ -o mongodb-cr.yaml
检查生成的文件。它包含:
spec.externalMembers, 列出源进程。spec.members设置为0。mongodb.com/migration-dry-run: true注释,插件始终会添加该注释。
该命令还支持以下可选标志:
--certs-secret-prefix:启用 TLS 时必需。设置spec.security.certsSecretPrefix。--prometheus-secret-name:在启用 Prometheus 时使用。Secret必须已经存在并拥有password键。--resource-name-override: 在生成的资源上设置metadata.name。插件会在副本集名称不是有效的 Kubernetes 名称时自动将其规范化,并为您设置spec.replicaSetNameOverride。
生成 MongoDBUser 自定义资源。
仅在您想要迁移数据库用户时才完成此步骤。迁移不需要它。
为每个 SCRAM 用户预先创建一个 Secret,每个用户都有一个 password 密钥。运行:
kubectl mongodb migrate-to-mck users \ --config-map-name <configmap> \ --secret-name <secret> \ --namespace <namespace> \ --users-secrets-file users.csv \ -o users-cr.yaml
CSV 文件将用户映射到 Secrets,每行一个,形式为 username:database,secret-name。省略 --users-secrets-file,代之提示每个用户。
该插件对 $external 数据库生成 X.509 和 LDAP 用户。它会跳过自动化代理用户。
如果部署使用 TLS,请签发 Kubernetes 节点证书。
使用签署虚拟机证书的同一证书颁发机构颁发 Kubernetes 节点证书。
Kubernetes 操作符需要名为 <certsSecretPrefix>-<resourceName>-cert 的 kubernetes.io/tls Secret 和名为 <resourceName>-ca 的 CA ConfigMap,其中包含 ca-pem 密钥和 mms-ca.crt 密钥。证书需要 SAN,覆盖每个 Pod 和服务 DNS 名称,以及服务器认证和客户端认证用途。
如果源部署不使用 TLS,请在迁移之前,在现有虚拟机部署的 MongoDB Ops Manager 或 Cloud Manager 中将 net.tls.mode 设置为 disabled。在这种情况下,您无需在 MongoDB 自定义资源中进行任何设置。
注意
CA 不匹配将在下一个步骤的预运行中被检测到,这是设计如此。
配置外部访问。
在运行试运行之前,配置 spec.externalAccess,以便虚拟机节点可以访问 Kubernetes Pods。为了让这些节点通过主机名解析 Pod,您还可以设置 spec.externalAccess.externalDomain。要了解所涉及的字段和 DNS 要求,请参阅 迁移的网络要求。
此设置由用户拥有:您需要为您的环境配置 LoadBalancer 或 NodePort 以及 DNS 记录。
重要
如果您在此部署中使用 MongoDB Search 或向量搜索,请勿设置 externalDomain。MongoDBSearch 不支持设置 externalDomain 的 MongoDB 资源,并且在创建集群后无法删除该字段。要了解更多信息,请参阅 MongoDB Search 与迁移的交互。
运行试运行并检查连接。
应用带有 mongodb.com/migration-dry-run 注解的生成资源。当设置了该注解时,Kubernetes Operator 不会进行任何自动化配置更改,仅验证连接性。
Kubernetes Operator 会创建一个名为 <resourceName>-connectivity-check 的作业,该作业会拨入每个外部节点并进行身份验证。该作业使用 ttlSecondsAfterFinished 删除自身,下一个协调会重新创建它,因此验证是自动进行的。您可以在 Kubernetes 或 MongoDB Ops Manager 用户界面中修复问题,并自由重新运行。
试运行会检查 Kubernetes 到虚拟机的可达性(DNS、TLS、防火墙和节点地址)以及凭证,包括 local 数据库上的 __system 角色,以及启用 TLS 时的 CA。它不会检查从虚拟机到 Kubernetes 的入站连接。
由于该方向完全取决于您的网络设置,因此没有任何单一命令可以保证这一点。请参考以下清单:
确认 Kubernetes 节点将具有的主机名(遵循模式
<metadata.name>-0.<spec.externalAccess.externalDomain>)可从虚拟机节点解析。确认可以从虚拟机访问 Kubernetes 节点或 LoadBalancer IP。
从 status.conditions[type=NetworkConnectivityVerified] 中读取结果:
验证器作业退出代码 | 条件状态 | 原因 | 含义 |
|---|---|---|---|
作业仍在运行 |
|
|
|
|
|
| 所有外部节点都可访问并已经身份验证。 |
|
|
| 凭证、身份验证机制或缺失 |
|
|
| DNS、TLS、超时或无法访问的节点。检查作业 Pod 日志。 |
|
|
| 未分类失败。检查作业 Pod 日志。 |
在作业开始之前发生的故障使用原因 OperatorImageUnknown、BuildStatefulSetOptions、AgentCertSecretFailed 和 AgentCertSubject。
一旦没有外部节点留下,Kubernetes 操作符会从 status.conditions 中完全删除 NetworkConnectivityVerified 条件。
将副本集扩展到 Kubernetes。
删除试运行注解:
kubectl annotate mdb <resourceName> \ mongodb.com/migration-dry-run-
这是 Kubernetes Operator 接管 Ops Manager 项目的时间点。
提出 spec.members 并共同写入 spec.memberConfig。
警告
设置 spec.memberConfig在增加节点数量之前
默认情况下,新的 Kubernetes 节点作为投票节点加入。CRD 默认是 votes: 1 和 priority: "1",这允许仍在同步的节点在完成初始同步之前参与选举。
MongoDB 建议您在增加节点数量之前,为每个新的 Kubernetes 节点写入一个 spec.memberConfig 记录,并使用 votes: 0 和 priority: "0",以防尚在同步的节点赢得选举。votes是一个整数。priority是一个字符串。
例如,要添加三个 Kubernetes 节点作为非投票节点:
spec: memberConfig: - votes: 0 priority: "0" - votes: 0 priority: "0" - votes: 0 priority: "0"
等待完全初始同步和目标状态。如果您在上述可选步骤中生成了 MongoDBUser 资源,请立即应用它们并确认每个资源都达到 Updated 的 status.phase。
删除外部节点。
重要
每次仅从 spec.externalMembers 中删除一个条目。每次删除后等待目标状态,然后再删除下一个条目。
例如:
kubectl patch mdb <resourceName> --type=json \ -p='[{"op":"remove","path":"/spec/externalMembers/0"}]'
您可以删除条目,但开始迁移后就无法添加条目。
观看 status.conditions[type=Migrating].reason 经过 Extending、InProgress 和 Pruning:
原因 | 状态 | 含义 |
|---|---|---|
|
| 空运行注释已设置。 |
|
| 所需的 Kubernetes 节点数超过了上次协调的计数。 |
|
|
|
|
| 外部节点存在,但没有任何变化。这也是在初次协调时的原因。 |
|
| 所有外部节点均已移除。 |
优先级是 Validating > Extending > Pruning > InProgress。一个也会扩展 Kubernetes 侧的清理报告 Extending,这是逐步更改的另一个原因。
不允许同时进行修剪和扩展。
若要通过脚本实现迁移完成后的操作,请使用 kubectl wait --for=condition=Migrating=False,而不是轮询 status.phase。
连接字符串密钥
Kubernetes 操作符会自动生成一个连接字符串 Secret,不包含任何凭证,命名为 <metadata.name>-cluster-connection-string,并使其与活动节点保持同步。将您的应用程序指向此 Secret,而不是硬编码连接字符串。
迁移期间的可用性
读取在迁移过程中始终可用。写入可能会在选举期间短暂失败,因此您的驱动程序必须使用可重试写入。如果读取目标移动,读取延迟可能会增加,因此请将 Kubernetes 集群与虚拟机在同一区域运行。对迁移的从节点(secondary node from replica set)运行的长时间游标会中断,因为没有静止模式。