Ejecución de servicios distribuidos en clústeres privados de GKE con Cloud Service Mesh
En este documento, se muestra cómo ejecutar servicios distribuidos en varias Clústeres de Google Kubernetes Engine (GKE) en Google Cloud con Cloud Service Mesh. En este documento, también se muestra cómo exponer un servicio distribuido con Ingress de varios clústeres y Cloud Service Mesh. Puedes usar este documento para configurar clústeres de GKE no privados. En el documento, se destaca la configuración diseñada para clústeres privados.
Este documento está dirigido a los administradores de plataformas y operadores de servicios que tienen conocimientos básicos de Kubernetes. Manejar algunos conocimientos de la malla de servicios es beneficioso, aunque no es obligatorio. Cloud Service Mesh se basa en el servicio de Istio de código abierto tecnología. Para obtener más información sobre Istio y la malla de servicios, consulta istio.io.
Un servicio distribuido es un Service de Kubernetes que actúa como un servicio único lógico. Los servicios distribuidos son más resilientes que los servicios de Kubernetes porque se ejecutan en varios clústeres de Kubernetes en el mismo espacio de nombres. Un servicio distribuido permanece activo incluso si uno o más clústeres de GKE están inactivos, siempre que los clústeres en buen estado puedan entregar la carga deseada.
Los services de Kubernetes solo son conocidos para el servidor de la API de Kubernetes del clúster en el que se ejecutan. Si el clúster de Kubernetes está inactivo (por ejemplo, durante un mantenimiento programado), todos los servicios de Kubernetes que se ejecutan en ese clúster también están inactivos. Ejecutar servicios distribuidos facilita la administración del ciclo de vida de los clústeres porque puedes reducirlos para mantenimiento o actualizaciones, mientras que otros clústeres entregan tráfico de servicios. Para crear un servicio distribuido, la funcionalidad de la malla de servicios que proporciona Cloud Service Mesh se usa para vincular los servicios que se ejecutan en varios clústeres a fin de que actúen como un único servicio lógico.
Los clústeres privados de GKE te permiten configurar los nodos y el servidor de la API como recursos privados disponibles solo en la red de nube privada virtual (VPC). Ejecutar servicios distribuidos en clústeres privados de GKE brinda a las empresas servicios seguros y confiables.
Arquitectura
En este instructivo, se usa la arquitectura que se muestra en el siguiente diagrama:
En el diagrama anterior, la arquitectura incluye los siguientes clústeres:
- Dos clústeres (
gke-central-priv
ygke-west-priv
) actúan como clústeres privados de GKE idénticos en dos regiones diferentes. - Un clúster independiente (
ingress-config
) actúa como el clúster del plano de control que configura Ingress de varios clústeres.
En este instructivo, implementarás la aplicación de ejemplo Bank of Anthos en dos clústeres privados de GKE (gke-central-priv
y gke-west-priv
). Bank of Anthos es una aplicación de microservicios de ejemplo que consta de varios microservicios y bases de datos SQL que simulan una app de banca en línea. La aplicación consta de un frontend web al que los clientes pueden acceder y varios servicios de backend, como servicios de balance, registro y cuenta que simulan un banco.
La aplicación incluye dos bases de datos de PostgreSQL instaladas en Kubernetes como StatefulSets. Una base de datos se usa para las transacciones, mientras que la otra base de datos se usa para cuentas de usuario. Todos los servicios, excepto las dos bases de datos, se ejecutan como servicios distribuidos. Esto significa que los Pods para todos los Services se ejecutan tanto clústeres de aplicaciones (en el mismo espacio de nombres), y Cloud Service Mesh para que cada servicio aparezca como un único servicio lógico.
Objetivos
- Crear tres clústeres de GKE
- Configurar dos de los clústeres de GKE como clústeres privados (
gke-central-priv
ygke-west-priv
). - Configurar un clúster de GKE (
ingress-config
) como el clúster de configuración central. Este clúster actúa como un clúster de configuración para Ingress de varios clústeres. - Configurar las herramientas de redes (puertas de enlace NAT, Cloud Router y reglas de firewall) para permitir el tráfico entre clústeres y de salida de los dos clústeres privados de GKE.
- Configurar las redes autorizadas para permitir el acceso a los servicios de API desde Cloud Shell a los dos clústeres privados de GKE.
- Implementar y configurar Cloud Service Mesh de varios clústeres en los dos clústeres privados en modo de varias instancias principales El modo de instancia principal múltiple implementa un plano de control de Cloud Service Mesh en ambos clústeres.
- Implementar la aplicación del Bank of Anthos en los dos clústeres privados. Todos los servicios, excepto las bases de datos, se implementan como servicios distribuidos (Pods que se ejecutan en ambos clústeres privados).
- Supervisa los servicios con Cloud Service Mesh.
- Configura Ingress de varios clústeres en los servicios
frontend
de Bank of Anthos. Esto permite que los clientes externos (por ejemplo, el navegador web) accedan a un servicio distribuido que se ejecuta en una flota de clústeres de GKE privados.
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Antes de comenzar
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
Ejecuta todos los comandos de este instructivo desde Cloud Shell.
Define las variables de entorno que se usan en este instructivo. Las variables definen nombres de clúster, regiones, zonas, direccionamiento IP y versiones de Cloud Service Mesh que se usan en este instructivo.
Reemplaza
YOUR_PROJECT_ID
por el ID del proyecto:export PROJECT_ID=YOUR_PROJECT_ID gcloud config set project ${PROJECT_ID}
Configura las variables de entorno restantes:
export CLUSTER_1=gke-west-priv export CLUSTER_2=gke-central-priv export CLUSTER_1_ZONE=us-west2-a export CLUSTER_1_REGION=us-west2 export CLUSTER_1_MASTER_IPV4_CIDR=172.16.0.0/28 export CLUSTER_2_ZONE=us-central1-a export CLUSTER_2_REGION=us-central1 export CLUSTER_2_MASTER_IPV4_CIDR=172.16.1.0/28 export CLUSTER_INGRESS=gke-ingress export CLUSTER_INGRESS_ZONE=us-west1-a export CLUSTER_INGRESS_REGION=us-west1 export CLUSTER_INGRESS_MASTER_IPV4_CIDR=172.16.2.0/28 export WORKLOAD_POOL=${PROJECT_ID}.svc.id.goog export ASM_VERSION=1.10 export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
Prepare el entorno
En Cloud Shell, habilita las API:
gcloud services enable \ --project=${PROJECT_ID} \ container.googleapis.com \ mesh.googleapis.com \ gkehub.googleapis.com
Habilita la flota de la malla de servicios de Cloud para tu proyecto:
gcloud container fleet mesh enable --project=${PROJECT_ID}
Preparar las herramientas de redes para clústeres de GKE privados
En esta sección, prepararás las herramientas de redes para los clústeres de GKE privados que uses a fin de ejecutar servicios distribuidos.
A los nodos del clúster de GKE privado no se les asigna una dirección IP pública. Todos los nodos de un clúster de GKE privado tienen asignada una dirección IP de VPC privada (en el espacio de direcciones RFC 1918). Esto significa que los Pods que necesitan acceder a recursos externos (fuera de la red de VPC) requieren una puerta de enlace de Cloud NAT. Las puertas de enlace Cloud NAT son puertas de enlace NAT regionales que permiten a los Pods con direcciones IP internas comunicarse con Internet. En este instructivo, configurarás una puerta de enlace de Cloud NAT en cada una de las dos regiones. Varios clústeres dentro de una región pueden usar la misma puerta de enlace NAT.
En Cloud Shell, crea y reserva dos direcciones IP externas para las dos puertas de enlace NAT:
gcloud compute addresses create ${CLUSTER_1_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_1_REGION} gcloud compute addresses create ${CLUSTER_2_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_2_REGION}
Almacena la dirección IP y el nombre de las direcciones IP en las variables:
export NAT_REGION_1_IP_ADDR=$(gcloud compute addresses describe ${CLUSTER_1_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_1_REGION} \ --format='value(address)') export NAT_REGION_1_IP_NAME=$(gcloud compute addresses describe ${CLUSTER_1_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_1_REGION} \ --format='value(name)') export NAT_REGION_2_IP_ADDR=$(gcloud compute addresses describe ${CLUSTER_2_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_2_REGION} \ --format='value(address)') export NAT_REGION_2_IP_NAME=$(gcloud compute addresses describe ${CLUSTER_2_REGION}-nat-ip \ --project=${PROJECT_ID} \ --region=${CLUSTER_2_REGION} \ --format='value(name)')
Crea puertas de enlace de Cloud NAT en las dos regiones de los clústeres de GKE privados:
gcloud compute routers create rtr-${CLUSTER_1_REGION} \ --network=default \ --region ${CLUSTER_1_REGION} gcloud compute routers nats create nat-gw-${CLUSTER_1_REGION} \ --router=rtr-${CLUSTER_1_REGION} \ --region ${CLUSTER_1_REGION} \ --nat-external-ip-pool=${NAT_REGION_1_IP_NAME} \ --nat-all-subnet-ip-ranges \ --enable-logging gcloud compute routers create rtr-${CLUSTER_2_REGION} \ --network=default \ --region ${CLUSTER_2_REGION} gcloud compute routers nats create nat-gw-${CLUSTER_2_REGION} \ --router=rtr-${CLUSTER_2_REGION} \ --region ${CLUSTER_2_REGION} \ --nat-external-ip-pool=${NAT_REGION_2_IP_NAME} \ --nat-all-subnet-ip-ranges \ --enable-logging
Crea una regla de firewall que permita la comunicación de Pod a Pod y la comunicación de servidor de Pod a API. La comunicación de Pod a Pod permite que los servicios distribuidos se comuniquen entre sí en todos los clústeres de GKE. La comunicación del servidor de API a Pod permite que el plano de control de Cloud Service Mesh consulte los clústeres de GKE para el descubrimiento de servicios.
gcloud compute firewall-rules create all-pods-and-master-ipv4-cidrs \ --project ${PROJECT_ID} \ --network default \ --allow all \ --direction INGRESS \ --source-ranges 10.0.0.0/8,${CLUSTER_1_MASTER_IPV4_CIDR},${CLUSTER_2_MASTER_IPV4_CIDR},${CLUSTER_INGRESS_MASTER_IPV4_CIDR}
Las herramientas de redes ya están preparadas. En este instructivo, usarás todo el rango de direcciones IP 10.0.0.0/8
, que incluye todos los rangos de Pods. Te recomendamos crear una regla de firewall más estricta en producción, según las condiciones y los requisitos.
Crea clústeres de GKE privados
En esta sección, crearás los dos clústeres privados de GKE en los que se implementa la app de ejemplo. En este instructivo, los nodos privados del clúster de GKE tienen direcciones IP privadas, y el servidor de la API tiene un extremo público. Sin embargo, el acceso al servidor de la API se restringe mediante redes autorizadas.
En Cloud Shell, crea dos clústeres privados que tengan redes autorizadas. Configura los clústeres para permitir el acceso desde el rango de CIDR de la IP del Pod (para el plano de control de Cloud Service Mesh) y desde Cloud Shell a fin de que puedas acceder a los clústeres desde la terminal.
gcloud container clusters create ${CLUSTER_1} \ --project ${PROJECT_ID} \ --zone=${CLUSTER_1_ZONE} \ --machine-type "e2-standard-4" \ --num-nodes "3" --min-nodes "3" --max-nodes "5" \ --enable-ip-alias --enable-autoscaling \ --workload-pool=${WORKLOAD_POOL} \ --enable-private-nodes \ --master-ipv4-cidr=${CLUSTER_1_MASTER_IPV4_CIDR} \ --enable-master-authorized-networks \ --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32 gcloud container clusters create ${CLUSTER_2} \ --project ${PROJECT_ID} \ --zone=${CLUSTER_2_ZONE} \ --machine-type "e2-standard-4" \ --num-nodes "3" --min-nodes "3" --max-nodes "5" \ --enable-ip-alias --enable-autoscaling \ --workload-pool=${WORKLOAD_POOL} \ --enable-private-nodes \ --master-ipv4-cidr=${CLUSTER_2_MASTER_IPV4_CIDR} \ --enable-master-authorized-networks \ --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32
Las redes autorizadas contienen las direcciones IP públicas en las puertas de enlace de Cloud NAT. Debido a que el extremo del servidor de API de un clúster privado es un extremo público, los Pods que se ejecutan en un clúster privado deben usar una puerta de enlace de Cloud NAT para acceder a los extremos del servidor de API pública.
La dirección IP de Cloud Shell también forma parte de las redes autorizadas, lo que te permite acceder y administrar clústeres desde tu terminal de Cloud Shell. Las direcciones IP públicas de Cloud Shell son dinámicas, por lo que cada vez que inicies Cloud Shell, es posible que obtengas una dirección IP pública diferente. Cuando obtienes una dirección IP nueva, pierdes acceso a los clústeres porque la dirección IP nueva no forma parte de las redes autorizadas de los dos clústeres.
Si pierdes el acceso a los clústeres, actualiza las redes autorizadas de los clústeres para incluir la dirección IP nueva de Cloud Shell:
Obtén la dirección IP pública actualizada de Cloud Shell:
export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
Actualiza las redes autorizadas de los dos clústeres:
gcloud container clusters update ${CLUSTER_1} \ --zone=${CLUSTER_1_ZONE} \ --enable-master-authorized-networks \ --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32 gcloud container clusters update ${CLUSTER_2} \ --zone=${CLUSTER_2_ZONE} \ --enable-master-authorized-networks \ --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32
Verifica que todos los clústeres estén en ejecución:
gcloud container clusters list
El resultado luce de la siguiente manera:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS gke-central-priv us-central1-a 1.16.15-gke.6000 35.238.99.104 e2-standard-4 1.16.15-gke.6000 3 RUNNING gke-west-priv us-west2-a 1.16.15-gke.6000 34.94.188.180 e2-standard-4 1.16.15-gke.6000 3 RUNNING
Conéctate a ambos clústeres para generar entradas en el archivo kubeconfig:
touch ~/asm-kubeconfig && export KUBECONFIG=~/asm-kubeconfig gcloud container clusters get-credentials ${CLUSTER_1} --zone ${CLUSTER_1_ZONE} gcloud container clusters get-credentials ${CLUSTER_2} --zone ${CLUSTER_2_ZONE}
Crea un usuario y un contexto para cada clúster a fin de autenticarte en el archivo kubeconfig. Después de generar entradas en el archivo kubeconfig, puedes cambiar el contexto entre clústeres con rapidez.
Cambia el nombre de los contextos del clúster para mayor comodidad:
kubectl config rename-context \ gke_${PROJECT_ID}_${CLUSTER_1_ZONE}_${CLUSTER_1} ${CLUSTER_1} kubectl config rename-context \ gke_${PROJECT_ID}_${CLUSTER_2_ZONE}_${CLUSTER_2} ${CLUSTER_2}
Confirma que ambos contextos del clúster cambiaron el nombre y se configuraron de forma correcta:
kubectl config get-contexts --output="name"
El resultado luce de la siguiente manera:
gke-central-priv gke-west-priv
Registra tus clústeres en una flota.
gcloud container fleet memberships register ${CLUSTER_1} --gke-cluster=${CLUSTER_1_ZONE}/${CLUSTER_1} --enable-workload-identity gcloud container fleet memberships register ${CLUSTER_2} --gke-cluster=${CLUSTER_2_ZONE}/${CLUSTER_2} --enable-workload-identity
Ya creaste y cambiaste el nombre de tus clústeres privados de GKE.
Instala Cloud Service Mesh
En esta sección, instalarás Cloud Service Mesh en los dos clústeres de GKE y configurarlos para varios clústeres descubrimiento de servicios.
En Cloud Shell, instala Cloud Service Mesh en ambos clústeres con
fleet API
:gcloud container fleet mesh update --management automatic --memberships ${CLUSTER_1},${CLUSTER_2}
Después de habilitar Cloud Service Mesh administrado en los clústeres, configura un reloj para que se instale la malla:
watch -g "gcloud container fleet mesh describe | grep 'code: REVISION_READY'"
Instala las puertas de enlace de entrada de Cloud Service Mesh para ambos clústeres:
kubectl --context=${CLUSTER_1} create namespace asm-ingress kubectl --context=${CLUSTER_1} label namespace asm-ingress istio-injection=enabled --overwrite kubectl --context=${CLUSTER_2} create namespace asm-ingress kubectl --context=${CLUSTER_2} label namespace asm-ingress istio-injection=enabled --overwrite cat <<'EOF' > asm-ingress.yaml apiVersion: v1 kind: Service metadata: name: asm-ingressgateway namespace: asm-ingress spec: type: LoadBalancer selector: asm: ingressgateway ports: - port: 80 name: http - port: 443 name: https --- apiVersion: apps/v1 kind: Deployment metadata: name: asm-ingressgateway namespace: asm-ingress spec: selector: matchLabels: asm: ingressgateway template: metadata: annotations: # This is required to tell Anthos Service Mesh to inject the gateway with the # required configuration. inject.istio.io/templates: gateway labels: asm: ingressgateway spec: containers: - name: istio-proxy image: auto # The image will automatically update each time the pod starts. --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: asm-ingressgateway-sds namespace: asm-ingress rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: asm-ingressgateway-sds namespace: asm-ingress roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: asm-ingressgateway-sds subjects: - kind: ServiceAccount name: default EOF kubectl --context=${CLUSTER_1} apply -f asm-ingress.yaml kubectl --context=${CLUSTER_2} apply -f asm-ingress.yaml
Verifica que las puertas de enlace de entrada de la malla de servicios de Cloud estén implementadas:
kubectl --context=${CLUSTER_1} get pod,service -n asm-ingress kubectl --context=${CLUSTER_2} get pod,service -n asm-ingress
El resultado de ambos clústeres se verá de la siguiente manera:
NAME READY STATUS RESTARTS AGE pod/asm-ingressgateway-5894744dbd-zxlgc 1/1 Running 0 84s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/asm-ingressgateway LoadBalancer 10.16.2.131 34.102.100.138 80:30432/TCP,443:30537/TCP 92s
Después de instalar el plano de control de Cloud Service Mesh y las puertas de enlace de entrada para ambos clústeres, el descubrimiento de servicios entre clústeres se habilita con la API de la flota. El descubrimiento de servicios entre clústeres permite que los dos clústeres descubran extremos de servicio desde el clúster remoto. Los servicios distribuidos se ejecutan en varios clústeres en el mismo espacio de nombres.
Para que ambos planos de control de Cloud Service Mesh detecten todos los extremos de un servicio distribuido, Cloud Service Mesh debe tener acceso a todos los clústeres que ejecutan el servicio distribuido. En este ejemplo, se usan dos clústeres, por lo que ambos deben poder consultar al clúster remoto para los extremos del servicio. Con la malla de servicios administrados de Cloud habilitada con la API de flota, el descubrimiento de extremos se configura automáticamente.
Los clústeres y la malla de servicios de Cloud ya están configurados.
Implementa la aplicación Bank of Anthos
En Cloud Shell, clona el repositorio de GitHub de Bank of Anthos:
git clone https://github.com/GoogleCloudPlatform/bank-of-anthos.git ${HOME}/bank-of-anthos
Crea y etiqueta un espacio de nombres
bank-of-anthos
en ambos clústeres. La etiqueta permite la inserción automática de los proxies de sidecar de Envoy en cada Pod dentro del espacio de nombres etiquetado.# cluster_1 kubectl create --context=${CLUSTER_1} namespace bank-of-anthos kubectl label --context=${CLUSTER_1} namespace bank-of-anthos istio-injection=enabled # cluster_2 kubectl create --context=${CLUSTER_2} namespace bank-of-anthos kubectl label --context=${CLUSTER_2} namespace bank-of-anthos istio-injection=enabled
Implementa la aplicación Bank of Anthos en ambos clústeres en el espacio de nombres
bank-of-anthos
.# The following secret is used for user account creation and authentication kubectl --context=$CLUSTER_1 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/extras/jwt/jwt-secret.yaml kubectl --context=$CLUSTER_2 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/extras/jwt/jwt-secret.yaml # Deploy all manifests to both clusters kubectl --context=$CLUSTER_1 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/kubernetes-manifests kubectl --context=$CLUSTER_2 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/kubernetes-manifests
Los servicios de Kubernetes deben estar en ambos clústeres para el descubrimiento de servicios. Cuando un servicio de uno de los clústeres intenta realizar una solicitud, primero realiza una búsqueda de DNS para el nombre de host a fin de obtener la dirección IP. En GKE, el servidor de
kube-dns
que se ejecuta en el clúster controla esta búsqueda, por lo que se requiere una definición de servicio configurada.Borra el
StatefulSets
de un clúster para que las dos bases de datos de PostgreSQL existan solo en uno de los clústeres:# Delete the two DB statefulSets from Cluster2 kubectl --context=$CLUSTER_2 -n bank-of-anthos delete statefulset accounts-db kubectl --context=$CLUSTER_2 -n bank-of-anthos delete statefulset ledger-db
Asegúrate de que todos los Pods se ejecuten en ambos clústeres:
Obtén Pods de
cluster_1
:kubectl --context=${CLUSTER_1} -n bank-of-anthos get pod
El resultado luce de la siguiente manera:
NAME READY STATUS RESTARTS AGE accounts-db-0 2/2 Running 0 9m54s balancereader-c5d664b4c-xmkrr 2/2 Running 0 9m54s contacts-7fd8c5fb6-wg9xn 2/2 Running 1 9m53s frontend-7b7fb9b665-m7cw7 2/2 Running 1 9m53s ledger-db-0 2/2 Running 0 9m53s ledgerwriter-7b5b6db66f-xhbp4 2/2 Running 0 9m53s loadgenerator-7fb54d57f8-g5lz5 2/2 Running 0 9m52s transactionhistory-7fdb998c5f-vqh5w 2/2 Running 1 9m52s userservice-76996974f5-4wlpf 2/2 Running 1 9m52s
Obtén Pods de
cluster_2
:kubectl --context=${CLUSTER_2} -n bank-of-anthos get pod
El resultado luce de la siguiente manera:
NAME READY STATUS RESTARTS AGE balancereader-c5d664b4c-bn2pl 2/2 Running 0 9m54s contacts-7fd8c5fb6-kv8cp 2/2 Running 0 9m53s frontend-7b7fb9b665-bdpp4 2/2 Running 0 9m53s ledgerwriter-7b5b6db66f-297c2 2/2 Running 0 9m52s loadgenerator-7fb54d57f8-tj44v 2/2 Running 0 9m52s transactionhistory-7fdb998c5f-xvmtn 2/2 Running 0 9m52s userservice-76996974f5-mg7t6 2/2 Running 0 9m51s
Implementa las configuraciones de Cloud Service Mesh en ambos clústeres. Esto crea un Puerta de enlace en el espacio de nombres
asm-ingress
VirtualService en los espacios de nombresbank-of-anthos
para el serviciofrontend
, lo que te permite ingresar tráfico alfrontend
servicio.Por lo general, las
Gateways
son propiedad de los administradores de la plataforma o del equipo de administradores de redes. Por lo tanto, el recursoGateway
se crea en la puerta de enlace de entrada. espacio de nombres que pertenezca al administrador de la plataforma y podría usarse en otros espacios de nombres a través de sus propias entradas deVirtualService
. Este es un modelo de “Gateway compartida”.cat <<'EOF' > asm-vs-gateway.yaml apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: asm-ingressgateway namespace: asm-ingress spec: selector: asm: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: frontend namespace: bank-of-anthos spec: hosts: - "*" gateways: - asm-ingress/asm-ingressgateway http: - route: - destination: host: frontend port: number: 80 EOF kubectl --context=$CLUSTER_1 apply -f asm-vs-gateway.yaml kubectl --context=$CLUSTER_2 apply -f asm-vs-gateway.yaml
Ya implementaste la aplicación de Bank of Anthos en dos clústeres de GKE privados. Todos los servicios se ejecutan como servicios distribuidos, excepto la base de datos.
Cómo inspeccionar servicios distribuidos
En esta sección, usarás la herramienta de istioctl
para inspeccionar la configuración del proxy de cualquiera de los proxies. Esto te permite ver que los proxies de sidecar vean dos Pods para cada servicio, con un Pod en ejecución en cada clúster.
En Cloud Shell, inspecciona la lista de configuración de Endpoints de proxy-config en el Pod
frontend
encluster_1
:export FRONTEND1=$(kubectl get pod -n bank-of-anthos -l app=frontend \ --context=${CLUSTER_1} -o jsonpath='{.items[0].metadata.name}') istioctl proxy-config endpoints \ --context $CLUSTER_1 -n bank-of-anthos $FRONTEND1 | grep bank-of-anthos
El resultado luce de la siguiente manera:
10.12.0.6:5432 HEALTHY OK outbound|5432||accounts-db.bank-of-anthos.svc.cluster.local 10.12.0.7:8080 HEALTHY OK outbound|8080||balancereader.bank-of-anthos.svc.cluster.local 10.12.0.8:8080 HEALTHY OK outbound|8080||transactionhistory.bank-of-anthos.svc.cluster.local 10.12.0.9:8080 HEALTHY OK outbound|8080||userservice.bank-of-anthos.svc.cluster.local 10.12.1.10:8080 HEALTHY OK outbound|8080||ledgerwriter.bank-of-anthos.svc.cluster.local 10.12.1.9:8080 HEALTHY OK outbound|8080||contacts.bank-of-anthos.svc.cluster.local 10.12.2.11:5432 HEALTHY OK outbound|5432||ledger-db.bank-of-anthos.svc.cluster.local 10.12.2.13:8080 HEALTHY OK outbound|80||frontend.bank-of-anthos.svc.cluster.local 10.76.1.10:8080 HEALTHY OK outbound|8080||transactionhistory.bank-of-anthos.svc.cluster.local 10.76.1.8:8080 HEALTHY OK outbound|8080||balancereader.bank-of-anthos.svc.cluster.local 10.76.1.9:8080 HEALTHY OK outbound|80||frontend.bank-of-anthos.svc.cluster.local 10.76.2.10:8080 HEALTHY OK outbound|8080||userservice.bank-of-anthos.svc.cluster.local 10.76.2.8:8080 HEALTHY OK outbound|8080||contacts.bank-of-anthos.svc.cluster.local 10.76.2.9:8080 HEALTHY OK outbound|8080||ledgerwriter.bank-of-anthos.svc.cluster.local
En el resultado anterior, cada servicio distribuido tiene dos direcciones IP de extremos. Estas son las direcciones IP del Pod, una para cada clúster.
Accede a Bank of Anthos
Para acceder a la aplicación Bank of Anthos, puedes usar la dirección IP pública del servicio asm-ingressgateway
de cualquiera de los clústeres.
Obtén direcciones IP
asm-ingressgateway
de ambos clústeres:kubectl --context ${CLUSTER_1} \ --namespace asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress" kubectl --context ${CLUSTER_2} \ --namespace asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress"
La salida se verá de la siguiente manera.
{"ingress":[{"ip":"35.236.4.18"}]} {"ingress":[{"ip":"34.68.94.81"}]}
Copia una de las direcciones IP para usarlas en el siguiente paso.
Abre una pestaña nueva en un navegador web y ve a cualquier dirección IP del resultado anterior. Debería aparecer el frontend de Bank for Anthos, que te permite acceder a tu cuenta, depositar fondos y transferirlos a otras cuentas. La aplicación debe ser completamente funcional.
Visualiza servicios distribuidos
Puedes visualizar servicios distribuidos en Cloud Service Mesh.
Para ver tus servicios, ve a Malla de servicios en la consola de Google Cloud.
Puedes ver los servicios en la vista de tabla o en una vista de topología. La vista predeterminada es la vista de tabla, que muestra todos los servicios distribuidos que se ejecutan en formato tabular. Para cambiar las vistas, haz clic en la vista que deseas mostrar.
En la vista Tablas, haz clic en
frontend distributed service
. Cuando haces clic en un servicio individual, verás una vista detallada del servicio junto con los servicios conectados.En la vista de detalles del servicio, puedes hacer clic en Mostrar cronograma para crear un SLO y ver un cronograma histórico del servicio.
Para ver los indicadores dorados, en el panel lateral, haz clic en Métricas.
En el gráfico Solicitudes por segundos, haz clic en Desglose por y, luego, selecciona Ubicación.
Los resultados muestran las solicitudes por segundo de ambos clústeres en las dos regiones. El servicio distribuido está en buen estado y ambos extremos entregan tráfico.
Para ver la topología de tu malla de servicios, en el panel lateral, haz clic en Anthos Service Mesh y, luego, en Vista de topología.
Para ver datos adicionales, mantén el puntero del mouse sobre el servicio
frontend
. Esto muestra información como solicitudes por segundo hacia y desde el frontend a otros servicios.Para ver más detalles, haz clic en Expandir en el servicio
frontend
. Se muestran un servicio y una carga de trabajo. Puedes expandir aún más la carga de trabajo en dos Deployments, expandir las implementaciones en ReplicaSets y expandir los ReplicaSets a los Pods. Cuando expandes todos los elementos, puedes ver el servicio distribuidofrontend
, que es un servicio y dos pods.
Configura Ingress de varios clústeres
En esta sección, crearás un Ingress de varios clústeres que envía tráfico a los servicios frontend
de Bank of GKE Enterprise que se ejecutan en ambos clústeres. Usas
Cloud Load Balancing
para crear un balanceador de cargas que use los Services asm-ingressgateway
como backends. Un clúster ingress-config
se usa para organizar la configuración de Ingress de varios clústeres.
Para crear el balanceador de cargas, usa un MultiClusterIngress
y uno o más MultiClusterServices
. Los objetos MultiClusterIngress
y MultiClusterService
son análogos de varios clústeres para los recursos de Ingress y servicio de Kubernetes existentes que se usan en el contexto de clúster único.
Habilita las funciones necesarias de GKE Enterprise, GKE Fleet y APIs de Ingress de varios clústeres:
gcloud services enable \ anthos.googleapis.com \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com
Cree el clúster
ingress-config
. Puedes usar cualquier clúster, pero te recomendamos que crees un clúster independiente para este fin.gcloud container clusters create ${CLUSTER_INGRESS} \ --zone ${CLUSTER_INGRESS_ZONE} \ --num-nodes=1 \ --enable-ip-alias \ --workload-pool=${WORKLOAD_POOL}
Obtén las credenciales del clúster y cambia el nombre del contexto para mayor comodidad:
gcloud container clusters get-credentials ${CLUSTER_INGRESS} \ --zone ${CLUSTER_INGRESS_ZONE} --project ${PROJECT_ID} kubectl config rename-context \ gke_${PROJECT_ID}_${CLUSTER_INGRESS_ZONE}_${CLUSTER_INGRESS} ${CLUSTER_INGRESS}
Para usar Ingress de varios clústeres, registra todos los clústeres participantes en Flota empresarial de GKE, incluido el clúster de configuración:
Registra el clúster de configuración:
gcloud container fleet memberships register ${CLUSTER_INGRESS} \ --project=${PROJECT_ID} \ --gke-cluster=${CLUSTER_INGRESS_ZONE}/${CLUSTER_INGRESS} \ --enable-workload-identity
Verifica que todos los clústeres estén registrados en la flota de GKE Enterprise:
gcloud container fleet memberships list
El resultado luce de la siguiente manera:
NAME EXTERNAL_ID gke-west 7fe5b7ce-50d0-4e64-a9af-55d37b3dd3fa gke-central 6f1f6bb2-a3f6-4e9c-be52-6907d9d258cd gke-ingress 3574ee0f-b7e6-11ea-9787-42010a8a019c
Habilita las funciones de entrada de clústeres múltiples en el clúster
ingress-config
. Esto crea las CustomResourceDefinitions (CRD)MulticlusterService
yMulticlusterIngress
en el clúster.gcloud container fleet ingress enable \ --config-membership=projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_INGRESS}
Verifica que el Ingress de varios clústeres esté habilitado en el clúster
ingress-config
:gcloud container fleet ingress describe
El resultado luce de la siguiente manera:
membershipStates: projects/986443280307/locations/global/memberships/gke-central-priv: state: code: OK updateTime: '2022-09-29T13:57:02.972748202Z' projects/986443280307/locations/global/memberships/gke-ingress: state: code: OK updateTime: '2022-09-29T13:57:02.972744692Z' projects/986443280307/locations/global/memberships/gke-west-priv: state: code: OK updateTime: '2022-09-29T13:57:02.972746497Z'
Verifica que las dos CRD se implementen en el clúster
ingress-config
:kubectl --context=${CLUSTER_INGRESS} get crd | grep multicluster
La salida se verá de la siguiente manera.
multiclusteringresses.networking.gke.io 2020-10-29T17:32:50Z multiclusterservices.networking.gke.io 2020-10-29T17:32:50Z
Crea el espacio de nombres
asm-ingress
en el clústeringress-config
:kubectl --context ${CLUSTER_INGRESS} create namespace asm-ingress
Crea el recurso
MultiClusterIngress
:cat <<EOF > ${HOME}/mci.yaml apiVersion: networking.gke.io/v1beta1 kind: MultiClusterIngress metadata: name: asm-ingressgateway-multicluster-ingress spec: template: spec: backend: serviceName: asm-ingressgateway-multicluster-svc servicePort: 80 EOF
Crea el recurso
MultiClusterService
:cat <<'EOF' > $HOME/mcs.yaml apiVersion: networking.gke.io/v1beta1 kind: MultiClusterService metadata: name: asm-ingressgateway-multicluster-svc annotations: beta.cloud.google.com/backend-config: '{"ports": {"80":"gke-ingress-config"}}' spec: template: spec: selector: asm: ingressgateway ports: - name: frontend protocol: TCP port: 80 # servicePort defined in Multi Cluster Ingress clusters: - link: "us-west2-a/gke-west-priv" - link: "us-central1-a/gke-central-priv" EOF
Crea el recurso
BackendConfig
para las verificaciones de estado:cat <<EOF > $HOME/backendconfig.yaml apiVersion: cloud.google.com/v1beta1 kind: BackendConfig metadata: name: gke-ingress-config spec: healthCheck: type: HTTP port: 15021 requestPath: /healthz/ready EOF
Aplica los manifiestos
BackendConfig
,MultiClusterService
yMultiClusterIngress
:kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/backendconfig.yaml kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/mci.yaml kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/mcs.yaml
El
MultiClusterService
que implementaste en el clúster de Ingress creará unService
“sin interfaz gráfica” en los clústeres 1 y 2. Verifica que se hayan creado losServices
“sin interfaz gráfica”:kubectl --context=${CLUSTER_1} -n asm-ingress \ get services | grep multicluster-svc kubectl --context=${CLUSTER_2} -n asm-ingress \ get services | grep multicluster-svc
El resultado es similar al siguiente:
mci-frontend-multi-cluster-service-svc-f7rcyqry22iq8nmw ClusterIP None <none> 80/TCP 77s mci-frontend-multi-cluster-service-svc-f7rcyqry22iq8nmw ClusterIP None <none> 80/TCP 78s
Ejecuta el siguiente comando y espera hasta que obtengas una dirección IP de Cloud Load Balancing:
watch kubectl --context ${CLUSTER_INGRESS} -n asm-ingress get multiclusteringress \ -o jsonpath="{.items[].status.VIP}"
El resultado luce de la siguiente manera:
35.35.23.11
Para salir del comando watch, presiona Ctrl+C.
Navega a la dirección IP de Cloud Load Balancing en un navegador web para acceder al frontend de Bank of Anthos:
kubectl --context ${CLUSTER_INGRESS} \ -n asm-ingress get multiclusteringress \ -o jsonpath="{.items[].status.VIP}"
Si recibes un error 404 (o 502), espera unos minutos y, luego, actualiza la página en tu navegador web.
Limpia
Para evitar que se apliquen cargos a tu cuenta, borra el proyecto o la entre los clústeres de Kubernetes.
Borra el proyecto
La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Borra los clústeres
En Cloud Shell, anula el registro y borra los clústeres
blue
ygreen
:gcloud container fleet memberships unregister ${CLUSTER_1} \ --project=${PROJECT} \ --gke-uri=${CLUSTER_1_URI} gcloud container clusters delete ${CLUSTER_1} \ --zone ${CLUSTER_1_ZONE} \ --quiet gcloud container fleet memberships unregister ${CLUSTER_2} \ --project=${PROJECT} \ --gke-uri=${CLUSTER_2_URI} gcloud container clusters delete ${CLUSTER_2} \ --zone ${CLUSTER_2_ZONE} \ --quiet
Borra el recurso
MuticlusterIngress
del clúster de configuración de Ingress:kubectl --context ${CLUSTER_INGRESS} -n istio-system delete -f $HOME/mci.yaml
Con este comando, se borran los recursos de Cloud Load Balancing del proyecto.
Cancela el registro del clúster
ingress-config
y bórralo:gcloud container fleet memberships unregister ${CLUSTER_INGRESS} \ --project=${PROJECT} \ --gke-uri=${CLUSTER_INGRESS_URI} gcloud container clusters delete ${CLUSTER_INGRESS} \ --zone ${CLUSTER_INGRESS_ZONE} \ --quiet
Verifica que se borren todos los clústeres:
gcloud container clusters list
Este es el resultado:
<null>
Restablece el archivo
kubeconfig
:unset KUBECONFIG
¿Qué sigue?
- Obtén más información sobre Ingress de varios clústeres.
- Obtén más información para implementar Ingress de varios clústeres en diferentes clústeres.