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, 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

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.

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. Usar GKE (Google Kubernetes Engine) e Istio Service Mesh 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 controladores MongoDB para operadores de 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

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.

Clone el repositorio del operador de controladores MongoDB para Kubernetes, cámbiese al mongodb-kubernetes directorio y verifique la versión actual.

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

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 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"

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

  4. 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-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 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
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. Agregue y actualice el repositorio de Helm de MongoDB. Verifique 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 $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-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. Verifique la implementación del operador de Kubernetes:

    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, 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
    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. 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 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. 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 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. 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.

    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, 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 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 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