您可以将使用内部托管的应用程序数据库的 MongoDB Ops Manager 资源转换为使用 外部 应用程序数据库的资源,即将 spec.role 设置为 AppDB 的 MongoDB 自定义资源。这样就可以让 MongoDB Ops Manager 备份和恢复应用程序数据库。要了解更多信息,请参阅 备份 MongoDB Ops Manager 应用程序数据库。
此次迁移将现有的应用程序数据库 StatefulSet 及其 持久卷 的所有权从 MongoDB Ops Manager 资源重新指向 MongoDB 资源。Kubernetes 操作符 不会移动或重新创建您的数据,也不会重启 Ops Manager Pod。
迁移如何工作
MongoDB Ops Manager 资源以内部托管的应用程序数据库开始,Kubernetes 操作符拥有名为 <primary-om-name>-db 的 StatefulSet。迁移如下进行:
您创建一个 MongoDB 资源,将
spec.role设置为AppDB,并使用与 StatefulSet 相同的名称,该资源位于由 管理 MongoDB Ops Manager 实例托管的项目中。MongoDB 资源尚无法获取 StatefulSet 的所有权,因此它保持在Pending阶段,并显示一条消息,指出它无法获取应用程序数据库 StatefulSet 的所有权。您将
spec.externalApplicationDatabaseRef添加到 MongoDB Ops Manager 资源中。Kubernetes Operator 通过删除 MongoDB Ops Manager 资源的所有者引用并将 StatefulSet 标记为可迁移,从而分离 StatefulSet。然后,MongoDB 资源将获取其所有权。
由于 Kubernetes Operator 计算出的连接字符串与之前相同(使用相同的主机名),因此 MongoDB Ops Manager Pod 不会重启。
先决条件
在开始之前,请完成以下任务:
安装 Kubernetes 操作符和
kubectl。要了解更多信息,请参阅 使用 Kubernetes 安装。部署一个使用内部托管的应用程序数据库的主节点 (primary node in the replica set) MongoDB Ops Manager 资源。此资源设置
spec.applicationDatabase,并且 Kubernetes 操作符拥有名为<primary-om-name>-db的 StatefulSet。要了解详情,请参阅部署 Ops Manager 资源。部署一个处于
Running阶段且拥有外部应用程序数据库项目的管理 MongoDB Ops Manager 资源。要了解更多信息,请参阅 使用外部应用程序数据库部署 MongoDB Ops Manager。Create credentials for the Kubernetes Operator. The secret holds the programmatic API key pair that the Kubernetes Operator uses to authenticate to the management Ops Manager API on your behalf. You can give the secret any name. To learn more, see Create Credentials for the Kubernetes Operator.
Considerations
在迁移之前,请查看以下考虑因素:
在 MongoDB 资源上设置的应用程序数据库版本必须与内部托管的应用程序数据库运行的版本匹配,并且必须是管理 MongoDB Ops Manager 实例提供的 MongoDB 版本。
Kubernetes 操作符在迁移过程中不支持
spec.applicationDatabase.passwordSecretKeyRef。Kubernetes 操作符 生成新密码,并且它轮换您提供的任何密码。如果 MongoDB 资源配置与内部托管的应用程序数据库配置不同(例如不同的 Pod 模板或不同的容器集),应用程序数据库可能会在 1 到 2 分钟内不可用。如果这两种配置在语义上相同,则应用程序数据库保持可用。
Kubernetes 操作符只支持在单个 Kubernetes 集群上迁移。
步骤
设置用于迁移的环境变量。
export K8S_CTX="<your-kube-context>" export MDB_NS="mongodb" export MANAGEMENT_OM_NAME="management-om" export PRIMARY_OM_NAME="primary-om" export APPDB_NAME="${PRIMARY_OM_NAME}-db" export APPDB_VERSION="8.0.5-ent" export MANAGEMENT_OM_URL="http://${MANAGEMENT_OM_NAME}-svc.${MDB_NS}.svc.cluster.local:8080" export MANAGEMENT_OM_ADMIN_KEY_SECRET="<your-operator-credentials-secret>" export APPDB_PROJECT_CONFIGMAP="${APPDB_NAME}-config" export APPDB_PROJECT_NAME="external-appdb"
确认起始省/市/自治区。
确认主节点 (primary node in the replica set) Ops Manager 资源及其内部托管的应用程序数据库处于
Running阶段:kubectl get om "${PRIMARY_OM_NAME}" --context "${K8S_CTX}" -n "${MDB_NS}" \ -o jsonpath='{.status.opsManager.phase} / appdb={.status.applicationDatabase.phase}{"\n"}' 确认 MongoDB Ops Manager 资源控制应用程序数据库 StatefulSet:
kubectl get statefulset "${APPDB_NAME}" --context "${K8S_CTX}" -n "${MDB_NS}" \ -o jsonpath='{range .metadata.ownerReferences[*]}{.kind}/{.name}{"\n"}{end}' 该命令返回
MongoDBOpsManager/${PRIMARY_OM_NAME}。
为外部应用程序数据库创建项目的 ConfigMap。
orgId 值是必填项。如果您将其设置为空 string,Kubernetes Operator 会创建一个与您的项目同名的组织。
kubectl create configmap "${APPDB_PROJECT_CONFIGMAP}" \ --context "${K8S_CTX}" -n "${MDB_NS}" \ --from-literal=baseUrl="${MANAGEMENT_OM_URL}" \ --from-literal=projectName="${APPDB_PROJECT_NAME}" \ --from-literal=orgId=""
为外部应用程序数据库创建 MongoDB 资源。
为该资源指定与现有应用程序数据库 StatefulSet 相同的名称。
kubectl apply --context "${K8S_CTX}" -n "${MDB_NS}" -f - <<EOF apiVersion: mongodb.com/v1 kind: MongoDB metadata: name: ${APPDB_NAME} spec: members: 3 version: ${APPDB_VERSION} type: ReplicaSet role: AppDB opsManager: configMapRef: name: ${APPDB_PROJECT_CONFIGMAP} credentials: ${MANAGEMENT_OM_ADMIN_KEY_SECRET} persistent: true security: authentication: enabled: true modes: ["SCRAM"] ignoreUnknownUsers: true EOF
确认 MongoDB 资源等待所有权。
直到 MongoDB Ops Manager 资源释放 StatefulSet,MongoDB 资源会保持在 Pending 阶段。这是预期的,并不是错误。
kubectl wait --for=jsonpath='{.status.phase}'=Pending \ mdb/"${APPDB_NAME}" --context "${K8S_CTX}" -n "${MDB_NS}" --timeout=300s kubectl get mdb "${APPDB_NAME}" --context "${K8S_CTX}" -n "${MDB_NS}" \ -o jsonpath='{.status.message}{"\n"}'
状态消息报告称,资源无法拥有应用程序数据库 StatefulSet。
将外部应用程序数据库引用添加到 MongoDB Ops Manager 资源。
kubectl patch om "${PRIMARY_OM_NAME}" \ --context "${K8S_CTX}" -n "${MDB_NS}" \ --type merge \ -p "{\"spec\":{\"externalApplicationDatabaseRef\":{\"name\":\"${APPDB_NAME}\",\"kind\":\"MongoDB\"}}}"
您可以在同一个补丁中删除 spec.applicationDatabase。将其保留在原位没有影响:设置 spec.externalApplicationDatabaseRef 后,Kubernetes 操作符将停止管理此资源的内部应用程序数据库。
验证迁移。
确认 MongoDB 资源拥有应用程序数据库 StatefulSet:
kubectl get statefulset "${APPDB_NAME}" --context "${K8S_CTX}" -n "${MDB_NS}" \ -o jsonpath='{range .metadata.ownerReferences[*]}{.kind}/{.name}{"\n"}{end}' 该命令返回
MongoDB/${APPDB_NAME}。确认 MongoDB Ops Manager 资源将其应用程序数据库报告为
Disabled,这意味着 Kubernetes 操作符不再为其托管内部应用程序数据库:kubectl get om "${PRIMARY_OM_NAME}" --context "${K8S_CTX}" -n "${MDB_NS}" \ -o jsonpath='{.status.applicationDatabase.phase}{"\n"}' 通过检查 Ops Manager Pod 的运行时间和重启次数,确认它们没有重启:
kubectl get pods --context "${K8S_CTX}" -n "${MDB_NS}"
常见迁移问题
MongoDB 资源报告版本错误
如果 MongoDB 资源报告 Failed 且消息显示 MongoDB 版本不可用,请将 spec.version 设置为管理 Ops Manager 实例提供的版本,并确保 Ops Manager 版本和应用程序数据库版本处于同一主版本。
MongoDB 资源在打补丁后保持待处理状态
Kubernetes 操作符必须分离 StatefulSet,然后 MongoDB 资源才能取得其所有权。确认您已将 spec.externalApplicationDatabaseRef 应用于主节点 (primary node in the replica set) Ops Manager 资源,并且 spec.externalApplicationDatabaseRef.name 的值为正好 <primary-om-name>-db。
MongoDB 资源报告项目错误
如果 MongoDB 资源因项目或注册错误而停留在 Pending 阶段,则在您创建资源时,管理 MongoDB Ops Manager 公共 API 可能尚未准备就绪。确认管理 MongoDB Ops Manager 资源处于 Running 阶段,并且其 API 回答请求,然后再次协调该资源。
MongoDB Ops Manager Pods 在迁移过程中重启
如果 MongoDB Ops Manager Pod 重启,计算出的连接字符串会发生变化。对于使用默认端口的副本集,迁移前后的连接字符串是相同的。Kubernetes 操作符 不支持此迁移的非默认端口。
后续步骤
要备份外部应用程序数据库,请在管理 MongoDB Ops Manager 实例托管的项目中,在 MongoDB 资源上启用备份。要了解更多信息,请参阅配置 MongoDB 数据库备份。
要反转此迁移,请参阅 将外部应用程序数据库返回 MongoDB Ops Manager。