Si bien es posible implementar Multi-Cluster Ops Manager, Multi-Cluster Sharded Cluster y configuraciones de Multi-Cluster set de réplicas sin una malla de servicios, el enfoque recomendado (presentado aquÃ) es aprovechar una malla de servicios para gestionar las redes en varios clústeres de Kubernetes. Para aprender más, consulta Cómo establece la conectividad el Operador de Kubernetes.
Esta página te guÃa a través del proceso de implementación y validación de un Istio service mesh en múltiples clústeres de Kubernetes. Istio es solo una de las muchas opciones para implementar un malla de servicios y no es compatible con MongoDB.
Nota
Istio no está soportado por MongoDB
MongoDB no es compatible con Istio y es solo una de las muchas herramientas que puedes usar para implementar un mallado de servicios en todos tus clústeres de Kubernetes.
Requisitos previos
Antes de empezar, realiza las siguientes tareas:
Instale
kubectl.Establece las variables de entorno
K8S_CLUSTER_*_CONTEXT_NAMEcomo se explica en la GuÃa de clústeres GKE.
Código fuente
Se puede encontrar todo el código fuente incluido en el repositorio de MongoDB Kubernetes operador.
Procedimiento
Instala la malla de servicio Istio.
Instale Istio service mesh para permitir la resolución DNS entre clústeres y la conectividad de red entre clústeres de Kubernetes.
CTX_CLUSTER1=${K8S_CLUSTER_0_CONTEXT_NAME} \CTX_CLUSTER2=${K8S_CLUSTER_1_CONTEXT_NAME} \CTX_CLUSTER3=${K8S_CLUSTER_2_CONTEXT_NAME} \ISTIO_VERSION="1.20.2" \./install_istio_separate_network.shEtiqueta los espacios de nombres de Kubernetes.
Etiqueta los namespaces de Kubernetes en cada clúster para permitir la inyección de sidecar de Istio.
kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" label namespace "${OPERATOR_NAMESPACE}" istio-injection=enabled --overwritekubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" label namespace "${OPERATOR_NAMESPACE}" istio-injection=enabled --overwritekubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" label namespace "${OPERATOR_NAMESPACE}" istio-injection=enabled --overwrite
kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" label namespace "${OM_NAMESPACE}" istio-injection=enabled --overwritekubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" label namespace "${OM_NAMESPACE}" istio-injection=enabled --overwritekubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" label namespace "${OM_NAMESPACE}" istio-injection=enabled --overwrite
kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" label namespace "${MDB_NAMESPACE}" istio-injection=enabled --overwritekubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" label namespace "${MDB_NAMESPACE}" istio-injection=enabled --overwritekubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" label namespace "${MDB_NAMESPACE}" istio-injection=enabled --overwriteopcional. Verificar la conectividad del clúster.
Los siguientes scripts opcionales verifican si el service mesh está configurado correctamente para la resolución de DNS entre clústeres y la conectividad.
Crea un namespace de Kubernetes para la prueba de conectividad.
kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" create namespace "connectivity-test"kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" label namespace "connectivity-test" istio-injection=enabled --overwrite kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" create namespace "connectivity-test"kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" label namespace "connectivity-test" istio-injection=enabled --overwrite kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" create namespace "connectivity-test"kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" label namespace "connectivity-test" istio-injection=enabled --overwriteEjecute este script en el clúster 0:
kubectl apply --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "connectivity-test" -f - <<EOF apiVersion: apps/v1 kind: StatefulSet metadata: name: echoserver0 spec: replicas: 1 selector: matchLabels: app: echoserver0 template: metadata: labels: app: echoserver0 spec: containers: - image: k8s.gcr.io/echoserver:1.10 imagePullPolicy: Always name: echoserver0 ports: - containerPort: 8080EOFEjecute este script en el clúster 1:
kubectl apply --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "connectivity-test" -f - <<EOF apiVersion: apps/v1 kind: StatefulSet metadata: name: echoserver1 spec: replicas: 1 selector: matchLabels: app: echoserver1 template: metadata: labels: app: echoserver1 spec: containers: - image: k8s.gcr.io/echoserver:1.10 imagePullPolicy: Always name: echoserver1 ports: - containerPort: 8080EOFEjecute este script en el clúster 2:
kubectl apply --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "connectivity-test" -f - <<EOF apiVersion: apps/v1 kind: StatefulSet metadata: name: echoserver2 spec: replicas: 1 selector: matchLabels: app: echoserver2 template: metadata: labels: app: echoserver2 spec: containers: - image: k8s.gcr.io/echoserver:1.10 imagePullPolicy: Always name: echoserver2 ports: - containerPort: 8080EOFEjecuta este script para esperar la creación de StatefulSets:
kubectl wait --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "connectivity-test" --for=condition=ready pod -l statefulset.kubernetes.io/pod-name=echoserver0-0 --timeout=60skubectl wait --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "connectivity-test" --for=condition=ready pod -l statefulset.kubernetes.io/pod-name=echoserver1-0 --timeout=60skubectl wait --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "connectivity-test" --for=condition=ready pod -l statefulset.kubernetes.io/pod-name=echoserver2-0 --timeout=60sCrea un servicio de Pods en el clúster 0:
kubectl apply --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "connectivity-test" -f - <<EOFapiVersion: v1kind: Servicemetadata: name: echoserver0-0spec: ports: - port: 8080 targetPort: 8080 protocol: TCP selector: statefulset.kubernetes.io/pod-name: "echoserver0-0"EOFCrea un servicio de Pods en el clúster 1:
kubectl apply --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "connectivity-test" -f - <<EOFapiVersion: v1kind: Servicemetadata: name: echoserver1-0spec: ports: - port: 8080 targetPort: 8080 protocol: TCP selector: statefulset.kubernetes.io/pod-name: "echoserver1-0"EOFCrea un servicio de Pods en el clúster 2:
kubectl apply --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "connectivity-test" -f - <<EOFapiVersion: v1kind: Servicemetadata: name: echoserver2-0spec: ports: - port: 8080 targetPort: 8080 protocol: TCP selector: statefulset.kubernetes.io/pod-name: "echoserver2-0"EOFCrear un servicio round robin en el clúster 0:
kubectl apply --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "connectivity-test" -f - <<EOFapiVersion: v1kind: Servicemetadata: name: echoserverspec: ports: - port: 8080 targetPort: 8080 protocol: TCP selector: app: echoserver0EOFCrear un servicio round robin en el clúster 1:
kubectl apply --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "connectivity-test" -f - <<EOFapiVersion: v1kind: Servicemetadata: name: echoserverspec: ports: - port: 8080 targetPort: 8080 protocol: TCP selector: app: echoserver1EOFCrear un servicio round robin en el clúster 2:
kubectl apply --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "connectivity-test" -f - <<EOFapiVersion: v1kind: Servicemetadata: name: echoserverspec: ports: - port: 8080 targetPort: 8080 protocol: TCP selector: app: echoserver2EOFVerifica el Pod 0 del clúster 1:
source_cluster=${K8S_CLUSTER_1_CONTEXT_NAME}target_pod="echoserver0-0"source_pod="echoserver1-0"target_url="http://${target_pod}.connectivity-test.svc.cluster.local:8080"echo "Checking cross-cluster DNS resolution and connectivity from ${source_pod} in ${source_cluster} to ${target_pod}"out=$(kubectl exec --context "${source_cluster}" -n "connectivity-test" "${source_pod}" -- \ /bin/bash -c "curl -v ${target_url}" 2>&1); if grep "Hostname: ${target_pod}" &>/dev/null <<< "${out}"then echo "SUCCESS"else echo "ERROR: ${out}" return 1fiVerifica el Pod 1 del clúster 0:
source_cluster=${K8S_CLUSTER_0_CONTEXT_NAME}target_pod="echoserver1-0"source_pod="echoserver0-0"target_url="http://${target_pod}.connectivity-test.svc.cluster.local:8080"echo "Checking cross-cluster DNS resolution and connectivity from ${source_pod} in ${source_cluster} to ${target_pod}"out=$(kubectl exec --context "${source_cluster}" -n "connectivity-test" "${source_pod}" -- \ /bin/bash -c "curl -v ${target_url}" 2>&1); if grep "Hostname: ${target_pod}" &>/dev/null <<< "${out}"then echo "SUCCESS"else echo "ERROR: ${out}" return 1fiVerifica el Pod 1 del clúster 2:
source_cluster=${K8S_CLUSTER_2_CONTEXT_NAME}target_pod="echoserver1-0"source_pod="echoserver2-0"target_url="http://${target_pod}.connectivity-test.svc.cluster.local:8080"echo "Checking cross-cluster DNS resolution and connectivity from ${source_pod} in ${source_cluster} to ${target_pod}"out=$(kubectl exec --context "${source_cluster}" -n "connectivity-test" "${source_pod}" -- \ /bin/bash -c "curl -v ${target_url}" 2>&1); if grep "Hostname: ${target_pod}" &>/dev/null <<< "${out}"then echo "SUCCESS"else echo "ERROR: ${out}" return 1fiVerifica el Pod 2 del clúster 0:
source_cluster=${K8S_CLUSTER_0_CONTEXT_NAME}target_pod="echoserver2-0"source_pod="echoserver0-0"target_url="http://${target_pod}.connectivity-test.svc.cluster.local:8080"echo "Checking cross-cluster DNS resolution and connectivity from ${source_pod} in ${source_cluster} to ${target_pod}"out=$(kubectl exec --context "${source_cluster}" -n "connectivity-test" "${source_pod}" -- \ /bin/bash -c "curl -v ${target_url}" 2>&1); if grep "Hostname: ${target_pod}" &>/dev/null <<< "${out}"then echo "SUCCESS"else echo "ERROR: ${out}" return 1fiEjecute el script de limpieza:
kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "connectivity-test" delete statefulset echoserver0kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "connectivity-test" delete statefulset echoserver1kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "connectivity-test" delete statefulset echoserver2kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "connectivity-test" delete service echoserverkubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "connectivity-test" delete service echoserverkubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "connectivity-test" delete service echoserverkubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" -n "connectivity-test" delete service echoserver0-0kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" -n "connectivity-test" delete service echoserver1-0kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" -n "connectivity-test" delete service echoserver2-0kubectl --context "${K8S_CLUSTER_0_CONTEXT_NAME}" delete ns "connectivity-test"kubectl --context "${K8S_CLUSTER_1_CONTEXT_NAME}" delete ns "connectivity-test"kubectl --context "${K8S_CLUSTER_2_CONTEXT_NAME}" delete ns "connectivity-test"