Docs Menu
Docs Home
/
Enterprise Kubernetes Operator
/

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, las redes, las limitaciones y el rendimiento de las implementaciones de múltiples clústeres de Kubernetes para los recursos de Ops Manager, consulte:

  • Arquitectura de Multi-Cluster Ops Manager

  • Limitaciones

  • Diferencias entre las implementaciones de Ops Manager de un solo clúster y de varios clústeres

  • Diagrama de arquitectura

  • Redes, balanceador de carga, malla de servicios

  • Rendimiento

Al implementar la aplicación Ops Manager y la base de datos de la aplicación mediante el procedimiento de esta sección, usted:

  1. Utilice GKE (Google Kubernetes Engine)y la malla de servicios Istio como herramientas que ayudan a demostrar la implementación de múltiples 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 configure este clúster para vigilar $NAMESPACE y administrar todos los clústeres 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 miembro para demostrar la similitud entre una implementación multiclúster y una implementación de un solo clúster. Una implementación de un solo clúster con spec.topology y configurados spec.applicationDatabase.topology como MultiCluster prepara la implementación para agregar 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. Crear certificados válidos para CifradoTLS y establecimiento de conexiones cifradas TLS hacia y desde la aplicación Ops Manager, así como entre los miembros del conjunto de réplicas de la base de datos de la aplicación. Al ejecutarse mediante HTTPS, Ops Manager se ejecuta en el puerto 8443 de forma predeterminada.

  7. Habilite la copia de seguridad con almacenamiento compatible con S e implemente el Daemon de copia de seguridad en3 el tercer clúster de Kubernetes miembro. Para simplificar la configuración3de los buckets de almacenamiento compatibles con S, implemente el operador MinIO. Habilite el Daemon de copia de seguridad solo en un clúster miembro de su implementación. Sin embargo, puede configurar otros clústeres miembros para que también alojen los recursos del Daemon de copia de seguridad. Solo se admiten las copias de seguridad S en implementaciones multiclúster de Ops Manager.3

Antes de poder comenzar la implementación, instale las siguientes herramientas necesarias:

Instale gcloud CLI y autorícelo:

gcloud auth login

El complemento kubectl mongodb automatiza la configuración de los clústeres de Kubernetes. Esto permite al operador de Kubernetes implementar recursos, roles y servicios necesarios 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 complemento kubectl mongodb:

1

Descargue la versión del paquete Kubernetes Operator que desee desde la página de lanzamiento del repositorio de Kubernetes Operator de MongoDB Enterprise.

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

Desempaquete 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 complemento 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.

Clona el Repositorio MongoDB Enterprise Kubernetes Operator, cambia al directorio mongodb-enterprise-kubernetes y comprueba la versión actual.

git clone https://github.com/mongodb/mongodb-enterprise-kubernetes.git
cd mongodb-enterprise-kubernetes
git checkout 1.25
cd public/samples/ops-manager-multi-cluster

Importante

Algunos pasos de esta guía solo funcionan si los ejecuta desde el directorio public/samples/ops-manager-multi-cluster.

Todos los pasos de 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 OPERATOR_HELM_CHART="mongodb/enterprise-operator"
42
43# (Optional) Change the following setting when using the external URL.
44# This env variable is used in OpenSSL configuration to generate
45# server certificates for Ops Manager Application.
46export OPS_MANAGER_EXTERNAL_DOMAIN="om-svc.${NAMESPACE}.svc.cluster.local"
47
48export OPS_MANAGER_VERSION="7.0.4"
49export APPDB_VERSION="7.0.9-ubi8"

Ajuste la configuración del ejemplo anterior según sus necesidades según las instrucciones de los comentarios e introdúzcalos en su shell de la siguiente manera:

source env_variables.sh

Importante

Cada vez que actualice env_variables.sh, ejecute source env_variables.sh para asegurarse de 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

Puede omitir este paso si ya ha instalado y configurado sus propios clústeres de Kubernetes con una malla de servicio.

  1. Cree 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. 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 kubectl hacen referencia a estos contextos utilizando las siguientes variables:

    • $K8S_CLUSTER_0_CONTEXT_NAME

    • $K8S_CLUSTER_1_CONTEXT_NAME

    • $K8S_CLUSTER_2_CONTEXT_NAME

  3. Verifique 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-d0f98a43-dtlc Ready <none> 65s v1.28.7-gke.1026000
    4gke-k8s-mdb-0-default-pool-d0f98a43-q9sf Ready <none> 65s v1.28.7-gke.1026000
    5gke-k8s-mdb-0-default-pool-d0f98a43-zn8x Ready <none> 64s v1.28.7-gke.1026000
    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-37ea602a-0qgw Ready <none> 111s v1.28.7-gke.1026000
    10gke-k8s-mdb-1-default-pool-37ea602a-k4qk Ready <none> 114s v1.28.7-gke.1026000
    11gke-k8s-mdb-1-default-pool-37ea602a-p2g7 Ready <none> 113s v1.28.7-gke.1026000
    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-4b459a09-t1v9 Ready <none> 29s v1.28.7-gke.1026000
  4. Instale la malla de servicio Istio para permitir la resolución de DNS entre clústeres 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 de sidecar en Istio, los siguientes comandos agregan las istio-injection=enabled etiquetas a $OPERATOR_NAMESPACE los mongodb espacios de nombres y de cada clúster miembro. Si utiliza otra malla de servicios, configúrela 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 utiliza cartas e imágenes oficiales de Helm del registro de 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 la malla de servicio está configurada correctamente para la resolución y conectividad de DNS entre clústeres.

  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. Crear servicio Pod 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. Crear servicio Pod 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. Crear servicio Pod 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. Verificar 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. Verificar 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. Verificar 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. Verificar 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.

Dado que configura los clústeres de Kubernetes antes de instalar el operador de Kubernetes, cuando implementa el operador de Kubernetes para la operación de múltiples clústeres de Kubernetes, toda la configuración de múltiples clústeres necesaria 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
1Build: 1f23ae48c41d208f14c860356e483ba386a3aab8, 2024-04-26T12:19:36Z
2Ensured namespaces exist in all clusters.
3creating operator cluster roles in cluster: gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
4creating member roles in cluster: gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1
5creating member roles in cluster: gke_scratch-kubernetes-team_europe-central2-c_k8s-mdb-2
6Ensured ServiceAccounts and Roles.
7Creating KubeConfig secret mongodb-operator/mongodb-enterprise-operator-multi-cluster-kubeconfig in cluster gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
8Ensured database Roles in member clusters.
9Creating Member list Configmap mongodb-operator/mongodb-enterprise-operator-member-list in cluster gke_scratch-kubernetes-team_europe-central2-a_k8s-mdb-0
6
  1. Instale el operador de Kubernetes $OPERATOR_NAMESPACE en, configurado para $NAMESPACE supervisar y administrar tres clústeres de Kubernetes miembros. En este punto del procedimiento, lascuentas de servicio y los roles ya están implementados por el kubectl mongodb complemento. Por lo tanto, los siguientes scripts omiten su configuración y configuran operator.createOperatorServiceAccount=false operator.createResourcesServiceAccountsAndRoles=falsey. Los scripts especifican la configuración multiCluster.clusters para indicar al gráfico de Helm que implemente el operador de Kubernetes en modo multiclúster.

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

    1kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "${OPERATOR_NAMESPACE}" rollout status deployment/mongodb-enterprise-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-enterprise-operator-multi-cluster" rollout to finish: 0 of 1 updated replicas are available...
    2deployment "mongodb-enterprise-operator-multi-cluster" successfully rolled out
    3Operator deployment in mongodb-operator namespace
    4NAME READY UP-TO-DATE AVAILABLE AGE
    5mongodb-enterprise-operator-multi-cluster 1/1 1 1 12s
    6
    7Operator pod in mongodb-operator namespace
    8NAME READY STATUS RESTARTS AGE
    9mongodb-enterprise-operator-multi-cluster-78cc97547d-nlgds 2/2 Running 1 (3s ago) 12s
7

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

  1. Opcional. Generar claves y certificados:

    Utilice la herramienta de línea de comandos openssl para generar CA y certificados autofirmados para 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
    9
    10[ dn ]
    11C=US
    12ST=New York
    13L=New York
    14O=Example Company
    15OU=IT Department
    16CN=exampleCA
    17EOF
    18
    19cat <<EOF >certs/om.cnf
    20[ req ]
    21default_bits = 2048
    22prompt = no
    23default_md = sha256
    24distinguished_name = dn
    25req_extensions = req_ext
    26
    27[ dn ]
    28C=US
    29ST=New York
    30L=New York
    31O=Example Company
    32OU=IT Department
    33CN=${OPS_MANAGER_EXTERNAL_DOMAIN}
    34
    35[ req_ext ]
    36subjectAltName = @alt_names
    37keyUsage = critical, digitalSignature, keyEncipherment
    38extendedKeyUsage = serverAuth, clientAuth
    39
    40[ alt_names ]
    41DNS.1 = ${OPS_MANAGER_EXTERNAL_DOMAIN}
    42DNS.2 = om-svc.${NAMESPACE}.svc.cluster.local
    43EOF
    44
    45cat <<EOF >certs/appdb.cnf
    46[ req ]
    47default_bits = 2048
    48prompt = no
    49default_md = sha256
    50distinguished_name = dn
    51req_extensions = req_ext
    52
    53[ dn ]
    54C=US
    55ST=New York
    56L=New York
    57O=Example Company
    58OU=IT Department
    59CN=AppDB
    60
    61[ req_ext ]
    62subjectAltName = @alt_names
    63keyUsage = critical, digitalSignature, keyEncipherment
    64extendedKeyUsage = serverAuth, clientAuth
    65
    66[ alt_names ]
    67# multi-cluster mongod hostnames from service for each pod
    68DNS.1 = *.${NAMESPACE}.svc.cluster.local
    69# single-cluster mongod hostnames from headless service
    70DNS.2 = *.om-db-svc.${NAMESPACE}.svc.cluster.local
    71EOF
    72
    73# generate CA keypair and certificate
    74openssl genrsa -out certs/ca.key 2048
    75openssl req -x509 -new -nodes -key certs/ca.key -days 1024 -out certs/ca.crt -config certs/ca.cnf
    76
    77# generate OpsManager's keypair and certificate
    78openssl genrsa -out certs/om.key 2048
    79openssl req -new -key certs/om.key -out certs/om.csr -config certs/om.cnf
    80
    81# generate AppDB's keypair and certificate
    82openssl genrsa -out certs/appdb.key 2048
    83openssl req -new -key certs/appdb.key -out certs/appdb.csr -config certs/appdb.cnf
    84
    85# generate certificates signed by CA for OpsManager and AppDB
    86openssl 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
    87openssl 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. Crear secretos con claves TLS:

    Si prefiere utilizar sus propias claves y certificados, omita el paso de generación anterior y coloque las claves y los certificados en los siguientes archivos:

    • certs/ca.crt Certificados de CA. No son necesarios cuando se utilizan certificados de confianza.

    • certs/appdb.key - clave 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. Cree las credenciales necesarias para el usuario administrador de Ops Manager que el operador de Kubernetes creará después de implementar la instancia de la aplicación Ops Manager:

    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 demuestra que la implementación de un solo clúster de Kubernetes es un caso especial de implementación de varios clústeres de Kubernetes en un solo clúster miembro de Kubernetes. Puede empezar a implementar la aplicación Ops Manager y la base de datos de la aplicación en tantos clústeres de Kubernetes como necesite desde el principio, sin necesidad de empezar la implementación con un solo clúster miembro 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 conjunto de réplicas de la base de datos de la aplicación y espera a que los procesos MongoDB en el conjunto 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 a que esté lista.

    • Agrega los contenedores del Agente de Monitoreo MongoDB 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 11m
    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 8m39s
    22om-db-0-0 4/4 Running 0 44s
    23om-db-0-1 4/4 Running 0 2m6s
    24om-db-0-2 4/4 Running 0 3m19s
    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. Espere a que el operador de Kubernetes 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 Pending Running Disabled 14m
    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 Terminating 0 12m
    14om-db-0-0 4/4 Running 0 4m12s
    15om-db-0-1 4/4 Running 0 5m34s
    16om-db-0-2 4/4 Running 0 6m47s
    17
    18Pods running in cluster gke_scratch-kubernetes-team_europe-central2-b_k8s-mdb-1
    19NAME READY STATUS RESTARTS AGE
    20om-1-0 0/2 Init:0/2 0 0s
    21om-db-1-0 4/4 Running 0 3m24s
    22om-db-1-1 4/4 Running 0 104s
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. Instale el operador MinIO.

    Este procedimiento implementa almacenamiento compatible con S para sus3 copias de seguridad mediante el operador MinIO. Puede omitir este paso si dispone de buckets de AWS S3 u otros buckets compatibles con S.3 S3_* En este caso, ajuste las variables según corresponda en env_variables.sh.

    1kustomize build "github.com/minio/operator/resources/?timeout=120&ref=v5.0.12" | \
    2 kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" apply -f -
    3
    4kustomize build "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, cree 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 utiliza certificados de confianza pública, puede omitir este paso y eliminar los valores de las configuraciones spec.backup.s3Stores.customCertificateSecretRefs spec.backup.s3OpLogStores.customCertificateSecretRefs y.

    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 de Backup Daemon y los nodos del conjunto de réplicas de la base de datos de la aplicación en cualquier combinación en cualquier clúster miembro para el que configure el operador de Kubernetes.

    Para ilustrar la flexibilidad de la configuración de implementación de varios clústeres de Kubernetes, implemente solo una instancia de Backup Daemon en el tercer clúster miembro y especifique cero miembros de Backup Daemon para el primer y el 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 22m
    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 7m10s
    16om-db-0-0 4/4 Running 0 11m
    17om-db-0-1 4/4 Running 0 13m
    18om-db-0-2 4/4 Running 0 14m
    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 4m8s
    23om-db-1-0 4/4 Running 0 11m
    24om-db-1-1 4/4 Running 0 9m25s
    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 2m5s
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 referenciados en env_variables.sh. No los ejecute si desea conservar los clústeres de GKE; por ejemplo, si no los creó durante 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