Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
/ / /

Implementar recursos de Ops Manager en varios clústeres de Kubernetes

Para que la implementación de Ops Manager y la base de datos de la aplicación en múltiples clústeres sean resilientes a caídas de centros de datos completos o zonas enteras, implemente la aplicación Ops Manager y la base de datos de la aplicación en múltiples clústeres de Kubernetes.

Para obtener más información sobre la arquitectura, la red, las limitaciones y el rendimiento de las implementaciones de múltiples clústeres de Kubernetes para los recursos de Ops Manager, consulta:

  • Arquitectura de Multi-Cluster Ops Manager

  • Limitaciones

  • Diferencias entre implementaciones de Ops Manager de un solo clúster y de múltiples clústeres

  • Diagrama de arquitectura

  • Red, balanceador de carga, service mesh

  • Rendimiento

Nota

El siguiente procedimiento requiere la implementación de una malla de servicios en todos los clústeres de Kubernetes. Si necesita implementar Ops Manager en varios clústeres de Kubernetes sin una malla de servicios, consulte Ops Manager multiclúster sin una malla de servicios para obtener más información.

Cuando implementas la Ops Manager aplicación y la base de datos de la aplicación utilizando el procedimiento en esta sección, tú:

  1. Usar GKE (Motor de Kubernetes de Google) e Istio service mesh como herramientas que ayudan a demostrar la implementación multinodo de clústeres de Kubernetes.

  2. Instale el operador de Kubernetes en uno de los clústeres de Kubernetes miembros, conocido como el clúster del operador. Este clúster actúa como un concentrador en el patrón "Hub and Spoke" que utiliza el operador de Kubernetes para gestionar implementaciones en varios clústeres de Kubernetes.

  3. Implementar el clúster de operadores en el $OPERATOR_NAMESPACE y configurar este clúster para que supervise $NAMESPACE y administre todos los clústeres de Kubernetes miembros.

  4. Implemente la base de datos de la aplicación y la aplicación Ops Manager en un clúster de Kubernetes de un solo nodo para demostrar la similitud entre una implementación multi-clúster y una implementación de clúster único. Un única implementación de clúster con spec.topology y spec.applicationDatabase.topology configurados en MultiCluster prepara la implementación para añadir más clústeres de Kubernetes.

  5. Implemente un conjunto de réplicas adicional de la base de datos de la aplicación en el segundo nodo del clúster de Kubernetes para mejorar la resiliencia de la base de datos de la aplicación. También implementa una instancia adicional de la aplicación de Ops Manager en el segundo nodo del clúster de Kubernetes.

  6. Cree certificados válidos para cifrado TLS, y establecer conexiones cifradas TLShacia y desde la aplicación de Ops Manager y entre los miembros del set de réplicas de la base de datos de la aplicación. Cuando se ejecuta sobre HTTPS, Ops Manager se ejecuta en el puerto 8443 por defecto.

  7. Active la copia de seguridad utilizando almacenamiento compatible con S3y implemente el daemon de copias de seguridad en el tercer clúster nodo de Kubernetes. Para simplificar la configuración de cubos de almacenamiento compatibles con S3, implemente el Operador MinIO. Active el daemon de copias de seguridad solo en un clúster nodo de su implementación. Sin embargo, también puede configurar otros nodos clúster para alojar los recursos del daemon de copias de seguridad. Solo se admiten copias de seguridad S3 en implementaciones de varios clústeres de Ops Manager.

Antes de que pueda iniciar la implementación, instale las siguientes herramientas requeridas:

Instalar la CLI de gcloud y autorizarla:

gcloud auth login

El plugin kubectl mongodb automatiza la configuración de los clústeres de Kubernetes. Esto permite al operador de Kubernetes implementar recursos, funciones necesarias y servicios para las cuentas de la aplicación Ops Manager, la base de datos de la aplicación y los recursos de MongoDB en estos clústeres.

Para instalar el plugin kubectl mongodb:

1

Descargue la versión deseada del paquete del operador de Kubernetes desde la Página de lanzamiento del Repositorio del operador MongoDB Controllers for Kubernetes.

El nombre del paquete utiliza este patrón: kubectl-mongodb_{{ .Version }}_{{ .Os }}_{{ .Arch }}.tar.gz.

Utilice uno de los siguientes paquetes:

  • kubectl-mongodb_{{ .Version }}_darwin_amd64.tar.gz

  • kubectl-mongodb_{{ .Version }}_darwin_arm64.tar.gz

  • kubectl-mongodb_{{ .Version }}_linux_amd64.tar.gz

  • kubectl-mongodb_{{ .Version }}_linux_arm64.tar.gz

2

Desempaqueta el paquete, como en el siguiente ejemplo:

tar -zxvf kubectl-mongodb_<version>_darwin_amd64.tar.gz
3

Busque el binario kubectl-mongodb en el directorio descomprimido y muévalo a su destino deseado, dentro de PATH para el usuario Operador de Kubernetes, como se muestra en el siguiente ejemplo:

mv kubectl-mongodb /usr/local/bin/kubectl-mongodb

Ahora puedes ejecutar el plugin kubectl mongodb usando los siguientes comandos:

kubectl mongodb multicluster setup
kubectl mongodb multicluster recover

Para obtener más información sobre los indicadores admitidos, consulte la Referencia del complemento kubectl de MongoDB.

Clonar el repositorio de Controladores de MongoDB para Kubernetes operador, cambiar al directorio mongodb-kubernetes y obtener la versión actual.

git clone https://github.com/mongodb/mongodb-kubernetes.git
cd mongodb-kubernetes
git checkout 1.4.0
cd public/architectures

Importante

Algunos pasos en esta guía solo funcionan si se ejecutan desde el directorio public/samples/ops-manager-multi-cluster.

Todos los pasos en esta guía hacen referencia a las variables de entorno definidas en env_variables.sh.

1export MDB_GKE_PROJECT="### Set your GKE project name here ###"
2
3export NAMESPACE="mongodb"
4export OPERATOR_NAMESPACE="mongodb-operator"
5
6# comma-separated key=value pairs
7# export OPERATOR_ADDITIONAL_HELM_VALUES=""
8
9# Adjust the values for each Kubernetes cluster in your deployment.
10# The deployment script references the following variables to get values for each cluster.
11export K8S_CLUSTER_0="k8s-mdb-0"
12export K8S_CLUSTER_0_ZONE="europe-central2-a"
13export K8S_CLUSTER_0_NUMBER_OF_NODES=3
14export K8S_CLUSTER_0_MACHINE_TYPE="e2-standard-4"
15export K8S_CLUSTER_0_CONTEXT_NAME="gke_${MDB_GKE_PROJECT}_${K8S_CLUSTER_0_ZONE}_${K8S_CLUSTER_0}"
16
17export K8S_CLUSTER_1="k8s-mdb-1"
18export K8S_CLUSTER_1_ZONE="europe-central2-b"
19export K8S_CLUSTER_1_NUMBER_OF_NODES=3
20export K8S_CLUSTER_1_MACHINE_TYPE="e2-standard-4"
21export K8S_CLUSTER_1_CONTEXT_NAME="gke_${MDB_GKE_PROJECT}_${K8S_CLUSTER_1_ZONE}_${K8S_CLUSTER_1}"
22
23export K8S_CLUSTER_2="k8s-mdb-2"
24export K8S_CLUSTER_2_ZONE="europe-central2-c"
25export K8S_CLUSTER_2_NUMBER_OF_NODES=1
26export K8S_CLUSTER_2_MACHINE_TYPE="e2-standard-4"
27export K8S_CLUSTER_2_CONTEXT_NAME="gke_${MDB_GKE_PROJECT}_${K8S_CLUSTER_2_ZONE}_${K8S_CLUSTER_2}"
28
29# Comment out the following line so that the script does not create preemptible nodes.
30# DO NOT USE preemptible nodes in production.
31export GKE_SPOT_INSTANCES_SWITCH="--preemptible"
32
33export S3_OPLOG_BUCKET_NAME=s3-oplog-store
34export S3_SNAPSHOT_BUCKET_NAME=s3-snapshot-store
35
36# minio defaults
37export S3_ENDPOINT="minio.tenant-tiny.svc.cluster.local"
38export S3_ACCESS_KEY="console"
39export S3_SECRET_KEY="console123"
40
41export OFFICIAL_OPERATOR_HELM_CHART="mongodb/mongodb-kubernetes"
42export OPERATOR_HELM_CHART="${OFFICIAL_OPERATOR_HELM_CHART}"
43
44# (Optional) Change the following setting when using the external URL.
45# This env variable is used in OpenSSL configuration to generate
46# server certificates for Ops Manager Application.
47export OPS_MANAGER_EXTERNAL_DOMAIN="om-svc.${NAMESPACE}.svc.cluster.local"
48
49export OPS_MANAGER_VERSION="7.0.4"
50export APPDB_VERSION="7.0.9-ubi8"

Ajusta la configuración en el ejemplo anterior según tus necesidades, tal como se indica en los comentarios, y cárgala en tu shell de la siguiente manera:

source env_variables.sh

Importante

Cada vez que actualices env_variables.sh, ejecuta source env_variables.sh para garantizar que los scripts en esta sección utilicen variables actualizadas.

Este procedimiento se aplica a la implementación de una instancia de Ops Manager en varios clústeres de Kubernetes.

1

Puedes omitir este paso si ya tienes instalados y configurados tus propios clústeres de Kubernetes con una malla de servicios.

  1. Crea tres clústeres de GKE (Google Kubernetes Engine):

    1gcloud container clusters create "${K8S_CLUSTER_0}" \
    2 --zone="${K8S_CLUSTER_0_ZONE}" \
    3 --num-nodes="${K8S_CLUSTER_0_NUMBER_OF_NODES}" \
    4 --machine-type "${K8S_CLUSTER_0_MACHINE_TYPE}" \
    5 ${GKE_SPOT_INSTANCES_SWITCH:-""}
    1gcloud container clusters create "${K8S_CLUSTER_1}" \
    2 --zone="${K8S_CLUSTER_1_ZONE}" \
    3 --num-nodes="${K8S_CLUSTER_1_NUMBER_OF_NODES}" \
    4 --machine-type "${K8S_CLUSTER_1_MACHINE_TYPE}" \
    5 ${GKE_SPOT_INSTANCES_SWITCH:-""}
    1gcloud container clusters create "${K8S_CLUSTER_2}" \
    2 --zone="${K8S_CLUSTER_2_ZONE}" \
    3 --num-nodes="${K8S_CLUSTER_2_NUMBER_OF_NODES}" \
    4 --machine-type "${K8S_CLUSTER_2_MACHINE_TYPE}" \
    5 ${GKE_SPOT_INSTANCES_SWITCH:-""}
  2. Establezca su proyecto gcloud predeterminado:

    1gcloud config set project "${MDB_GKE_PROJECT}"
  3. Obtener credenciales y guardar contextos en el kubeconfig archivo actual. De forma predeterminada, este archivo se encuentra en el ~/.kube/config directorio y se referencia mediante la $KUBECONFIG variable de entorno.

    1gcloud container clusters get-credentials "${K8S_CLUSTER_0}" --zone="${K8S_CLUSTER_0_ZONE}"
    2gcloud container clusters get-credentials "${K8S_CLUSTER_1}" --zone="${K8S_CLUSTER_1_ZONE}"
    3gcloud container clusters get-credentials "${K8S_CLUSTER_2}" --zone="${K8S_CLUSTER_2_ZONE}"

    Todos los comandos de kubectl hacen referencia a estos contextos usando las siguientes variables:

    • $K8S_CLUSTER_0_CONTEXT_NAME

    • $K8S_CLUSTER_1_CONTEXT_NAME

    • $K8S_CLUSTER_2_CONTEXT_NAME

  4. Verifica que kubectl tenga acceso a los clústeres de Kubernetes:

    1echo "Nodes in cluster ${K8S_CLUSTER_0_CONTEXT_NAME}"
    2kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" get nodes
    3echo; echo "Nodes in cluster ${K8S_CLUSTER_1_CONTEXT_NAME}"
    4kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" get nodes
    5echo; echo "Nodes in cluster ${K8S_CLUSTER_2_CONTEXT_NAME}"
    6kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" get nodes
    1Nodes in cluster gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
    2NAME STATUS ROLES AGE VERSION
    3gke-k8s-mdb-0-default-pool-267f1e8f-d0dg Ready <none> 38m v1.29.7-gke.1104000
    4gke-k8s-mdb-0-default-pool-267f1e8f-pmgh Ready <none> 38m v1.29.7-gke.1104000
    5gke-k8s-mdb-0-default-pool-267f1e8f-vgj9 Ready <none> 38m v1.29.7-gke.1104000
    6
    7Nodes in cluster gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1
    8NAME STATUS ROLES AGE VERSION
    9gke-k8s-mdb-1-default-pool-263d341f-3tbp Ready <none> 38m v1.29.7-gke.1104000
    10gke-k8s-mdb-1-default-pool-263d341f-4f26 Ready <none> 38m v1.29.7-gke.1104000
    11gke-k8s-mdb-1-default-pool-263d341f-z751 Ready <none> 38m v1.29.7-gke.1104000
    12
    13Nodes in cluster gke_scratch-kubernetes-team_europe-central2-c_k8s-mdb-2
    14NAME STATUS ROLES AGE VERSION
    15gke-k8s-mdb-2-default-pool-d0da5fd1-chm1 Ready <none> 38m v1.29.7-gke.1104000
  5. Instale Istio la service mesh para permitir la resolución cruzada de DNS y la conectividad de red entre clústeres de Kubernetes:

    1CTX_CLUSTER1=${K8S_CLUSTER_0_CONTEXT_NAME} \
    2CTX_CLUSTER2=${K8S_CLUSTER_1_CONTEXT_NAME} \
    3CTX_CLUSTER3=${K8S_CLUSTER_2_CONTEXT_NAME} \
    4ISTIO_VERSION="1.20.2" \
    5../multi-cluster/install_istio_separate_network.sh
2

Nota

Para habilitar la inyección sidecar en Istio, los siguientes comandos añaden las etiquetas istio-injection=enabled a los espacios de nombres $OPERATOR_NAMESPACE y mongodb en cada clúster nodo. Si utilizas otra malla de servicios, configúrala para gestionar el tráfico de red en los espacios de nombres creados.

  • Cree un namespace separado, mongodb-operator, referenciado por la $OPERATOR_NAMESPACE variable de entorno para la implementación del operador de Kubernetes.

  • Cree el mismo $OPERATOR_NAMESPACE en cada clúster miembro de Kubernetes. Esto es necesario para que el complemento kubectl mongodb pueda crear una cuenta de servicio para el operador de Kubernetes en cada clúster miembro. El operador de Kubernetes utiliza estas cuentas de servicio en el clúster del operador para realizar operaciones en cada clúster miembro.

    1kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" create namespace "${OPERATOR_NAMESPACE}"
    2kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" label namespace "${OPERATOR_NAMESPACE}" istio-injection=enabled --overwrite
    3
    4kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" create namespace "${OPERATOR_NAMESPACE}"
    5kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" label namespace "${OPERATOR_NAMESPACE}" istio-injection=enabled --overwrite
    6
    7kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" create namespace "${OPERATOR_NAMESPACE}"
    8kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" label namespace "${OPERATOR_NAMESPACE}" istio-injection=enabled --overwrite
  • En cada clúster miembro, incluido el clúster que actúa como clúster de operador, cree otro espacio de nombres independiente, mongodb. El operador de Kubernetes utiliza este espacio de nombres para los recursos y componentes de Ops Manager.

    1kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" create namespace "${NAMESPACE}"
    2kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" label namespace "${NAMESPACE}" istio-injection=enabled --overwrite
    3
    4kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" create namespace "${NAMESPACE}"
    5kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" label namespace "${NAMESPACE}" istio-injection=enabled --overwrite
    6
    7kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" create namespace "${NAMESPACE}"
    8kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" label namespace "${NAMESPACE}" istio-injection=enabled --overwrite
3

Este paso es opcional si utilizas gráficas e imágenes oficiales de Helm provenientes del registro Quay.

1kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${OPERATOR_NAMESPACE}" create secret generic "image-registries-secret" \
2 --from-file=.dockerconfigjson="${HOME}/.docker/config.json" --type=kubernetes.io/dockerconfigjson
3kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" create secret generic "image-registries-secret" \
4 --from-file=.dockerconfigjson="${HOME}/.docker/config.json" --type=kubernetes.io/dockerconfigjson
5kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" create secret generic "image-registries-secret" \
6 --from-file=.dockerconfigjson="${HOME}/.docker/config.json" --type=kubernetes.io/dockerconfigjson
7kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "${NAMESPACE}" create secret generic "image-registries-secret" \
8 --from-file=.dockerconfigjson="${HOME}/.docker/config.json" --type=kubernetes.io/dockerconfigjson
4

Los siguientes scripts opcionales verifican si el service mesh está configurado correctamente para la resolución de DNS entre clústeres y la conectividad.

  1. Ejecute este script en el clúster 0:

    1kubectl apply --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2 apiVersion: apps/v1
    3 kind: StatefulSet
    4 metadata:
    5 name: echoserver0
    6 spec:
    7 replicas: 1
    8 selector:
    9 matchLabels:
    10 app: echoserver0
    11 template:
    12 metadata:
    13 labels:
    14 app: echoserver0
    15 spec:
    16 containers:
    17 - image: k8s.gcr.io/echoserver:1.10
    18 imagePullPolicy: Always
    19 name: echoserver0
    20 ports:
    21 - containerPort: 8080
    22EOF
  2. Ejecute este script en el clúster 1:

    1kubectl apply --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2 apiVersion: apps/v1
    3 kind: StatefulSet
    4 metadata:
    5 name: echoserver1
    6 spec:
    7 replicas: 1
    8 selector:
    9 matchLabels:
    10 app: echoserver1
    11 template:
    12 metadata:
    13 labels:
    14 app: echoserver1
    15 spec:
    16 containers:
    17 - image: k8s.gcr.io/echoserver:1.10
    18 imagePullPolicy: Always
    19 name: echoserver1
    20 ports:
    21 - containerPort: 8080
    22EOF
  3. Ejecute este script en el clúster 2:

    1kubectl apply --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2 apiVersion: apps/v1
    3 kind: StatefulSet
    4 metadata:
    5 name: echoserver2
    6 spec:
    7 replicas: 1
    8 selector:
    9 matchLabels:
    10 app: echoserver2
    11 template:
    12 metadata:
    13 labels:
    14 app: echoserver2
    15 spec:
    16 containers:
    17 - image: k8s.gcr.io/echoserver:1.10
    18 imagePullPolicy: Always
    19 name: echoserver2
    20 ports:
    21 - containerPort: 8080
    22EOF
  4. Ejecute este script para esperar la creación de StatefulSets:

    1kubectl wait --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" --for=condition=ready pod -l statefulset.kubernetes.io/pod-name=echoserver0-0 --timeout=60s
    2kubectl wait --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" --for=condition=ready pod -l statefulset.kubernetes.io/pod-name=echoserver1-0 --timeout=60s
    3kubectl wait --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "${NAMESPACE}" --for=condition=ready pod -l statefulset.kubernetes.io/pod-name=echoserver2-0 --timeout=60s
  5. Crea un servicio de Pods en el clúster 0:

    1kubectl apply --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2apiVersion: v1
    3kind: Service
    4metadata:
    5 name: echoserver0-0
    6spec:
    7 ports:
    8 - port: 8080
    9 targetPort: 8080
    10 protocol: TCP
    11 selector:
    12 statefulset.kubernetes.io/pod-name: "echoserver0-0"
    13EOF
  6. Crea un servicio de Pods en el clúster 1:

    1kubectl apply --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2apiVersion: v1
    3kind: Service
    4metadata:
    5 name: echoserver1-0
    6spec:
    7 ports:
    8 - port: 8080
    9 targetPort: 8080
    10 protocol: TCP
    11 selector:
    12 statefulset.kubernetes.io/pod-name: "echoserver1-0"
    13EOF
  7. Crea un servicio de Pods en el clúster 2:

    1kubectl apply --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2apiVersion: v1
    3kind: Service
    4metadata:
    5 name: echoserver2-0
    6spec:
    7 ports:
    8 - port: 8080
    9 targetPort: 8080
    10 protocol: TCP
    11 selector:
    12 statefulset.kubernetes.io/pod-name: "echoserver2-0"
    13EOF
  8. Crear un servicio round robin en el clúster 0:

    1kubectl apply --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2apiVersion: v1
    3kind: Service
    4metadata:
    5 name: echoserver
    6spec:
    7 ports:
    8 - port: 8080
    9 targetPort: 8080
    10 protocol: TCP
    11 selector:
    12 app: echoserver0
    13EOF
  9. Crear un servicio round robin en el clúster 1:

    1kubectl apply --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2apiVersion: v1
    3kind: Service
    4metadata:
    5 name: echoserver
    6spec:
    7 ports:
    8 - port: 8080
    9 targetPort: 8080
    10 protocol: TCP
    11 selector:
    12 app: echoserver1
    13EOF
  10. Crear un servicio round robin en el clúster 2:

    1kubectl apply --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2apiVersion: v1
    3kind: Service
    4metadata:
    5 name: echoserver
    6spec:
    7 ports:
    8 - port: 8080
    9 targetPort: 8080
    10 protocol: TCP
    11 selector:
    12 app: echoserver2
    13EOF
  11. Verifica el Pod 0 del clúster 1:

    1source_cluster=${K8S_CLUSTER_1_CONTEXT_NAME}
    2target_pod="echoserver0-0"
    3source_pod="echoserver1-0"
    4target_url="http://${target_pod}.${NAMESPACE}.svc.cluster.local:8080"
    5echo "Checking cross-cluster DNS resolution and connectivity from ${source_pod} in ${source_cluster} to ${target_pod}"
    6out=$(kubectl exec --context "${source_cluster}" -n "${NAMESPACE}" "${source_pod}" -- \
    7 /bin/bash -c "curl -v ${target_url}" 2>&1);
    8grep "Hostname: ${target_pod}" &>/dev/null <<< "${out}" && echo "SUCCESS" || (echo "ERROR: ${out}" && return 1)
    1Checking cross-cluster DNS resolution and connectivity from echoserver1-0 in gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1 to echoserver0-0
    2SUCCESS
  12. Verifica el Pod 1 del clúster 0:

    1source_cluster=${K8S_CLUSTER_0_CONTEXT_NAME}
    2target_pod="echoserver1-0"
    3source_pod="echoserver0-0"
    4target_url="http://${target_pod}.${NAMESPACE}.svc.cluster.local:8080"
    5echo "Checking cross-cluster DNS resolution and connectivity from ${source_pod} in ${source_cluster} to ${target_pod}"
    6out=$(kubectl exec --context "${source_cluster}" -n "${NAMESPACE}" "${source_pod}" -- \
    7 /bin/bash -c "curl -v ${target_url}" 2>&1);
    8grep "Hostname: ${target_pod}" &>/dev/null <<< "${out}" && echo "SUCCESS" || (echo "ERROR: ${out}" && return 1)
    1Checking cross-cluster DNS resolution and connectivity from echoserver0-0 in gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0 to echoserver1-0
    2SUCCESS
  13. Verifica el Pod 1 del clúster 2:

    1source_cluster=${K8S_CLUSTER_2_CONTEXT_NAME}
    2target_pod="echoserver1-0"
    3source_pod="echoserver2-0"
    4target_url="http://${target_pod}.${NAMESPACE}.svc.cluster.local:8080"
    5echo "Checking cross-cluster DNS resolution and connectivity from ${source_pod} in ${source_cluster} to ${target_pod}"
    6out=$(kubectl exec --context "${source_cluster}" -n "${NAMESPACE}" "${source_pod}" -- \
    7 /bin/bash -c "curl -v ${target_url}" 2>&1);
    8grep "Hostname: ${target_pod}" &>/dev/null <<< "${out}" && echo "SUCCESS" || (echo "ERROR: ${out}" && return 1)
    1Checking cross-cluster DNS resolution and connectivity from echoserver2-0 in gke_scratch-kubernetes-team_europe-central2-c_k8s-mdb-2 to echoserver1-0
    2SUCCESS
  1. Verifica el Pod 2 del clúster 0:

    1source_cluster=${K8S_CLUSTER_0_CONTEXT_NAME}
    2target_pod="echoserver2-0"
    3source_pod="echoserver0-0"
    4target_url="http://${target_pod}.${NAMESPACE}.svc.cluster.local:8080"
    5echo "Checking cross-cluster DNS resolution and connectivity from ${source_pod} in ${source_cluster} to ${target_pod}"
    6out=$(kubectl exec --context "${source_cluster}" -n "${NAMESPACE}" "${source_pod}" -- \
    7 /bin/bash -c "curl -v ${target_url}" 2>&1);
    8grep "Hostname: ${target_pod}" &>/dev/null <<< "${out}" && echo "SUCCESS" || (echo "ERROR: ${out}" && return 1)
    1Checking cross-cluster DNS resolution and connectivity from echoserver0-0 in gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0 to echoserver2-0
    2SUCCESS
  2. Ejecute el script de limpieza:

    1kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" delete statefulset echoserver0
    2kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" delete statefulset echoserver1
    3kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "${NAMESPACE}" delete statefulset echoserver2
    4kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" delete service echoserver
    5kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" delete service echoserver
    6kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "${NAMESPACE}" delete service echoserver
    7kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" delete service echoserver0-0
    8kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" delete service echoserver1-0
    9kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "${NAMESPACE}" delete service echoserver2-0
5

En este paso, utiliza el complemento kubectl mongodb para automatizar la configuración del clúster de Kubernetes que es necesaria para que el operador de Kubernetes administre cargas de trabajo en varios clústeres de Kubernetes.

Debido a que configuras los clústeres de Kubernetes antes de instalar el operador de Kubernetes, cuando implementas el operador de Kubernetes para la operación de clústeres múltiples de Kubernetes, toda la configuración necesaria para multi-clúster ya está en su lugar.

Como se indica en la descripción general, el operador de Kubernetes configura tres clústeres miembros que se pueden usar para implementar bases de datos MongoDB de Ops Manager. El primer clúster también se usa como clúster del operador, donde se instala el operador de Kubernetes y se implementan los recursos personalizados.

1kubectl mongodb multicluster setup \
2 --central-cluster="${K8S_CLUSTER_0_CONTEXT_NAME}" \
3 --member-clusters="${K8S_CLUSTER_0_CONTEXT_NAME},${K8S_CLUSTER_1_CONTEXT_NAME},${K8S_CLUSTER_2_CONTEXT_NAME}" \
4 --member-cluster-namespace="${NAMESPACE}" \
5 --central-cluster-namespace="${OPERATOR_NAMESPACE}" \
6 --create-service-account-secrets \
7 --install-database-roles=true \
8 --image-pull-secrets=image-registries-secret
1Ensured namespaces exist in all clusters.
2creating operator cluster roles in cluster: gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
3creating member roles in cluster: gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1
4creating member roles in cluster: gke_scratch-kubernetes-team_europe-central2-c_k8s-mdb-2
5Ensured ServiceAccounts and Roles.
6Creating KubeConfig secret mongodb-operator/mongodb-enterprise-operator-multi-cluster-kubeconfig in cluster gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
7Ensured database Roles in member clusters.
8Creating Member list Configmap mongodb-operator/mongodb-kubernetes-operator-member-list in cluster gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
6
  1. Añade y actualiza el repositorio Helm de MongoDB. Verifica que la caché local de Helm haga referencia a la versión correcta del operador de Kubernetes:

    1helm repo add mongodb https://mongodb.github.io/helm-charts
    2helm repo update mongodb
    3helm search repo "${OFFICIAL_OPERATOR_HELM_CHART}"
    1"mongodb" already exists with the same configuration, skipping
    2Hang tight while we grab the latest from your chart repositories...
    3...Successfully got an update from the "mongodb" chart repository
    4Update Complete. ⎈Happy Helming!⎈
    5NAME CHART VERSION APP VERSION DESCRIPTION
    6mongodb/mongodb-kubernetes 1.0.0 MongoDB Kubernetes Enterprise Operator
  2. Instale el Operador de Kubernetes en el $OPERATOR_NAMESPACE, configurado para supervisar $NAMESPACE y gestionar tres clústeres de Kubernetes nodos. En este punto del procedimiento, ServiceAccounts y roles ya están implementados por el kubectl mongodb plugin. Por lo tanto, los siguientes scripts omiten configurarlos y establecen operator.createOperatorServiceAccount=false y operator.createResourcesServiceAccountsAndRoles=false. Los scripts especifican la configuración multiCluster.clusters para indicar que la gráfica de Helm debe implementar el Operador de Kubernetes en modo multi-cluster.

    1helm upgrade --install \
    2 --debug \
    3 --kube-context "${K8S_CLUSTER_0_CONTEXT_NAME}" \
    4 mongodb-kubernetes-operator-multi-cluster \
    5 "${OPERATOR_HELM_CHART}" \
    6 --namespace="${OPERATOR_NAMESPACE}" \
    7 --set namespace="${OPERATOR_NAMESPACE}" \
    8 --set operator.namespace="${OPERATOR_NAMESPACE}" \
    9 --set operator.watchNamespace="${NAMESPACE}" \
    10 --set operator.name=mongodb-kubernetes-operator-multi-cluster \
    11 --set operator.createOperatorServiceAccount=false \
    12 --set operator.createResourcesServiceAccountsAndRoles=false \
    13 --set "multiCluster.clusters={${K8S_CLUSTER_0_CONTEXT_NAME},${K8S_CLUSTER_1_CONTEXT_NAME},${K8S_CLUSTER_2_CONTEXT_NAME}}" \
    14 --set "${OPERATOR_ADDITIONAL_HELM_VALUES:-"dummy=value"}"
    1Release "mongodb-kubernetes-operator-multi-cluster" does not exist. Installing it now.
    2name: mongodb-kubernetes-operator-multi-cluster
    3LAST DEPLOYED: Mon Aug 26 10:55:49 2024
    4NAMESPACE: mongodb-operator
    5STATUS: deployed
    6REVISION: 1
    7TEST SUITE: None
    8USER-SUPPLIED VALUES:
    9dummy: value
    10multiCluster:
    11 clusters:
    12 - gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
    13 - gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1
    14 - gke_scratch-kubernetes-team_europe-central2-c_k8s-mdb-2
    15namespace: mongodb-operator
    16operator:
    17 createOperatorServiceAccount: false
    18 createResourcesServiceAccountsAndRoles: false
    19 name: mongodb-kubernetes-operator-multi-cluster
    20 namespace: mongodb-operator
    21 watchNamespace: mongodb
    22
    23COMPUTED VALUES:
    24agent:
    25 name: mongodb-agent
    26 version: 107.0.0.8502-1
    27database:
    28 name: mongodb-kubernetes-database
    29 version: 1.27.0
    30dummy: value
    31initAppDb:
    32 name: mongodb-kubernetes-init-appdb
    33 version: 1.27.0
    34initDatabase:
    35 name: mongodb-kubernetes-init-database
    36 version: 1.27.0
    37initOpsManager:
    38 name: mongodb-kubernetes-init-ops-manager
    39 version: 1.27.0
    40managedSecurityContext: false
    41mongodb:
    42 appdbAssumeOldFormat: false
    43 imageType: ubi8
    44 name: mongodb-enterprise-server
    45 repo: quay.io/mongodb
    46mongodbLegacyAppDb:
    47 name: mongodb-kubernetes-appdb-database-ubi
    48 repo: quay.io/mongodb
    49multiCluster:
    50 clusterClientTimeout: 10
    51 clusters:
    52 - gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
    53 - gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1
    54 - gke_scratch-kubernetes-team_europe-central2-c_k8s-mdb-2
    55 kubeConfigSecretname: mongodb-enterprise-operator-multi-cluster-kubeconfig
    56 performFailOver: true
    57namespace: mongodb-operator
    58operator:
    59 additionalArguments: []
    60 affinity: {}
    61 createOperatorServiceAccount: false
    62 createResourcesServiceAccountsAndRoles: false
    63 deployment_name: mongodb-kubernetes-operator
    64 env: prod
    65 maxConcurrentReconciles: 1
    66 mdbDefaultArchitecture: non-static
    67 name: mongodb-kubernetes-operator-multi-cluster
    68 namespace: mongodb-operator
    69 nodeSelector: {}
    70 operator_image_name: mongodb-kubernetes-operator
    71 replicas: 1
    72 resources:
    73 limits:
    74 cpu: 1100m
    75 memory: 1Gi
    76 requests:
    77 cpu: 500m
    78 memory: 200Mi
    79 tolerations: []
    80 vaultSecretBackend:
    81 enabled: false
    82 tlsSecretRef: ""
    83 version: 1.27.0
    84 watchNamespace: mongodb
    85 watchedResources:
    86 - mongodb
    87 - opsmanagers
    88 - mongodbusers
    89 webhook:
    90 installClusterRole: true
    91 registerConfiguration: true
    92opsManager:
    93 name: mongodb-enterprise-ops-manager-ubi
    94registry:
    95 agent: quay.io/mongodb
    96 appDb: quay.io/mongodb
    97 database: quay.io/mongodb
    98 imagePullSecrets: null
    99 initAppDb: quay.io/mongodb
    100 initDatabase: quay.io/mongodb
    101 initOpsManager: quay.io/mongodb
    102 operator: quay.io/mongodb
    103 opsManager: quay.io/mongodb
    104 pullPolicy: Always
    105subresourceEnabled: true
    106
    107HOOKS:
    108MANIFEST:
    109---
    110kind: ClusterRole
    111apiVersion: rbac.authorization.k8s.io/v1
    112metadata:
    113 name: mongodb-kubernetes-operator-mongodb-webhook
    114rules:
    115 - apiGroups:
    116 - "admissionregistration.k8s.io"
    117 resources:
    118 - validatingwebhookconfigurations
    119 verbs:
    120 - get
    121 - create
    122 - update
    123 - delete
    124 - apiGroups:
    125 - ""
    126 resources:
    127 - services
    128 verbs:
    129 - get
    130 - list
    131 - watch
    132 - create
    133 - update
    134 - delete
    135---
    136kind: ClusterRoleBinding
    137apiVersion: rbac.authorization.k8s.io/v1
    138metadata:
    139 name: mongodb-kubernetes-operator-multi-cluster-mongodb-operator-webhook-binding
    140roleRef:
    141 apiGroup: rbac.authorization.k8s.io
    142 kind: ClusterRole
    143 name: mongodb-kubernetes-operator-mongodb-webhook
    144subjects:
    145 - kind: ServiceAccount
    146 name: mongodb-kubernetes-operator-multi-cluster
    147 namespace: mongodb-operator
    148---
    149apiVersion: apps/v1
    150kind: Deployment
    151metadata:
    152 name: mongodb-kubernetes-operator-multi-cluster
    153 namespace: mongodb-operator
    154spec:
    155 replicas: 1
    156 selector:
    157 matchLabels:
    158 app.kubernetes.io/component: controller
    159 app.kubernetes.io/name: mongodb-kubernetes-operator-multi-cluster
    160 app.kubernetes.io/instance: mongodb-kubernetes-operator-multi-cluster
    161 template:
    162 metadata:
    163 labels:
    164 app.kubernetes.io/component: controller
    165 app.kubernetes.io/name: mongodb-kubernetes-operator-multi-cluster
    166 app.kubernetes.io/instance: mongodb-kubernetes-operator-multi-cluster
    167 spec:
    168 serviceAccountName: mongodb-kubernetes-operator-multi-cluster
    169 securityContext:
    170 runAsNonRoot: true
    171 runAsUser: 2000
    172 containers:
    173 - name: mongodb-kubernetes-operator-multi-cluster
    174 image: "quay.io/mongodb/mongodb-kubernetes-operator:1.27.0"
    175 imagePullPolicy: Always
    176 args:
    177 - -watch-resource=mongodb
    178 - -watch-resource=opsmanagers
    179 - -watch-resource=mongodbusers
    180 - -watch-resource=mongodbmulticluster
    181 command:
    182 - /usr/local/bin/mongodb-kubernetes-operator
    183 volumeMounts:
    184 - mountPath: /etc/config/kubeconfig
    185 name: kube-config-volume
    186 resources:
    187 limits:
    188 cpu: 1100m
    189 memory: 1Gi
    190 requests:
    191 cpu: 500m
    192 memory: 200Mi
    193 env:
    194 - name: OPERATOR_ENV
    195 value: prod
    196 - name: MDB_DEFAULT_ARCHITECTURE
    197 value: non-static
    198 - name: WATCH_NAMESPACE
    199 value: "mongodb"
    200 - name: NAMESPACE
    201 valueFrom:
    202 fieldRef:
    203 fieldPath: metadata.namespace
    204 - name: CLUSTER_CLIENT_TIMEOUT
    205 value: "10"
    206 - name: IMAGE_PULL_POLICY
    207 value: Always
    208 # Database
    209 - name: MONGODB_ENTERPRISE_DATABASE_IMAGE
    210 value: quay.io/mongodb/mongodb-kubernetes-database
    211 - name: INIT_DATABASE_IMAGE_REPOSITORY
    212 value: quay.io/mongodb/mongodb-kubernetes-init-database
    213 - name: INIT_DATABASE_VERSION
    214 value: 1.27.0
    215 - name: DATABASE_VERSION
    216 value: 1.27.0
    217 # Ops Manager
    218 - name: OPS_MANAGER_IMAGE_REPOSITORY
    219 value: quay.io/mongodb/mongodb-enterprise-ops-manager-ubi
    220 - name: INIT_OPS_MANAGER_IMAGE_REPOSITORY
    221 value: quay.io/mongodb/mongodb-kubernetes-init-ops-manager
    222 - name: INIT_OPS_MANAGER_VERSION
    223 value: 1.27.0
    224 # AppDB
    225 - name: INIT_APPDB_IMAGE_REPOSITORY
    226 value: quay.io/mongodb/mongodb-kubernetes-init-appdb
    227 - name: INIT_APPDB_VERSION
    228 value: 1.27.0
    229 - name: OPS_MANAGER_IMAGE_PULL_POLICY
    230 value: Always
    231 - name: AGENT_IMAGE
    232 value: "quay.io/mongodb/mongodb-agent:107.0.0.8502-1"
    233 - name: MDB_AGENT_IMAGE_REPOSITORY
    234 value: "quay.io/mongodb/mongodb-agent"
    235 - name: MONGODB_IMAGE
    236 value: mongodb-enterprise-server
    237 - name: MONGODB_REPO_URL
    238 value: quay.io/mongodb
    239 - name: MDB_IMAGE_TYPE
    240 value: ubi8
    241 - name: PERFORM_FAILOVER
    242 value: 'true'
    243 - name: MDB_MAX_CONCURRENT_RECONCILES
    244 value: "1"
    245 volumes:
    246 - name: kube-config-volume
    247 secret:
    248 defaultMode: 420
    249 secretname: mongodb-enterprise-operator-multi-cluster-kubeconfig
  3. Verifica la implementación de Kubernetes Operator:

    1kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${OPERATOR_NAMESPACE}" rollout status deployment/mongodb-kubernetes-operator-multi-cluster
    2echo "Operator deployment in ${OPERATOR_NAMESPACE} namespace"
    3kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${OPERATOR_NAMESPACE}" get deployments
    4echo; echo "Operator pod in ${OPERATOR_NAMESPACE} namespace"
    5kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${OPERATOR_NAMESPACE}" get pods
    1Waiting for deployment "mongodb-kubernetes-operator-multi-cluster" rollout to finish: 0 of 1 updated replicas are available...
    2deployment "mongodb-kubernetes-operator-multi-cluster" successfully rolled out
    3Operator deployment in mongodb-operator namespace
    4NAME READY UP-TO-DATE AVAILABLE AGE
    5mongodb-kubernetes-operator-multi-cluster 1/1 1 1 10s
    6
    7Operator pod in mongodb-operator namespace
    8NAME READY STATUS RESTARTS AGE
    9mongodb-kubernetes-operator-multi-cluster-54d786b796-7l5ct 2/2 Running 1 (4s ago) 10s
7

En este paso, activa TLS para la base de datos de la aplicación y la aplicación Ops Manager. Si no desea utilizar TLS, elimine los siguientes campos de los recursos MongoDBOpsManager:

  1. Opcional. Generar claves y certificados:

    Utiliza la herramienta de línea de comandos openssl para generar ACs y certificados autofirmados con fines de prueba.

    1mkdir certs || true
    2
    3cat <<EOF >certs/ca.cnf
    4[ req ]
    5default_bits = 2048
    6prompt = no
    7default_md = sha256
    8distinguished_name = dn
    9x509_extensions = v3_ca
    10
    11[ dn ]
    12C=US
    13ST=New York
    14L=New York
    15O=Example Company
    16OU=IT Department
    17CN=exampleCA
    18
    19[ v3_ca ]
    20basicConstraints = CA:TRUE
    21keyUsage = critical, keyCertSign, cRLSign
    22subjectKeyIdentifier = hash
    23authorityKeyIdentifier = keyid:always,issuer
    24EOF
    25
    26cat <<EOF >certs/om.cnf
    27[ req ]
    28default_bits = 2048
    29prompt = no
    30default_md = sha256
    31distinguished_name = dn
    32req_extensions = req_ext
    33
    34[ dn ]
    35C=US
    36ST=New York
    37L=New York
    38O=Example Company
    39OU=IT Department
    40CN=${OPS_MANAGER_EXTERNAL_DOMAIN}
    41
    42[ req_ext ]
    43subjectAltName = @alt_names
    44keyUsage = critical, digitalSignature, keyEncipherment
    45extendedKeyUsage = serverAuth, clientAuth
    46
    47[ alt_names ]
    48DNS.1 = ${OPS_MANAGER_EXTERNAL_DOMAIN}
    49DNS.2 = om-svc.${NAMESPACE}.svc.cluster.local
    50EOF
    51
    52cat <<EOF >certs/appdb.cnf
    53[ req ]
    54default_bits = 2048
    55prompt = no
    56default_md = sha256
    57distinguished_name = dn
    58req_extensions = req_ext
    59
    60[ dn ]
    61C=US
    62ST=New York
    63L=New York
    64O=Example Company
    65OU=IT Department
    66CN=AppDB
    67
    68[ req_ext ]
    69subjectAltName = @alt_names
    70keyUsage = critical, digitalSignature, keyEncipherment
    71extendedKeyUsage = serverAuth, clientAuth
    72
    73[ alt_names ]
    74# multi-cluster mongod hostnames from service for each pod
    75DNS.1 = *.${NAMESPACE}.svc.cluster.local
    76# single-cluster mongod hostnames from headless service
    77DNS.2 = *.om-db-svc.${NAMESPACE}.svc.cluster.local
    78EOF
    79
    80# generate CA keypair and certificate
    81openssl genrsa -out certs/ca.key 2048
    82openssl req -x509 -new -nodes -key certs/ca.key -days 1024 -out certs/ca.crt -config certs/ca.cnf
    83
    84# generate OpsManager's keypair and certificate
    85openssl genrsa -out certs/om.key 2048
    86openssl req -new -key certs/om.key -out certs/om.csr -config certs/om.cnf
    87
    88# generate AppDB's keypair and certificate
    89openssl genrsa -out certs/appdb.key 2048
    90openssl req -new -key certs/appdb.key -out certs/appdb.csr -config certs/appdb.cnf
    91
    92# generate certificates signed by CA for OpsManager and AppDB
    93openssl x509 -req -in certs/om.csr -CA certs/ca.crt -CAkey certs/ca.key -CAcreateserial -out certs/om.crt -days 365 -sha256 -extfile certs/om.cnf -extensions req_ext
    94openssl x509 -req -in certs/appdb.csr -CA certs/ca.crt -CAkey certs/ca.key -CAcreateserial -out certs/appdb.crt -days 365 -sha256 -extfile certs/appdb.cnf -extensions req_ext
  2. Crea secretos con claves TLS:

    Si prefieres usar tus propias claves y certificados, omite el paso anterior de generación y coloca las claves y certificados en los siguientes archivos:

    • certs/ca.crt - Certificados CA. estos no son necesarios al utilizar certificados de confianza.

    • certs/appdb.key - llave privada para la base de datos de la aplicación.

    • certs/appdb.crt - certificado para la Base de Datos de la Aplicación.

    • certs/om.key - clave privada para Ops Manager.

    • certs/om.crt - certificado para Ops Manager.

    1kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" create secret tls cert-prefix-om-cert \
    2 --cert=certs/om.crt \
    3 --key=certs/om.key
    4
    5kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" create secret tls cert-prefix-om-db-cert \
    6 --cert=certs/appdb.crt \
    7 --key=certs/appdb.key
    8
    9kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" create configmap om-cert-ca --from-file="mms-ca.crt=certs/ca.crt"
    10kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" create configmap appdb-cert-ca --from-file="ca-pem=certs/ca.crt"
8

En este punto, ha preparado el entorno y el operador de Kubernetes para implementar el recurso Ops Manager.

  1. Crea las credenciales necesarias para el usuario administrador de Ops Manager que creará el operador de Kubernetes después de implementar la instancia de Ops Manager aplicación:

    1kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" --namespace "${NAMESPACE}" create secret generic om-admin-user-credentials \
    2 --from-literal=Username="admin" \
    3 --from-literal=Password="Passw0rd@" \
    4 --from-literal=FirstName="Jane" \
    5 --from-literal=LastName="Doe"
  2. Implemente el MongoDBOpsManager recurso personalizado más simple posible (con TLS habilitado) en un solo clúster miembro, también conocido como clúster del operador.

    Esta implementación es casi la misma que para el modo de clúster único, pero con spec.topology y spec.applicationDatabase.topology configurados MultiCluster en.

    Implementar de esta manera muestra que la implementación de un solo clúster de Kubernetes es un caso especial de implementación de clústeres multi-Kubernetes en un solo clúster nodo de Kubernetes. Puedes iniciar la implementación de la aplicación de Ops Manager y la base de datos de la aplicación en tantos clústeres de Kubernetes como sea necesario desde el principio, y no es necesario que comiences la implementación con un único clúster nodo de Kubernetes.

    En este punto, ya deberías haber preparado la implementación de Ops Manager para expandirse a más de un clúster de Kubernetes, lo cual harás más adelante en este procedimiento.

    1kubectl apply --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2apiVersion: mongodb.com/v1
    3kind: MongoDBOpsManager
    4metadata:
    5 name: om
    6spec:
    7 topology: MultiCluster
    8 version: "${OPS_MANAGER_VERSION}"
    9 adminCredentials: om-admin-user-credentials
    10 security:
    11 certsSecretPrefix: cert-prefix
    12 tls:
    13 ca: om-cert-ca
    14 clusterSpecList:
    15 - clusterName: "${K8S_CLUSTER_0_CONTEXT_NAME}"
    16 members: 1
    17 applicationDatabase:
    18 version: "${APPDB_VERSION}"
    19 topology: MultiCluster
    20 security:
    21 certsSecretPrefix: cert-prefix
    22 tls:
    23 ca: appdb-cert-ca
    24 clusterSpecList:
    25 - clusterName: "${K8S_CLUSTER_0_CONTEXT_NAME}"
    26 members: 3
    27 backup:
    28 enabled: false
    29EOF
  3. Espere a que el operador de Kubernetes retome el trabajo y alcance el estado status.applicationDatabase.phase=Pending. Espere a que se completen las implementaciones de la base de datos de la aplicación y del administrador de operaciones.

    1echo "Waiting for Application Database to reach Pending phase..."
    2kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.applicationDatabase.phase}'=Pending opsmanager/om --timeout=30s
    1Waiting for Application Database to reach Pending phase...
    2mongodbopsmanager.mongodb.com/om condition met
  4. Implementar Ops Manager. El operador de Kubernetes implementa Ops Manager siguiendo estos pasos:

    • Implementa los nodos del set de réplicas de la Base de datos de la aplicación y espera que los procesos de MongoDB en el set de réplicas comiencen a ejecutarse.

    • Implementa la instancia de la aplicación Ops Manager con la cadena de conexión de la base de datos de la aplicación y espera que esté lista.

    • Agrega los contenedores de supervisión de MongoDB Agent a cada pod de la base de datos de la aplicación.

    • Espera a que tanto la aplicación Ops Manager como los pods de la base de datos de la aplicación comiencen a ejecutarse.

    1echo "Waiting for Application Database to reach Running phase..."
    2kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.applicationDatabase.phase}'=Running opsmanager/om --timeout=900s
    3echo; echo "Waiting for Ops Manager to reach Running phase..."
    4kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.opsManager.phase}'=Running opsmanager/om --timeout=900s
    5echo; echo "Waiting for Application Database to reach Pending phase (enabling monitoring)..."
    6kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.applicationDatabase.phase}'=Running opsmanager/om --timeout=900s
    7echo "Waiting for Application Database to reach Running phase..."
    8kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.applicationDatabase.phase}'=Running opsmanager/om --timeout=900s
    9echo; echo "Waiting for Ops Manager to reach Running phase..."
    10kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.opsManager.phase}'=Running opsmanager/om --timeout=900s
    11echo; echo "MongoDBOpsManager resource"
    12kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" get opsmanager/om
    13echo; echo "Pods running in cluster ${K8S_CLUSTER_0_CONTEXT_NAME}"
    14kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" get pods
    15echo; echo "Pods running in cluster ${K8S_CLUSTER_1_CONTEXT_NAME}"
    16kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" get pods
    1Waiting for Application Database to reach Running phase...
    2mongodbopsmanager.mongodb.com/om condition met
    3
    4Waiting for Ops Manager to reach Running phase...
    5mongodbopsmanager.mongodb.com/om condition met
    6
    7Waiting for Application Database to reach Pending phase (enabling monitoring)...
    8mongodbopsmanager.mongodb.com/om condition met
    9Waiting for Application Database to reach Running phase...
    10mongodbopsmanager.mongodb.com/om condition met
    11
    12Waiting for Ops Manager to reach Running phase...
    13mongodbopsmanager.mongodb.com/om condition met
    14
    15MongoDBOpsManager resource
    16NAME REPLICAS VERSION STATE (OPSMANAGER) STATE (APPDB) STATE (BACKUP) AGE WARNINGS
    17om 7.0.4 Running Running Disabled 13m
    18
    19Pods running in cluster gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
    20NAME READY STATUS RESTARTS AGE
    21om-0-0 2/2 Running 0 10m
    22om-db-0-0 4/4 Running 0 69s
    23om-db-0-1 4/4 Running 0 2m12s
    24om-db-0-2 4/4 Running 0 3m32s
    25
    26Pods running in cluster gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1

    Ahora que ha implementado un clúster de un solo miembro en un modo de múltiples clústeres, puede reconfigurar esta implementación para abarcar más de un clúster de Kubernetes.

  5. En el segundo clúster de miembros, implemente dos miembros adicionales del conjunto de réplicas de la base de datos de aplicaciones y una instancia adicional de la aplicación Ops Manager:

    1kubectl apply --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2apiVersion: mongodb.com/v1
    3kind: MongoDBOpsManager
    4metadata:
    5 name: om
    6spec:
    7 topology: MultiCluster
    8 version: "${OPS_MANAGER_VERSION}"
    9 adminCredentials: om-admin-user-credentials
    10 security:
    11 certsSecretPrefix: cert-prefix
    12 tls:
    13 ca: om-cert-ca
    14 clusterSpecList:
    15 - clusterName: "${K8S_CLUSTER_0_CONTEXT_NAME}"
    16 members: 1
    17 - clusterName: "${K8S_CLUSTER_1_CONTEXT_NAME}"
    18 members: 1
    19 applicationDatabase:
    20 version: "${APPDB_VERSION}"
    21 topology: MultiCluster
    22 security:
    23 certsSecretPrefix: cert-prefix
    24 tls:
    25 ca: appdb-cert-ca
    26 clusterSpecList:
    27 - clusterName: "${K8S_CLUSTER_0_CONTEXT_NAME}"
    28 members: 3
    29 - clusterName: "${K8S_CLUSTER_1_CONTEXT_NAME}"
    30 members: 2
    31 backup:
    32 enabled: false
    33EOF
  6. Espera a que el Operador de Kubernetes recoja el trabajo (fase pendiente):

    1echo "Waiting for Application Database to reach Pending phase..."
    2kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.applicationDatabase.phase}'=Pending opsmanager/om --timeout=30s
    1Waiting for Application Database to reach Pending phase...
    2mongodbopsmanager.mongodb.com/om condition met
  7. Espera a que Kubernetes operador termine de implementar todos los componentes:

    1echo "Waiting for Application Database to reach Running phase..."
    2kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.applicationDatabase.phase}'=Running opsmanager/om --timeout=600s
    3echo; echo "Waiting for Ops Manager to reach Running phase..."
    4kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.opsManager.phase}'=Running opsmanager/om --timeout=600s
    5echo; echo "MongoDBOpsManager resource"
    6kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" get opsmanager/om
    7echo; echo "Pods running in cluster ${K8S_CLUSTER_0_CONTEXT_NAME}"
    8kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" get pods
    9echo; echo "Pods running in cluster ${K8S_CLUSTER_1_CONTEXT_NAME}"
    10kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" get pods
    1Waiting for Application Database to reach Running phase...
    2mongodbopsmanager.mongodb.com/om condition met
    3
    4Waiting for Ops Manager to reach Running phase...
    5mongodbopsmanager.mongodb.com/om condition met
    6
    7MongoDBOpsManager resource
    8NAME REPLICAS VERSION STATE (OPSMANAGER) STATE (APPDB) STATE (BACKUP) AGE WARNINGS
    9om 7.0.4 Running Running Disabled 20m
    10
    11Pods running in cluster gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
    12NAME READY STATUS RESTARTS AGE
    13om-0-0 2/2 Running 0 2m56s
    14om-db-0-0 4/4 Running 0 7m48s
    15om-db-0-1 4/4 Running 0 8m51s
    16om-db-0-2 4/4 Running 0 10m
    17
    18Pods running in cluster gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1
    19NAME READY STATUS RESTARTS AGE
    20om-1-0 2/2 Running 0 3m27s
    21om-db-1-0 4/4 Running 0 6m32s
    22om-db-1-1 4/4 Running 0 5m5s
9

En una implementación de la aplicación Ops Manager en un clúster multiKubernetes, solo se puede configurar el 3almacenamiento de copias de seguridad basado en S. Este procedimiento se refiere a S3_* definido en env_variables.sh.

  1. opcional. Instala el Operador MinIO.

    Este procedimiento implementa un almacenamiento compatible con S3para tus copias de seguridad usando el MinIO Operador. Puedes omitir este paso si tienes AWS S3 u otros buckets compatibles con S3disponibles. Ajuste las variables S3_* correspondientes en env_variables.sh en este caso.

    1kubectl kustomize "github.com/minio/operator/resources/?timeout=120&ref=v5.0.12" | \
    2 kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" apply -f -
    3
    4kubectl kustomize "github.com/minio/operator/examples/kustomization/tenant-tiny?timeout=120&ref=v5.0.12" | \
    5 kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" apply -f -
    6
    7# add two buckets to the tenant config
    8kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "tenant-tiny" patch tenant/myminio \
    9 --type='json' \
    10 -p="[{\"op\": \"add\", \"path\": \"/spec/buckets\", \"value\": [{\"name\": \"${S3_OPLOG_BUCKET_NAME}\"}, {\"name\": \"${S3_SNAPSHOT_BUCKET_NAME}\"}]}]"
  2. Antes de configurar y habilitar la copia de seguridad, crea secretos:

    • s3-access-secret - contiene credenciales S.3

    • s3-ca-cert Contiene un certificado de CA que emitió el certificado de servidor del bucket. En el caso de la implementación de MinIO de ejemplo utilizada en este procedimiento, se utiliza el certificado de CA raíz de Kubernetes predeterminado para firmar el certificado. Dado que no es un certificado de CA de confianza pública, debe proporcionarlo para que Ops Manager pueda confiar en la conexión.

    Si usás certificados de confianza pública, podés omitir este paso y remover los valores de las configuraciones de spec.backup.s3Stores.customCertificateSecretRefs y spec.backup.s3OpLogStores.customCertificateSecretRefs.

    1kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" create secret generic s3-access-secret \
    2 --from-literal=accessKey="${S3_ACCESS_KEY}" \
    3 --from-literal=secretKey="${S3_SECRET_KEY}"
    4
    5# minio TLS secrets are signed with the default k8s root CA
    6kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" create secret generic s3-ca-cert \
    7 --from-literal=ca.crt="$(kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n kube-system get configmap kube-root-ca.crt -o jsonpath="{.data.ca\.crt}")"
10
  1. El operador de Kubernetes puede configurar e implementar todos los componentes, la aplicación Ops Manager, las instancias del daemon de copias de seguridad y los nodos del set de réplicas de la base de datos de la aplicación en cualquier combinación en cualquier clúster miembro para los cuales configure el operador de Kubernetes.

    Para ilustrar la flexibilidad de la configuración de implementación de clústeres múltiples de Kubernetes, se debe implementar solo una instancia del daemon de copias de seguridad en el tercer clúster nodo y se debe especificar cero nodos de daemon de copias de seguridad para el primer y segundo clúster.

    1kubectl apply --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" -f - <<EOF
    2apiVersion: mongodb.com/v1
    3kind: MongoDBOpsManager
    4metadata:
    5 name: om
    6spec:
    7 topology: MultiCluster
    8 version: "${OPS_MANAGER_VERSION}"
    9 adminCredentials: om-admin-user-credentials
    10 security:
    11 certsSecretPrefix: cert-prefix
    12 tls:
    13 ca: om-cert-ca
    14 clusterSpecList:
    15 - clusterName: "${K8S_CLUSTER_0_CONTEXT_NAME}"
    16 members: 1
    17 backup:
    18 members: 0
    19 - clusterName: "${K8S_CLUSTER_1_CONTEXT_NAME}"
    20 members: 1
    21 backup:
    22 members: 0
    23 - clusterName: "${K8S_CLUSTER_2_CONTEXT_NAME}"
    24 members: 0
    25 backup:
    26 members: 1
    27 configuration: # to avoid configuration wizard on first login
    28 mms.adminEmailAddr: email@example.com
    29 mms.fromEmailAddr: email@example.com
    30 mms.ignoreInitialUiSetup: "true"
    31 mms.mail.hostname: smtp@example.com
    32 mms.mail.port: "465"
    33 mms.mail.ssl: "true"
    34 mms.mail.transport: smtp
    35 mms.minimumTLSVersion: TLSv1.2
    36 mms.replyToEmailAddr: email@example.com
    37 applicationDatabase:
    38 version: "${APPDB_VERSION}"
    39 topology: MultiCluster
    40 security:
    41 certsSecretPrefix: cert-prefix
    42 tls:
    43 ca: appdb-cert-ca
    44 clusterSpecList:
    45 - clusterName: "${K8S_CLUSTER_0_CONTEXT_NAME}"
    46 members: 3
    47 - clusterName: "${K8S_CLUSTER_1_CONTEXT_NAME}"
    48 members: 2
    49 backup:
    50 enabled: true
    51 s3Stores:
    52 - name: my-s3-block-store
    53 s3SecretRef:
    54 name: "s3-access-secret"
    55 pathStyleAccessEnabled: true
    56 s3BucketEndpoint: "${S3_ENDPOINT}"
    57 s3BucketName: "${S3_SNAPSHOT_BUCKET_NAME}"
    58 customCertificateSecretRefs:
    59 - name: s3-ca-cert
    60 key: ca.crt
    61 s3OpLogStores:
    62 - name: my-s3-oplog-store
    63 s3SecretRef:
    64 name: "s3-access-secret"
    65 s3BucketEndpoint: "${S3_ENDPOINT}"
    66 s3BucketName: "${S3_OPLOG_BUCKET_NAME}"
    67 pathStyleAccessEnabled: true
    68 customCertificateSecretRefs:
    69 - name: s3-ca-cert
    70 key: ca.crt
    71EOF
  2. Espere hasta que el Operador de Kubernetes finalice su configuración:

    1echo; echo "Waiting for Backup to reach Running phase..."
    2kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.backup.phase}'=Running opsmanager/om --timeout=1200s
    3echo "Waiting for Application Database to reach Running phase..."
    4kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.applicationDatabase.phase}'=Running opsmanager/om --timeout=600s
    5echo; echo "Waiting for Ops Manager to reach Running phase..."
    6kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" wait --for=jsonpath='{.status.opsManager.phase}'=Running opsmanager/om --timeout=600s
    7echo; echo "MongoDBOpsManager resource"
    8kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" get opsmanager/om
    9echo; echo "Pods running in cluster ${K8S_CLUSTER_0_CONTEXT_NAME}"
    10kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${NAMESPACE}" get pods
    11echo; echo "Pods running in cluster ${K8S_CLUSTER_1_CONTEXT_NAME}"
    12kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "${NAMESPACE}" get pods
    13echo; echo "Pods running in cluster ${K8S_CLUSTER_2_CONTEXT_NAME}"
    14kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "${NAMESPACE}" get pods
    1Waiting for Backup to reach Running phase...
    2mongodbopsmanager.mongodb.com/om condition met
    3Waiting for Application Database to reach Running phase...
    4mongodbopsmanager.mongodb.com/om condition met
    5
    6Waiting for Ops Manager to reach Running phase...
    7mongodbopsmanager.mongodb.com/om condition met
    8
    9MongoDBOpsManager resource
    10NAME REPLICAS VERSION STATE (OPSMANAGER) STATE (APPDB) STATE (BACKUP) AGE WARNINGS
    11om 7.0.4 Running Running Running 26m
    12
    13Pods running in cluster gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
    14NAME READY STATUS RESTARTS AGE
    15om-0-0 2/2 Running 0 5m11s
    16om-db-0-0 4/4 Running 0 13m
    17om-db-0-1 4/4 Running 0 14m
    18om-db-0-2 4/4 Running 0 16m
    19
    20Pods running in cluster gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1
    21NAME READY STATUS RESTARTS AGE
    22om-1-0 2/2 Running 0 5m12s
    23om-db-1-0 4/4 Running 0 12m
    24om-db-1-1 4/4 Running 0 11m
    25
    26Pods running in cluster gke_scratch-kubernetes-team_europe-central2-c_k8s-mdb-2
    27NAME READY STATUS RESTARTS AGE
    28om-2-backup-daemon-0 2/2 Running 0 3m8s
11

Ejecute el siguiente script para eliminar los clústeres de GKE y limpiar su entorno.

Importante

Los siguientes comandos no son reversibles. Eliminan todos los clústeres mencionados en env_variables.sh. No ejecutes estos comandos si quieres mantener los clústeres de GKE, por ejemplo, si no creaste los clústeres de GKE como parte de este procedimiento.

1yes | gcloud container clusters delete "${K8S_CLUSTER_0}" --zone="${K8S_CLUSTER_0_ZONE}" &
2yes | gcloud container clusters delete "${K8S_CLUSTER_1}" --zone="${K8S_CLUSTER_1_ZONE}" &
3yes | gcloud container clusters delete "${K8S_CLUSTER_2}" --zone="${K8S_CLUSTER_2_ZONE}" &
4wait

En esta página