您可以部署使用多集群外部应用程序数据库的Ops Manager资源:将 spec.role设立为 AppDB 的 MongoDBMultiCluster 自定义资源。此资源将应用程序数据库成员分布在多个Kubernetes集群中。第二个Ops Manager实例将资源作为一个项目进行管理,从而允许Ops Manager备份和恢复应用程序数据库。要学习;了解更多信息,请参阅备份Ops Manager 应用程序数据库。
此过程将部署新的Ops Manager实例。要转换使用内部托管的多集群应用程序数据库的现有Ops Manager实例,请参阅迁移多集群应用程序数据库。有关此过程的单集群变体,请参阅使用外部应用程序数据库部署Ops Manager 。
此过程将部署以下资源:
主节点 (primary node in the replica set)Ops Manager实例,省略
spec.applicationDatabase并引用外部应用程序数据库,并将spec.externalApplicationDatabaseRef设立为种类MongoDBMultiCluster。
先决条件
在开始之前,请完成以下任务:
部署跨集群并提供跨集群服务发现的服务网格。应用程序数据库成员通过网格跨集群通信。
此过程使用 Istio,但您可以使用任何能够在跨集群的 Pod 之间提供 FQDN 主机名解析的服务网格。服务网格本身并不是多集群外部应用程序数据库的必要条件。有关无网格部署模式,请参阅没有服务网格的多集群Ops Manager 。
安装
kubectl、helm和kubectl mongodb插件,并为所有三个集群进行配置。获取 Kubernetes 操作符 Helm 图表的使用权限。
Considerations
在部署之前,请查看以下注意事项:
将 MongoDB Ops Manager 版本和应用程序数据库版本设置为一致的对。管理 MongoDB Ops Manager 实例托管外部应用程序数据库,因此应用程序数据库版本必须是管理 MongoDB Ops Manager 实例在其版本清单中提供的 MongoDB 版本。示例,一个 8.0.xMongoDB Ops Manager 实例提供 8.0.xMongoDB 版本,但 7.0.xMongoDB Ops Manager 实例不提供。要查找兼容的对,请参阅 应用程序数据库兼容性矩阵。
多集群外部应用程序数据库需要 TLS加密。当应用程序数据库使用 TLS 时, MongoDB 助手会根据
spec.security.tls.ca中的 CA 捆绑包验证每个出站 HTTPS 连接,包括从downloads.mongodb.com下载MongoDB二进制文件。除了您自己的 CA 之外,CA 捆绑包还必须包含签署downloads.mongodb.com的公共根。要为多集群部署配置 TLS 证书,请参阅管理 TLS 证书。
步骤
为部署设置环境变量。
export K8S_CTX_0="<central-cluster-context>"export K8S_CTX_1="<member-cluster-1-context>"export K8S_CTX_2="<member-cluster-2-context>"export MDB_NS="mongodb"
export OPERATOR_HELM_CHART="oci://quay.io/mongodb/helm-charts/mongodb-kubernetes"
export OM_VERSION="8.0.7"export APPDB_VERSION="8.0.5-ent"
export MANAGEMENT_OM_NAME="management-om"export PRIMARY_OM_NAME="primary-om"
export APPDB_NAME="${PRIMARY_OM_NAME}-db"export APPDB_MEMBERS_C1=2export APPDB_MEMBERS_C2=2
export MANAGEMENT_OM_URL="http://${MANAGEMENT_OM_NAME}-svc.${MDB_NS}.svc.cluster.local:8080"export MANAGEMENT_OM_ADMIN_KEY_SECRET="${MDB_NS}-${MANAGEMENT_OM_NAME}-admin-key"
export APPDB_PROJECT_CONFIGMAP="${APPDB_NAME}-config"export APPDB_PROJECT_NAME="external-appdb"export APPDB_CONNECTION_STRING_SECRET="${APPDB_NAME}-connection-string"
export CERT_MANAGER_NAMESPACE="cert-manager"export APPDB_TLS_SELF_SIGNED_ISSUER="mongodb-self-signed-issuer"export APPDB_TLS_CA_CERT_NAME="mongodb-ca"export APPDB_TLS_CA_SECRET_NAME="mongodb-ca-key-pair"export APPDB_TLS_CA_ISSUER="mongodb-ca-issuer"export APPDB_CERT_PREFIX="appdb"export APPDB_CA_CONFIGMAP="${APPDB_NAME}-ca"
export OM_ADMIN_EMAIL="admin@example.com"export OM_ADMIN_PASSWORD="<your-password>"export OM_ADMIN_FIRST_NAME="Admin"export OM_ADMIN_LAST_NAME="User"Kubernetes 操作符 要求外部应用程序数据库命名为 <primary-om-name>-db,这就是 APPDB_NAME 从 PRIMARY_OM_NAME 派生的原因。
在每个集群中创建命名空间空间。
命名空间必须存在于中央集群和两个成员集群上。 istio-injection=enabled 标签向应用程序数据库 Pod 添加一个 sidecar,以便其代理可以跨集群解析管理Ops Manager服务。
for ctx in "${K8S_CTX_0}" "${K8S_CTX_1}" "${K8S_CTX_2}"; do kubectl create namespace "${MDB_NS}" --context "${ctx}" --dry-run=client -o yaml \ | kubectl apply --context "${ctx}" -f - kubectl label namespace "${MDB_NS}" istio-injection=enabled --overwrite --context "${ctx}"done以多集群模式安装Kubernetes Operator。
使用 kubectl mongodb 插件配置跨集群的服务帐户和角色,然后在注册了成员集群的中央集群上安装Kubernetes Operator。要学习;了解更多信息,请参阅多集群部署先决条件。
kubectl mongodb multicluster setup \ --central-cluster="${K8S_CTX_0}" \ --member-clusters="${K8S_CTX_0},${K8S_CTX_1},${K8S_CTX_2}" \ --member-cluster-namespace="${MDB_NS}" \ --central-cluster-namespace="${MDB_NS}" \ --create-service-account-secrets \ --install-database-roles=true
helm upgrade --install --kube-context "${K8S_CTX_0}" \ --create-namespace --namespace "${MDB_NS}" \ mongodb-kubernetes-operator-multi-cluster \ --set operator.name=mongodb-kubernetes-operator-multi-cluster \ --set operator.createOperatorServiceAccount=false \ --set operator.createResourcesServiceAccountsAndRoles=false \ --set "multiCluster.clusters={${K8S_CTX_0},${K8S_CTX_1},${K8S_CTX_2}}" \ "${OPERATOR_HELM_CHART}"
kubectl rollout status deployment/mongodb-kubernetes-operator-multi-cluster \ --context "${K8S_CTX_0}" -n "${MDB_NS}" --timeout=300s创建 MongoDB Ops Manager 管理秘密。
两个 MongoDB Ops Manager 资源引用此秘密,并使用 spec.adminCredentials.
kubectl create secret generic ops-manager-admin-secret \ --context "${K8S_CTX_0}" -n "${MDB_NS}" \ --from-literal=Username="${OM_ADMIN_EMAIL}" \ --from-literal=Password="${OM_ADMIN_PASSWORD}" \ --from-literal=FirstName="${OM_ADMIN_FIRST_NAME}" \ --from-literal=LastName="${OM_ADMIN_LAST_NAME}"配置 TLS CA。
创建签名链,然后将 CA 发布到 ConfigMap, Kubernetes Operator 将其引用为 spec.security.tls.ca。该捆绑包将您的自签名 CA 与主机的公共 CA 捆绑包相结合,因为MongoDB 助手会对照此捆绑包验证从 downloads.mongodb.com下载的MongoDB二进制文件。合并后的捆绑包超过了客户端kubectl apply 注解的大小限制,因此请在服务器端应用ConfigMap。
kubectl apply --context "${K8S_CTX_0}" -f - <<EOFapiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: ${APPDB_TLS_SELF_SIGNED_ISSUER}spec: selfSigned: {}EOF
kubectl apply --context "${K8S_CTX_0}" -n "${CERT_MANAGER_NAMESPACE}" -f - <<EOFapiVersion: cert-manager.io/v1kind: Certificatemetadata: name: ${APPDB_TLS_CA_CERT_NAME}spec: isCA: true commonName: mongodb-ca secretName: ${APPDB_TLS_CA_SECRET_NAME} duration: 87600h renewBefore: 8760h privateKey: algorithm: ECDSA size: 256 issuerRef: name: ${APPDB_TLS_SELF_SIGNED_ISSUER} kind: ClusterIssuerEOF
kubectl wait --for=condition=Ready certificate/"${APPDB_TLS_CA_CERT_NAME}" \ -n "${CERT_MANAGER_NAMESPACE}" --context "${K8S_CTX_0}" --timeout=120s
kubectl apply --context "${K8S_CTX_0}" -f - <<EOFapiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: ${APPDB_TLS_CA_ISSUER}spec: ca: secretName: ${APPDB_TLS_CA_SECRET_NAME}EOF
ca_crt=$(kubectl get secret "${APPDB_TLS_CA_SECRET_NAME}" \ -n "${CERT_MANAGER_NAMESPACE}" --context "${K8S_CTX_0}" \ -o jsonpath='{.data.ca\.crt}' | base64 -d)
system_ca=""for candidate in /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt /etc/ssl/cert.pem; do [[ -r "${candidate}" ]] && { system_ca=$(cat "${candidate}"); break; }done
ca_bundle_file=$(mktemp)printf '%s\n%s\n' "${ca_crt}" "${system_ca}" > "${ca_bundle_file}"
kubectl create configmap "${APPDB_CA_CONFIGMAP}" \ --context "${K8S_CTX_0}" -n "${MDB_NS}" \ --from-file=ca-pem="${ca_bundle_file}" \ --from-file=mms-ca.crt="${ca_bundle_file}" \ --dry-run=client -o yaml \ | kubectl apply --server-side --force-conflicts --context "${K8S_CTX_0}" -n "${MDB_NS}" -f -
rm -f "${ca_bundle_file}"生成应用程序数据库服务器证书。
证书密钥名称遵循Kubernetes Operator 约定 <certs-secret-prefix>-<appdb-name>-cert。通配符 dnsNames 条目涵盖每个集群中每个应用程序数据库成员的服务 FQDN。
kubectl apply --context "${K8S_CTX_0}" -n "${MDB_NS}" -f - <<EOFapiVersion: cert-manager.io/v1kind: Certificatemetadata: name: ${APPDB_CERT_PREFIX}-${APPDB_NAME}-certspec: secretName: ${APPDB_CERT_PREFIX}-${APPDB_NAME}-cert duration: 8760h renewBefore: 720h privateKey: algorithm: RSA size: 2048 usages: ["server auth", "client auth"] dnsNames: - "*.${MDB_NS}.svc.cluster.local" issuerRef: name: ${APPDB_TLS_CA_ISSUER} kind: ClusterIssuerEOF
kubectl wait --for=condition=Ready certificate/"${APPDB_CERT_PREFIX}-${APPDB_NAME}-cert" \ -n "${MDB_NS}" --context "${K8S_CTX_0}" --timeout=120s部署管理 MongoDB Ops Manager 实例。
kubectl apply --context "${K8S_CTX_0}" -n "${MDB_NS}" -f - <<EOFapiVersion: mongodb.com/v1kind: MongoDBOpsManagermetadata: name: ${MANAGEMENT_OM_NAME}spec: replicas: 1 version: ${OM_VERSION} adminCredentials: ops-manager-admin-secret applicationDatabase: members: 3 version: ${APPDB_VERSION} backup: enabled: false configuration: automation.versions.source: mongodb mms.ignoreInitialUiSetup: "true" mms.adminEmailAddr: admin@example.com mms.fromEmailAddr: admin@example.com mms.replyToEmailAddr: admin@example.com mms.mail.hostname: email-smtp.us-east-1.amazonaws.com mms.mail.port: "465" mms.mail.ssl: "true" mms.mail.transport: smtp mms.minimumTLSVersion: TLSv1.2EOFmms.* 邮件设置是必需的。当 mms.ignoreInitialUiSetup 为 true 时,除非存在 mms.fromEmailAddr 和相关的邮件设置,否则 MongoDB Ops Manager 预检检查不会启动 MongoDB Ops Manager。
等待管理 MongoDB Ops Manager 实例准备就绪。
等待内部托管的应用程序数据库和 MongoDB Ops Manager 资源:
kubectl wait --for=jsonpath='{.status.applicationDatabase.phase}'=Running \ om/"${MANAGEMENT_OM_NAME}" --context "${K8S_CTX_0}" -n "${MDB_NS}" --timeout=1200s kubectl wait --for=jsonpath='{.status.opsManager.phase}'=Running \ om/"${MANAGEMENT_OM_NAME}" --context "${K8S_CTX_0}" -n "${MDB_NS}" --timeout=1800s确认 Ops Manager 公共 API 回答请求。
opsManager.phase的Running表示 MongoDB Ops Manager pod 已启动,但 Kubernetes 操作符用于创建应用程序数据库项目的 API 可能会有几秒的延迟。401响应是预期的未经身份验证响应,并表示 API 已就绪:om_pod="${MANAGEMENT_OM_NAME}-0"until [ "$(kubectl exec "${om_pod}" -c mongodb-ops-manager --context "${K8S_CTX_0}" -n "${MDB_NS}" -- \ curl -s -o /dev/null -w '%{http_code}' \ "http://$(kubectl get pod "${om_pod}" --context "${K8S_CTX_0}" -n "${MDB_NS}" \ -o jsonpath='{.status.podIP}'):8080/api/public/v1.0" 2>/dev/null)" = "401" ]; do echo "waiting for management Ops Manager public API..."; sleep 10done确认 Kubernetes 操作符已为管理 MongoDB Ops Manager 实例创建了管理式 API 密钥秘密:
kubectl get secret "${MANAGEMENT_OM_ADMIN_KEY_SECRET}" \ --context "${K8S_CTX_0}" -n "${MDB_NS}"
为外部应用程序数据库创建项目的 ConfigMap。
sslMMSCAConfigMap 条目公布启用 TLS 的应用程序数据库代理在连接到管理Ops Manager实例时必须信任的 CA。
kubectl create configmap "${APPDB_PROJECT_CONFIGMAP}" \ --context "${K8S_CTX_0}" -n "${MDB_NS}" \ --from-literal=baseUrl="${MANAGEMENT_OM_URL}" \ --from-literal=projectName="${APPDB_PROJECT_NAME}" \ --from-literal=sslMMSCAConfigMap="${APPDB_CA_CONFIGMAP}" \ --from-literal=orgId="" \ --dry-run=client -o yaml \ | kubectl apply --context "${K8S_CTX_0}" -n "${MDB_NS}" -f -创建外部应用程序数据库。
在中央集群上应用 MongoDBMultiCluster资源。 Kubernetes Operator 在成员集群上创建应用程序数据库成员。
kubectl apply --context "${K8S_CTX_0}" -n "${MDB_NS}" -f - <<EOFapiVersion: mongodb.com/v1kind: MongoDBMultiClustermetadata: name: ${APPDB_NAME}spec: version: ${APPDB_VERSION} type: ReplicaSet role: AppDB persistent: true credentials: ${MANAGEMENT_OM_ADMIN_KEY_SECRET} opsManager: configMapRef: name: ${APPDB_PROJECT_CONFIGMAP} security: certsSecretPrefix: ${APPDB_CERT_PREFIX} tls: enabled: true ca: ${APPDB_CA_CONFIGMAP} clusterSpecList: - clusterName: ${K8S_CTX_1} members: ${APPDB_MEMBERS_C1} - clusterName: ${K8S_CTX_2} members: ${APPDB_MEMBERS_C2}EOF
kubectl wait --for=jsonpath='{.status.phase}'=Running \ mdbmc/"${APPDB_NAME}" --context "${K8S_CTX_0}" -n "${MDB_NS}" --timeout=1200s当您将 spec.role设立为 AppDB 时, Kubernetes Operator 会为资源配置SCRAM身份验证。要学习;了解更多信息,请参阅规范。角色。
部署主节点 (primary node in the replica set) MongoDB Ops Manager 实例。
此资源省略 spec.applicationDatabase,并引用外部应用程序数据库,并将 kind设立为 MongoDBMultiCluster。
kubectl apply --context "${K8S_CTX_0}" -n "${MDB_NS}" -f - <<EOFapiVersion: mongodb.com/v1kind: MongoDBOpsManagermetadata: name: ${PRIMARY_OM_NAME}spec: replicas: 1 version: ${OM_VERSION} adminCredentials: ops-manager-admin-secret externalApplicationDatabaseRef: name: ${APPDB_NAME} kind: MongoDBMultiCluster backup: enabled: false configuration: automation.versions.source: mongodb mms.ignoreInitialUiSetup: "true" mms.adminEmailAddr: admin@example.com mms.fromEmailAddr: admin@example.com mms.replyToEmailAddr: admin@example.com mms.mail.hostname: email-smtp.us-east-1.amazonaws.com mms.mail.port: "465" mms.mail.ssl: "true" mms.mail.transport: smtp mms.minimumTLSVersion: TLSv1.2EOF要为 MongoDB 部署启用备份,请将此资源上的 spec.backup.enabled 设置为 true,并配置快照存储。要了解更多,请参阅 使用 Kubernetes 操作符配置文件系统备份存储。
等待主节点 (primary node in the replica set) MongoDB Ops Manager 实例准备就绪。
kubectl wait --for=jsonpath='{.status.opsManager.phase}'=Running \ om/"${PRIMARY_OM_NAME}" --context "${K8S_CTX_0}" -n "${MDB_NS}" --timeout=1800s
kubectl wait --for=jsonpath='{.status.applicationDatabase.phase}'=Disabled \ om/"${PRIMARY_OM_NAME}" --context "${K8S_CTX_0}" -n "${MDB_NS}" --timeout=600s对于使用外部应用程序数据库的 MongoDB Ops Manager 资源,Kubernetes 操作符不管理内部应用程序数据库,因此 status.applicationDatabase.phase 报告 Disabled。这是预期的,并不是错误。
验证部署。
在多集群部署中,应用程序数据库 StatefulSet 在成员集群中运行, Kubernetes Operator 使用 mongodbmulticluster 标签而不是所有者引用来跟踪其所有权。
确认应用程序数据库 Pod 正在每个成员集群中运行,并且每个 StatefulSet 都带有设立为
<namespace>-<appdb-name>的mongodbmulticluster标签:idx=0for ctx in "${K8S_CTX_1}" "${K8S_CTX_2}"; do sts="${APPDB_NAME}-${idx}" kubectl get pods --context "${ctx}" -n "${MDB_NS}" \ -l "mongodbmulticluster=${MDB_NS}-${APPDB_NAME}" kubectl get statefulset "${sts}" --context "${ctx}" -n "${MDB_NS}" \ -o jsonpath='{.metadata.labels.mongodbmulticluster}{"\n"}' idx=$((idx + 1))done确认 Kubernetes 操作符已创建用于主节点 (primary node in the replica set) MongoDB Ops Manager 实例的连接字符串密钥:
kubectl get secret "${APPDB_CONNECTION_STRING_SECRET}" \ --context "${K8S_CTX_0}" -n "${MDB_NS}"
常见的外部应用程序数据库问题
应用程序数据库代理无法下载二进制文件
如果应用程序数据库代理无法下载带有 x509: certificate signed by unknown authority 的MongoDB二进制文件,则 spec.security.tls.ca 中的 CA 捆绑包不包含签署 downloads.mongodb.com 的公共根。启用 TLS 后, MongoDB 助手会根据此捆绑包而不是系统信任存储来验证下载。使用自签名 CA 和主机的公共 CA 捆绑包重新创建 ConfigMap,如 TLS CA 步骤所示。
应用程序数据库 Pod 无法解析Ops Manager
如果应用程序数据库代理为管理Ops Manager服务日志Could not resolve host,则成员集群命名空间缺少 istio-injection=enabled 标签。如果没有 sidecar,Pod 就无法通过网格解析中央集群Ops Manager服务。按照命名空间步骤所示应用标签。
CA ConfigMap 因太长而被拒绝
如果Kubernetes拒绝带有 metadata.annotations: Too long 的 CA ConfigMap,则组合后的 CA 捆绑包将超过客户端kubectl apply 注解的大小限制。使用 kubectl apply --server-side --force-conflicts 应用 ConfigMap,或使用 kubectl create 创建 ConfigMap。
MongoDBMultiCluster 资源报告版本错误
如果外部应用程序数据库报告 Failed 并显示MongoDB版本不可用的消息,请将 spec.version设立为管理Ops Manager实例提供的版本。保持Ops Manager版本和应用程序数据库版本相同的主要版本。
操作符 拒绝外部应用程序数据库参考
spec.externalApplicationDatabaseRef.name 的值必须恰好为 <primary-om-name>-db,并且 MongoDBMultiCluster资源必须与Ops Manager资源位于同一命名空间中。
后续步骤
要备份外部应用程序数据库,启用对管理Ops Manager实例管理的项目中的 MongoDBMultiCluster资源启用备份。要学习;了解更多信息,请参阅配置MongoDB数据库备份。