Puede implementar un recurso de Ops Manager que utilice una base de datos de aplicación externa multiclúster: un recurso personalizado MongoDBMultiCluster con spec.role configurado como AppDB. Este recurso distribuye los miembros de la base de datos de aplicación entre varios clústeres de Kubernetes. Una segunda instancia de Ops Manager gestiona el recurso como un proyecto, lo que permite a Ops Manager realizar copias de seguridad y restaurar la base de datos de aplicación. Para obtener más información, consulte Copia de seguridad de la base de datos de aplicación de Ops Manager.
Este procedimiento implementa una nueva instancia de Ops Manager. Para convertir una instancia existente de Ops Manager que utiliza una base de datos de aplicaciones multiclúster administrada internamente, consulte Migrar una base de datos de aplicaciones multiclúster. Para la variante de este procedimiento para un solo clúster, consulte Implementar Ops Manager con una base de datos de aplicaciones externa.
Este procedimiento implementa los siguientes recursos:
Una instancia de Ops Manager de gestión con su propia base de datos de aplicaciones gestionada internamente, que se ejecuta en el clúster central. Esta instancia gestiona el proyecto que contiene la base de datos de aplicaciones externa.
Una base de datos de aplicación externa: un conjunto de réplicas MongoDBMultiCluster con
spec.roleconfigurado comoAppDB, llamado<primary-om-name>-db. El operador de Kubernetes crea un StatefulSet por cada clúster miembro, llamado<primary-om-name>-db-<cluster-index>.Una instancia principal de Ops Manager que omite
spec.applicationDatabasey hace referencia a la base de datos de la aplicación externa conspec.externalApplicationDatabaseRefestablecida en el tipoMongoDBMultiCluster.
Requisitos previos
Antes de comenzar, cumpla con las siguientes tareas:
Implemente tres clústeres de Kubernetes, cada uno con un
StorageClasspredeterminado: un clúster central y dos clústeres miembros.Implemente una malla de servicios que abarque los clústeres y proporcione descubrimiento de servicios entre clústeres. Los miembros de la base de datos de aplicaciones se comunican entre clústeres a través de la malla.
Este procedimiento utiliza Istio, pero puede usar cualquier malla de servicios que proporcione resolución de nombres de host FQDN entre pods en distintos clústeres. Una malla de servicios no es un requisito para una base de datos de aplicaciones externa multiclúster. Para un patrón de implementación sin malla, consulte Administrador de operaciones multiclúster sin malla de servicios.
Instale
kubectl,helmy el complementokubectl mongodb, y configúrelos para los tres clústeres.Obtener acceso a la gráfica Helm del operador de Kubernetes.
Considerations
Antes de la implementación, revise las siguientes consideraciones:
Establezca la versión de MongoDB Ops Manager y la versión de la base de datos de la aplicación en un par coherente. La instancia de gestión de MongoDB Ops Manager gestiona la base de datos de la aplicación externa, por lo tanto, la versión de la base de datos de la aplicación debe ser una versión de MongoDB que la instancia de gestión de MongoDB Ops Manager ofrece en su manifiesto de versión. Por ejemplo, un 8.0.x La instancia de Ops Manager ofrece 8.0.x Versiones de MongoDB, pero una 7.0.x La instancia de MongoDB Ops Manager no lo hace. Para encontrar un par compatible, consulte la matriz de compatibilidad de la base de datos de la aplicación.
Una base de datos de aplicación externa multiclúster requiere cifrado TLS.Cuando la base de datos de aplicación utiliza TLS, el agente de MongoDB valida cada conexión HTTPS saliente con el paquete de CA en
spec.security.tls.ca, incluida la descarga del binario de MongoDB desdedownloads.mongodb.com. El paquete de CA debe incluir las raíces públicas que firmandownloads.mongodb.comademás de su propia CA. Para configurar certificados TLS para una implementación multiclúster, consulte la sección "Administrar certificados TLS".El clúster central ejecuta el operador de Kubernetes, ambas instancias de Ops Manager y contiene el recurso MongoDBMultiCluster. Los clústeres miembros ejecutan los pods de datos de la base de datos de la aplicación.
Procedimiento
Establezca las variables de entorno para la implementación.
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"El operador de Kubernetes requiere que la base de datos de la aplicación externa se llame <primary-om-name>-db, por lo que APPDB_NAME se deriva de PRIMARY_OM_NAME.
Cree el espacio de nombres en cada clúster.
El espacio de nombres debe existir en el clúster central y en ambos clústeres miembros. La etiqueta istio-injection=enabled agrega un contenedor auxiliar a los pods de la base de datos de aplicaciones para que sus agentes puedan resolver el servicio de administración de Ops Manager en todos los clústeres.
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}"doneInstale el operador de Kubernetes en modo multiclúster.
Configure las cuentas de servicio y los roles en todos los clústeres con el complemento kubectl mongodb, y luego instale el operador de Kubernetes en el clúster central con los clústeres miembros registrados. Para obtener más información, consulte los requisitos previos para la implementación en varios clústeres.
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=300sCrear el secreto de administrador de MongoDB Ops Manager.
Ambos recursos de MongoDB Ops Manager hacen referencia a este secreto con 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}"Instale cert-manager en el clúster central.
Los miembros de la base de datos de aplicaciones multiclúster utilizan TLS, por lo que cert-manager debe emitir la CA y el certificado del servidor de la base de datos de aplicaciones.
helm upgrade --install --kube-context "${K8S_CTX_0}" \ cert-manager jetstack/cert-manager \ --namespace "${CERT_MANAGER_NAMESPACE}" --create-namespace \ --set crds.enabled=trueConfigure la CA TLS.
Cree la cadena de firmas y publique la CA en un ConfigMap al que el operador de Kubernetes hace referencia como spec.security.tls.ca. El paquete combina su CA autofirmada con el paquete de CA pública del host, ya que el agente de MongoDB valida la descarga del binario de MongoDB desde downloads.mongodb.com con este paquete. El paquete combinado excede el límite de tamaño de la anotación kubectl apply del lado del cliente, por lo que se aplica el ConfigMap en el servidor.
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}"Generar el certificado del servidor de la base de datos de la aplicación.
El nombre secreto del certificado sigue la convención del operador de Kubernetes <certs-secret-prefix>-<appdb-name>-cert. La entrada comodín dnsNames abarca el FQDN del servicio de cada miembro de la base de datos de la aplicación en cada clúster.
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=120sImplementar la instancia de MongoDB Ops Manager de gestión.
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.2EOFLa configuración de correo de mms.* es obligatoria. Cuando mms.ignoreInitialUiSetup es true, la comprobación previa de MongoDB Ops Manager no inicia MongoDB Ops Manager a menos que mms.fromEmailAddr y la configuración de correo relacionada estén presentes.
Espere a que la instancia de gestión de MongoDB Ops Manager esté lista.
Espere a la base de datos de la aplicación gestionada internamente y al recurso de 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=1800sConfirme que la API pública de MongoDB Ops Manager responde a las solicitudes. Un
opsManager.phasedeRunningsignifica que el pod de MongoDB Ops Manager está en funcionamiento, pero la API que utiliza el operador de Kubernetes para crear el Proyecto de base de datos de la aplicación puede retrasarse unos segundos. Una respuesta401es la respuesta no autenticada esperada y significa que la API está lista: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 10doneConfirme que el operador de Kubernetes creó el secreto de la clave de API programática para la instancia de gestión de MongoDB Ops Manager:
kubectl get secret "${MANAGEMENT_OM_ADMIN_KEY_SECRET}" \ --context "${K8S_CTX_0}" -n "${MDB_NS}"
Crear el ConfigMap del Proyecto para la base de datos de la aplicación externa.
La entrada sslMMSCAConfigMap anuncia la CA en la que deben confiar los agentes de la base de datos de aplicaciones habilitados para TLS cuando se conectan a la instancia de administración de Ops Manager.
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 -Crear la base de datos externa de la aplicación.
Aplique el recurso MongoDBMultiCluster al clúster central. El operador de Kubernetes crea los miembros de la base de datos de la aplicación en los clústeres miembros.
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=1200sAl establecer spec.role en AppDB, el operador de Kubernetes configura la autenticación SCRAM para el recurso. Para obtener más información, consulte spec.role.
Implementar la instancia primaria de MongoDB Ops Manager.
Este recurso omite spec.applicationDatabase y hace referencia a la base de datos de la aplicación externa con kind establecido en 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.2EOFPara habilitar la copia de seguridad para sus implementaciones de MongoDB, establezca spec.backup.enabled en true en este recurso y configure el almacenamiento de snapshot. Para obtener más información, consulte Configurar el almacenamiento de copia de seguridad del sistema de archivos con el operador de Kubernetes.
Espere a que la instancia primaria de MongoDB Ops Manager esté lista.
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=600sEl operador de Kubernetes no gestiona una base de datos de la aplicación interna para un recurso de MongoDB Ops Manager que utiliza una base de datos de la aplicación externa, por lo que status.applicationDatabase.phase informa de Disabled. Esto es lo esperado y no es un error.
Verifique la implementación.
En una implementación de clústeres múltiples, los StatefulSets de la base de datos de aplicaciones se ejecutan en los clústeres miembros, y el operador de Kubernetes realiza un seguimiento de su propiedad con la etiqueta mongodbmulticluster en lugar de una referencia de propietario.
Confirme que los pods de la base de datos de la aplicación se estén ejecutando en cada clúster miembro y que cada StatefulSet tenga la etiqueta
mongodbmulticlusterestablecida en<namespace>-<appdb-name>: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))doneConfirme que el operador de Kubernetes creó el secreto de la cadena de conexión para la instancia principal de MongoDB Ops Manager:
kubectl get secret "${APPDB_CONNECTION_STRING_SECRET}" \ --context "${K8S_CTX_0}" -n "${MDB_NS}"
Problemas comunes de la base de datos de la aplicación externa
Los agentes de la base de datos de la aplicación fallan en la descarga binaria.
Si los agentes de la base de datos de la aplicación no logran descargar el binario de MongoDB con x509: certificate signed by unknown authority, el paquete de CA en spec.security.tls.ca no incluye las raíces públicas que firman downloads.mongodb.com. Con TLS habilitado, el agente de MongoDB valida la descarga con este paquete en lugar del almacén de confianza del sistema. Recree el ConfigMap con su CA autofirmada y el paquete de CA pública del host, como se muestra en el paso de TLS CA.
Los pods de la base de datos de la aplicación no pueden resolver Ops Manager.
Si los agentes de la base de datos de la aplicación registran Could not resolve host para el servicio de administración de Ops Manager, el espacio de nombres del clúster miembro no tiene la etiqueta istio-injection=enabled. Sin el contenedor auxiliar, los pods no pueden resolver el servicio de Ops Manager del clúster central a través de la malla. Aplique la etiqueta como se muestra en el paso del espacio de nombres.
El ConfigMap de CA es rechazado por ser demasiado largo.
Si Kubernetes rechaza el ConfigMap de CA con metadata.annotations: Too long, el paquete de CA combinado excede el límite de tamaño de la anotación kubectl apply del lado del cliente. Aplique el ConfigMap con kubectl apply --server-side --force-conflicts o créelo con kubectl create.
El recurso MongoDBMultiCluster informa un error de versión.
Si la base de datos de la aplicación externa informa Failed con un mensaje que indica que la versión de MongoDB no está disponible, establezca spec.version en una versión que ofrezca la instancia de Ops Manager. Mantenga la versión de Ops Manager y la de la base de datos de la aplicación en la misma versión principal.
El operador rechaza la referencia externa de la base de datos de la aplicación
El valor de spec.externalApplicationDatabaseRef.name debe ser exactamente <primary-om-name>-db, y el recurso MongoDBMultiCluster debe estar en el mismo espacio de nombres que el recurso Ops Manager.
Próximos pasos
Para realizar una copia de seguridad de la base de datos de la aplicación externa, habilite la copia de seguridad en el recurso MongoDBMultiCluster del proyecto que administra la instancia de Ops Manager. Para obtener más información, consulte Configurar copias de seguridad de la base de datos de MongoDB.