Este artículo es la continuación de mi post anterior, en el que compartí mi opinión sobre Istio Ambient Mesh y lo comparé con el modelo tradicional de Data Plane basado en sidecars.
Aquí te muestro cómo instalar y usar Istio Ambient Mesh en un cluster de Google Kubernetes Engine desplegado en Google Cloud Platform.
Nota: Istio Ambient Mesh todavía se encuentra en alpha y no debería usarse en entornos de producción hasta que pase a General Availability (GA).
Requisitos previos
- El cluster debe ejecutar una versión soportada de Kubernetes (1.25, 1.26, 1.27, 1.28, 1.29).
- El CNI (Container Network Interface) debe estar habilitado en el cluster. Los clusters de GKE traen GKE CNI habilitado por defecto. Dataplane v2 actualmente no es compatible.
- Al menos 3 nodos y 4 vCPU por nodo. Cada z-tunnel reserva 500mCPU y 2Gi de memoria, y eso sin contar los demás componentes, así que conviene tener suficiente vCPU y memoria disponibles.
- Requisitos de la plataforma
- Requisitos específicos de GKE
Nota: esta instalación no funciona en clusters de GKE Autopilot, ya que Dataplane v2 no es opcional, aunque sí puedes habilitar las capacidades NET_ADMIN y NET_RAW .
Importante: problemas de compatibilidad con DataPlane v2
Istio Ambient Mesh requiere instalar el plugin de Istio CNI, que reemplaza la funcionalidad del contenedor istio-init (el cual necesita las capacidades NET_ADMIN y NET_RAW) sin que las personas que ejecutan el despliegue requieran permisos RBAC elevados para aprovisionar contenedores privilegiados.
La documentación de Istio CNI incluye la siguiente advertencia.
Nota: el plugin de Istio CNI funciona como un plugin CNI encadenado y está diseñado para usarse junto con otro plugin CNI, como PTP o Calico. Consulta compatibilidad con otros plugins CNI para más detalles.
Aquí es donde la cosa se pone un poco enredada. El Data Plane heredado de GKE (hoy por defecto) usa GKE CNI (Calico CNI si Network Policy está habilitado), apoyándose en kube-proxies e iptables para enrutar el tráfico dentro del cluster.
En cambio, el relativamente nuevo GKE Data Plane v2 (que será el predeterminado y el estándar de facto a futuro) es básicamente una versión gestionada de Cilium CNI, con un Data Plane eBPF que reemplaza los kube-proxies por programas eBPF modernos para mejorar el networking.
Este artículo de Solo.io explica cómo configurar Cilium CNI sin romper Istio. Sin embargo, esto solo aplica al modelo de sidecar de Istio y, en cualquier caso, no funcionará con Dataplane V2, ya que se trata de un componente gestionado por GCP cuya configuración es inmutable.
DataPlane V2 sí utiliza un dispositivo veth, pero quizá los programas eBPF simplemente no son compatibles entre sí. Si conoces el motivo, me encantaría leerlo en los comentarios.

Por eso, debemos deshabilitar Dataplane v2 en nuestra implementación para que el componente de Istio CNI se instale correctamente.
Espero que en algún momento se dé soporte a Dataplane v2, ya que será el modo predeterminado del Data Plane en los clusters de GKE en un futuro cercano.
Configurando el cluster
En este ejemplo voy a crear un cluster básico de GKE con nodos privados y un endpoint público para el master.
Este es el comando que uso para desplegar el cluster en la red VPC predeterminada. Puedes ajustar las variables a tu gusto, pero asegúrate de que Dataplane v2 quede deshabilitado.
Tiene sentido contar con nodos más grandes y muchos pods por nodo para sacarle el máximo provecho en un entorno real.
export PROJECT_ID=`gcloud config get-value project` && \
export M_TYPE=e2-standard-4 && \
export ZONE=us-central1-a && \
export CLUSTER_NAME=ambient-mesh-cluster && \
gcloud services enable container.googleapis.com && \
gcloud container clusters create $CLUSTER_NAME \
--project $PROJECT_ID \
--cluster-version "latest" \
--release-channel "regular" \
--location $ZONE \
--machine-type $M_TYPE \
--image-type "COS_CONTAINERD" \
--num-nodes "3" \
--enable-private-nodes \
--master-ipv4-cidr "172.16.0.0/28" \
--enable-ip-alias \
--no-enable-master-authorized-networks \
--network "projects/$PROJECT_ID/global/networks/default" \
--subnetwork "projects/$PROJECT_ID/regions/us-central1/subnetworks/default"
Una vez creado el cluster, GCP genera automáticamente las reglas de firewall necesarias para que el master del control plane se comunique con los nodos.

Vemos que los puertos TCP 443 (HTTPS) y 10250 (Kubelet) están permitidos; sin embargo, esa regla no abre el puerto 15017, requerido por el webhook de validación de discovery de Pilot (componente del Control Plane de Istio).
Si usas un cluster privado de GKE (mi caso), tenemos que crear una regla de firewall que permita el tráfico desde el master por el puerto 15017. Primero, obtén el rango IP de origen del master y los network tags de la regla de firewall:
gcloud compute firewall-rules list --filter="name~gke-${CLUSTER_NAME}-[0-9a-z]*-master" --format="table(targetTags, sourceRanges.list())"
Luego, con el rango IP de origen y los network tags que arrojó el comando anterior, crea una nueva regla de firewall que permita el tráfico desde el master por el puerto TCP 15017:
gcloud compute firewall-rules create <firewall-rule-name> --network <VPC-name> --source-ranges=<CIDR_RANGE> --direction=INGRESS --target-tags=<TAG> --allow tcp:15017
Asegúrate también de tener Cloud NAT configurado en la VPC donde se desplegó el cluster, para que los pods de los nodos privados de GKE tengan salida a internet.
Descargando e instalando Istio en modo Ambient
Descarga la última versión de Istio:
curl -L https://istio.io/downloadIstio | sh -
Entra al directorio de Istio y agrega el cliente Istioctl a tu PATH:
cd istio-1.20.3/
export PATH=$PWD/bin:$PATH
Autentícate y conéctate a tu cluster de GKE (asegúrate de tener los permisos IAM suficientes para conectarte y desplegar en el cluster).
gcloud container clusters get-credentials ${CLUSTER_NAME} --zone ${ZONE} --project ${PROJECT_ID}
Instala los CRDs de Kubernetes Gateway:
$ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
{ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v1.0.0" | kubectl apply -f -; }
Instala Istio en modo ambient:
istioctl install --set profile=ambient --set "components.ingressGateways[0].enabled=true" --set "components.ingressGateways[0].name=istio-ingressgateway" --skip-confirmation
Deberías ver los siguientes 5 componentes instalados correctamente, en especial el CNI y el z-tunnel.

Verifica que los componentes estén instalados y listos revisando los pods y los DaemonSets en el namespace istio-system.

kubectl get pod -n istio-system

kubectl get ds -n istio-system

kubectl get ds -n kube-system
Desplegando aplicaciones en Istio Ambient Mesh
Una de las grandes ventajas de Istio es que no necesitas modificar tus aplicaciones. Aquí desplegaremos la clásica aplicación de ejemplo bookinfo de Istio tal cual viene y luego la sumaremos al mesh después del despliegue.
Encontrarás el código de la aplicación bookinfo en el mismo directorio donde instalaste Istio.
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
Despliega 2 aplicaciones más (clientes curl) que usaremos para simular tráfico hacia el entorno del mesh.
kubectl apply -f samples/sleep/sleep.yaml
kubectl apply -f samples/sleep/notsleep.yaml
Despliega un ingress gateway para acceder a la app Bookinfo desde internet.
kubectl apply -export GATEWAY_HOST=$(kubectl get service/istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}' -n istio-system)l
Obtén los endpoints interno y externo del servicio istio-ingressgateway. Enviaremos tráfico a ambos para visualizar tanto el tráfico dentro del mesh como el que llega desde fuera del cluster.
export GATEWAY_HOST_EXT=$(kubectl get service/istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}' -n istio-system)
export GATEWAY_HOST_INT=istio-ingressgateway.istio-system

visto desde el navegador
El Mesh en acción
Despliega una instalación de ejemplo de Prometheus y Kiali para monitorear y visualizar el tráfico, respectivamente.
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/prometheus.yaml
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/kiali.yaml
Modifica el archivo del servicio Kiali para exponerlo a internet y poder verlo desde tu navegador.
kubectl patch svc kiali -n istio-system -p '{"spec": {"type": "LoadBalancer"}}'
Ábrelo en el navegador en cuanto se aprovisione la IP externa para el servicio Kiali. Por ahora veremos pocos datos, ya que nuestras aplicaciones aún no forman parte del mesh.

Suma las aplicaciones de Bookinfo del namespace default al Ambient Mesh etiquetando el namespace.
kubectl label namespace default istio.io/dataplane-mode=ambient
Las aplicaciones ya forman parte del mesh sin interrupciones y de forma transparente. Enviemos algo de tráfico a estas aplicaciones desde nuestros clientes curl y veamos el mesh en acción.
curl http://$GATEWAY_HOST_EXT/productpage
#Tráfico desde el usuario al endpoint externo del gateway
kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST_INT/productpage"
#Tráfico desde un pod al endpoint interno del gateway
kubectl exec deploy/sleep -- curl -s http://productpage:9080/
#Tráfico desde un pod al svc (directamente)
kubectl exec deploy/notsleep -- curl -s http://productpage:9080/
#Tráfico desde un pod al svc (directamente)
Vuelve a revisar el grafo de Kiali. Ahora debería poblarse con datos que muestran las comunicaciones aseguradas con mTLS, junto con otra telemetría útil.

Aplicando políticas de autorización L7
Ahora que el secure overlay ya está en marcha, puedes aplicar fácilmente políticas de autorización L4, igual que harías con Istio en su modo predeterminado.
Sin embargo, este secure overlay no permite aprovechar el filtrado L7. Para eso necesitamos desplegar un waypoint proxy basado en Envoy para el servicio productpage.
El proxy se aplica sobre la service account, así que en el caso del servicio productpage la service account es bookinfo-productpage.
Despliega un waypoint proxy para el servicio productpage:
istioctl x waypoint apply --service-account bookinfo-productpage
Esto despliega un waypoint proxy para cualquier servicio que use la service account bookinfo-productpage.


De ahora en adelante, todo el tráfico hacia el servicio productpage tendrá que pasar por el proxy L7, que escala automáticamente según el uso.
Vamos a crear una AuthorizationPolicy L7 que permita explícitamente a las service accounts sleep y la del gateway hacer GET sobre el servicio productpage, sin habilitar ninguna otra operación.
export GATEWAY_SERVICE_ACCOUNT=ns/istio-system/sa/istio-ingressgateway-service-account
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: productpage-viewer
namespace: default
spec:
targetRef:
kind: Gateway
group: gateway.networking.k8s.io
name: bookinfo-productpage
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/default/sa/sleep
- cluster.local/$GATEWAY_SERVICE_ACCOUNT
to:
- operation:
methods: ["GET"]
EOF
Prueba la política en acción:
# esto debería fallar con un error RBAC porque no es una operación GET
kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage" -X DELETE
# La salida debería ser 'RBAC: access denied'
# esto debería fallar con un error RBAC porque la identidad no está permitida
kubectl exec deploy/notsleep -- curl -s http://productpage:9080/
# La salida debería ser 'RBAC: access denied'
# esto debería seguir funcionando
kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
# La salida debería ser '<title>Simple Bookstore App</title>'
Limpieza
Ejecuta los siguientes comandos para desinstalar Istio y sus componentes:
istioctl x waypoint delete --all
istioctl uninstall -y --purge
kubectl delete namespace istio-system
Elimina el cluster de GKE:
gcloud container clusters delete $CLUSTER_NAME --zone $ZONE
Resulta muy interesante cómo se modularizaron las funcionalidades L4 y L7 para ganar flexibilidad y eficiencia.
Tengo especial curiosidad por observar los beneficios a escala y me encantaría ver el Ambient Mesh en un entorno de producción real.
Espero que este artículo te haya resultado útil e interesante. No dudes en dejar tus comentarios y opiniones más abajo.