Anthos Service Mesh (ASM) es una instalación administrada de Istio, un service mesh para Kubernetes. Sigue esta guía paso a paso para configurar un ASM multicluster con el managed control plane.

Esta es una guía sencilla, paso a paso, para montar un Anthos Service Mesh (ASM) multicluster con el managed control plane.
El código que acompaña a la guía está disponible aquí: https://github.com/caddac/anthos-examples/tree/main/asm
Un service mesh es una capa de abstracción que se monta sobre distintas plataformas de cómputo —en este caso, clusters— para simplificar la comunicación entre servicios, la observabilidad y la seguridad. Esas responsabilidades se trasladan a la plataforma y, como resultado, la aplicación queda más simple. En este post desplegaremos Anthos Service Mesh, una instalación administrada de Istio. Istio es un service mesh para Kubernetes y una herramienta potente para obtener visibilidad consistente de la observabilidad y la seguridad entre servicios. Con Istio esto se logra enrutando toda la comunicación entre servicios a través de proxies que corren como sidecars junto a tus pods.
Los servicios pueden apoyarse en los patrones consistentes y transparentes de Istio para comunicarse entre sí, sin tener que ocuparse de cómo llegar a otro servicio, de la seguridad ante peticiones entrantes o de publicar métricas sobre el tráfico entre servicios. De todo eso se encarga Istio. Estas capacidades son aún más valiosas en una configuración multicluster, donde la sobrecarga operativa es todavía mayor.
Usar un service mesh también tiene algunas contras: complejidad de configuración, consumo extra de recursos y costo. Istio incluye muchas funcionalidades y varias formas de configurarlo, como istioctl, IstioOperator y helm. Sin embargo, Anthos Service Mesh con managed control plane no admite la API de IstioOperator ni helm.
En este tutorial crearemos dos clusters de GKE y desplegaremos en ellos la aplicación hello-world de Istio. Después instalaremos un único ingress (en uno solo de los clusters) y comprobaremos que el tráfico se balancea entre los 4 pods de hello-world que corren en los dos clusters de GKE.

Despliega el terraform
En el directorio asm/infra, actualiza los valores del archivo var_inputs.auto.tfvars.
Planéalo y aplícalo:
$ terraform init
$ terraform apply
Nota: si el apply falla, vuelve a intentarlo. A veces terraform se adelanta cuando aplica tantos recursos dependientes a la vez. A mí me tocó ejecutarlo tres veces para que se crearan todos los recursos.
Aquí pasan muchas cosas, así que las repasamos brevemente.
Despliega un nuevo proyecto de GCP y habilita varias APIs necesarias [1]. Una nota rápida: la documentación oficial parece omitir las APIs sts y anthos, así que no olvides habilitarlas.
También crea una VPC, dos subredes con rangos secundarios y una regla de firewall para que todo se comunique. Por último, habilita la funcionalidad de hub mesh en el proyecto.
Cada archivo despliega un cluster. Solo difieren en los nombres de los clusters, las regiones y las referencias a las subredes. Hay dos detalles a destacar de la configuración del cluster. Primero, definimos la etiqueta mesh_id para que GCP sepa a qué mesh pertenece el cluster. Segundo, habilitamos Workload Identity, que permite que las service accounts de Kubernetes actúen como service accounts de GCP [2] sin tener que descargar —ni siquiera crear— claves JSON.
Registramos el cluster en la fleet usando su nombre como id de membresía.
Por último, instalamos el managed control plane. Estamos usando el control-plane automático (es decir, "managed"), pero ¿qué revisión? Revisa la etiqueta de revisión en el namespace para ver qué revisión del control plane está en uso [5]. ¡Sí, así de fácil!
A estas alturas tenemos dos clusters corriendo en la misma fleet, ambos con ASM instalado mediante el managed control plane. Así que, aunque ya podemos empezar a instalar componentes de Istio, los clusters todavía no tienen activo el descubrimiento de servicios entre clusters.
Configura el descubrimiento de servicios entre clusters
Tenemos que instalar los secrets de cada cluster en todos los demás clusters de la fleet. Por suerte, existe una herramienta de cli para esto: asmcli. Lo malo es que todavía no funciona en macOS, así que lo más práctico es ejecutarla desde la cloud console.
Abre la cloud console de tu proyecto entrando a la consola de GCP y haciendo clic en el botón de cloud console.

Cuando la consola aparezca en la parte inferior de la pantalla, ejecuta los siguientes comandos:
$ curl https://storage.googleapis.com/csm-artifacts/asm/asmcli\_1.13 > asmcli
$ chmod +x asmcli
_$ ./asmcli create-mesh ${GOOGLE_CLOUD_PROJECT} _
_${GOOGLE_CLOUD_PROJECT}/us-west1/${GOOGLE_CLOUD_PROJECT}-cluster1 _
${GOOGLE_CLOUD_PROJECT}/us-east1/${GOOGLE_CLOUD_PROJECT}-cluster2

Una nota rápida: si trabajas con clusters privados, hay pasos adicionales para habilitar el descubrimiento de servicios entre clusters [6][7].
Despliega las apps y los componentes de Istio
Desde el directorio asm/manifests podemos instalar apps para probar el mesh. En el cluster 1 vamos a instalar la app helloworld y los componentes de Istio para el ingress.
Empieza obteniendo los contextos de los clusters:
export PROJECT_ID=<gcp_project_id>
gcloud container clusters get-credentials ${PROJECT_ID}-cluster1 --region us-west1 --project ${PROJECT_ID}
gcloud container clusters get-credentials ${PROJECT_ID}-cluster2 --region us-east1 --project ${PROJECT_ID}
Instala el cluster 1 con:
kubectl apply -k manifests/ --context=gke_${PROJECT_ID}_us-west1_${PROJECT_ID}-cluster1
Y el cluster 2 con:
kubectl apply -k manifests/app/ --context=gke_${PROJECT_ID}_us-east1_${PROJECT_ID}-cluster2

Revisa tu trabajo
Después de unos minutos todo debería estar arriba y podrás revisar el resultado.
Comprueba que todos los pods de helloworld estén corriendo en ambos clusters:
$ export PROJECT_ID=<gcp_project_id>
$ kubectl get pods -n helloworld
--context=gke_${PROJECT_ID}_us-west1_${PROJECT_ID}-cluster1
$ kubectl get pods -n helloworld
--context=gke_${PROJECT_ID}_us-east1_${PROJECT_ID}-cluster2

Comprueba que el deployment del ingress-gateway esté corriendo en el cluster 1:
$ kubectl get deploy -n asm-gateways --context=gke_${PROJECT_ID}_us-west1_${PROJECT_ID}-cluster1

Comprueba que el servicio del ingress-gateway tenga una IP externa en el cluster 1:
$ kubectl get svc -n asm-gateways --context=gke_${PROJECT_ID}_us-west1_${PROJECT_ID}-cluster1

Por último, verifica que el balanceo de carga entre clusters funciona consultando el endpoint público varias veces. Verás que la versión y el id del pod cambian a medida que las peticiones caen en pods distintos. Deberías obtener 4 ids de pod diferentes y 2 versiones distintas.

$ curl /hello

Personalización y consulta de logs
Habilita los logs de depuración de envoy
Esto ya lo hicimos al desplegar la configuración de asm. Echa un vistazo al archivo asm/manifests/gateways/asm-config.yaml. El ConfigMap que desplegamos configura los proxies de envoy para que envíen sus access logs a stdout. Hay otras opciones que puedes habilitar de forma parecida [3].
Logs del control plane
Aun usando el managed control plane puedes seguir consultando los logs del control plane. Están en Logs Explorer, bajo el recurso "Istio Control Plane".
Referencias
- https://cloud.google.com/service-mesh/docs/managed/auto-control-plane-with-fleet#before_you_begin
- https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity
- https://cloud.google.com/service-mesh/docs/managed/enable-managed-anthos-service-mesh-optional-features
- https://cloud.google.com/service-mesh/docs/managed/auto-control-plane-with-fleet
- https://cloud.google.com/service-mesh/docs/managed/select-a-release-channel#how_to_select_a_release_channel
- https://cloud.google.com/service-mesh/docs/unified-install/gke-install-multi-cluster#private-clusters-endpoint
- https://cloud.google.com/service-mesh/docs/unified-install/gke-install-multi-cluster#private-clusters-authorized-network