Istio es el complemento perfecto de Kubernetes. Una solución elegante y completa de “networking”, que además proporciona registro y monitorización en varias plataformas (Prometheus, Grafana, Jaeger, Servicegraph, etc), que viene integrado directamente en su “control plane”.
En este informe, más que deconstruir; explicando por separado cada componente del que consiste Istio Kubernetes, veremos qué es Istio y cómo puede simplificar la gestión de un clúster, a medida que éste vaya creciendo. También exploramos los planteamientos que debería cambiar un administrador y la diferencia entre el manejo de datos de un clúster; con y sin Istio.
Gestión del Tráfico en Istio Kubernetes
El problema
Al pasar de una aplicación monolítica a una basada en micro-servicios, no todo son ventajas. Una aplicación monolítica se puede dividir en decenas de micro-servicios. A medida que un clúster va creciendo es inevitable tener varias decenas, e incluso centenares de servicios corriendo; con diferentes versiones, en diferentes entornos, etc. Esto hace que sea muy difícil de visualizar el clúster y haya cada vez más propensión a equivocarse.
¿Qué es Istio Kubernetes y cómo simplifica el tráfico?
Istio Kubernetes es una red (o malla) de servicio que proporciona gestión de tráfico, aplicación de políticas de complimiento y recolección de métricas. Una malla de servicios (“Service mesh”) es una capa de infraestructura dedicada para gestionar la comunicación de servicio a servicio.
En Istio Kubernetes, esto se consigue configurando proxies basados en “Envoy”, que es añadido a los pods como container “sidecar”, e impone el flujo natural del tráfico al backend apropiado, mientras inhabilita a otros servicios que se comuniquen con este. Además, los servicios no se comunican directamente, sino que lo hacen a través de sus contenedores sidecar (“Envoy”). El responsable de este proceso es el “Pilot”.


Puede que algunos se hayan dado cuenta que con este comportamiento, Istio Kubernetes satisface algunos requerimientos que se conseguiría con NetworkPolicies.
En la imagen de arriba se puede ver que los servicios A y B solo se comunican directamente con sus contenedores sidecar Envoy asociados. Así que si el servicio A quisiera enviar un paquete al servicio B, se lo pasaría a su contenedor Envoy, que se lo enviaría al contenedor Envoy del servicio B, que a su vez se lo pasaría al servicio B.
Si el servicio B tuviera varias réplicas, Pilot se encargaría de la distribución de la carga de forma homogénea, así es como se podría configurar para que un porcentaje de solicitudes fuera a un servicio B’, o que las solicitudes con ciertos headers vayan a un servicio B’.


La recolecta y visualización de las métricas es un añadido que se agradece. La verdad es que es una práctica bastante astuta por parte del equipo Istio. Una vez se tiene el paquete a enrutar, no cuesta nada multiplexarlo a otro bloque y sacar el máximo jugo al tráfico. El bloque que se encarga de esta tarea es el Mixer.
Mixer aplica políticas de complimiento a lo largo de la malla (comprueba si el servicio A está configurado para hablar con el servicio B) y recoge métricas de los containers sidecar Envoy y otros servicios (figura abajo). Además proporciona varias funcionalidades adicionales en Istio Kubernetes. Debido a su modelo plugin de propósito general, es posible ampliar los backends infra-estructurales con los que puede interactuar Mixer de forma relativamente fácil. Implica programar un adaptador.
Istio Kubernetes viene con varios adaptadores (que son como drivers) de Mixer incorporados; éstos permiten con mínima configuración conseguir un fin en particular, como por ejemplo tener los logs y las métricas en la herramienta de nuestra elección.
Para la monitorización en Prometheus, pasariamos las métricas al adaptador de Prometheus y el Mixer se encargaría del resto.


Lo bueno de Istio es que está implementado como una extensión de Kubernetes, lo que hace que los objetos estén integrados dentro del api-server. Esto hace que el Admin tenga que aprenderse algunos objetos nuevos de Kubernetes y su propósito, en vez de desplegar una aplicación desacoplada y configurarla.
Esto es una ventaja que proporciona Kubernetes, no Istio Kubernetes directamente.
Los objetos nuevos a destacar para la gestión del tráfico son Gateway, VirtualSevice y DestinationRule. Estos objetos, combinados, y el control de plano de Istio, permiten reemplazar al ingress controller por defecto o integrar uno, en caso de no tenerlo. En GKE, esto implicaría en un control más granular y flexible del tráfico y menor coste. A continuación vamos a ver estos objetos y su propósito.
- Gateway: El objeto Gateway describe cómo debe entrar el tráfico al clúster. En este objeto típicamente se definiría el puerto, el protocolo, el host, información sobre el certificado y la llave TLS, etc. Una solicitud tendría que satisfacer los requisitos exigidos para entrar al clúster.
- VirtualService: Un VirtualService va enlazado a un Gateway. En este objeto se definen reglas de enrutamiento; éstas se aplican a todas las solicitudes que hayan superado los requisitos del Gateway, al cual va enlazado. Una configuración típica sería distribuir el tráfico entre varios backend, según el path.
- DestinationRule: El DestinationRule define reglas, que se aplican a una solicitud que ya ha sido enrutado hacia un servicio en particular. Puede darse el caso que tengamos varias versiones de una misma aplicación, de este modo, e podría definir un subconjunto de la aplicación y dependiendo de algunos parámetros, enviar el tráfico a una versión u otra. Estas comprobaciones se harían en el VirtualService.
Este es un enfoque ligeramente diferente al utilizar un objeto del tipo Ingress, que enrutaría el paquete a un servicio, que acabaría en un pod. Aunque Istio Kubernetes sea capaz de gestionar un objeto Ingress, puede que no sea muy buena idea, por la flexibilidad de la alternativa descrita arriba. Dicho de otra forma, Istio Kubernetes gestiona los paquetes que entran en el cluster de forma propia, ésta resulta ser más apropiada que utilizar el convencional objeto Ingress.
Istio, con estos objetos, consigue un comportamiento similar al que se conseguiría con NetworkPolicies, aunque no de la misma forma.
En Istio, la comunicación no autorizada se bloquea tanto para Ingress, como para Egress. Para el Egress, se puede destacar un objeto: ServiceEntry.
- ServiceEntry: El objeto ServiceEntry permite añadir servicios externos al clúster, al mesh. Es decir, si quisieramos acceder a “google.com”, por ejemplo, desde un pod de dentro del mesh, no podríamos a menos que añadiésemos un ServiceEntry permitiendo el acceso a “google.com”.
Monitorización
Para la gestión de logs y monitorización, los objetos son varios y se agrupan en tres tipos; instances, handlers y rules. A continuación, vamos a ver qué son. Recordemos, de Mixer, que Istio Kubernetes tiene varios adaptadores, de herramientas muy popularesintegradas por defecto.
- Instances: Un instance define los atributos que se deben pasar a un adaptador. Típicamente podría ser una métrica.
- Handler: Un handler se encarga de entregar el atributo de forma correcta al adaptador. Si decimos que Istio Kubernetes tiene varios adaptadores integrados por defecto, estamos diciendo que tiene varios tipos de handlers pre-definidos.
- Rule: Un rule enlaza un Instance a un handler.
Por ejemplo, si quisiéramos monitorizar una aplicación en Prometheus, crearíamos un objeto tipo metric que sería el instance, en el cual definiríamos las métricas que queremos monitorizar. También crearíamos un objeto tipo prometheus, que sería el handler, donde definiríamos cómo queremos procesar y formatear las métricas. Por último, un objeto tipo rule enlazaría al instance con el handler, para que Mixer sepa cómo actuar.
Istio, recoge por defecto las métricas del plano de control. Lo que hace que sea más fácil identificar ciertos problemas. Uno tendría que configurar solo las métricas de su aplicación. Debajo, un ejemplo de Grafana con con el dashboard de la malla de servicios.


Ventajas Istio Kubernetes
Clúster con Istio
Kubernetes, por defecto, viene sin algunos controladores. Ingress Controller y NetworkPolicy Controller, son algunos de ellos. Esta es una de las inconvenientes de utilizar Kubernetes en bare metal, que hay que adaptarlo al plano de control en el que corre y, por eso, soluciones como GKE o EKS son tan populares.
En GKE, se puede habilitar/instalar Istio al crear el clúster. Pero GKE ya tiene GCLB, que es el Ingress Controller de Kubernetes de Google y se puede instalar Calico al crear el clúster, como NetworkPolicy Controller, igual que Istio. Veamos cuál es la diferencia entre utilizar estos controladores e Istio.
Ingress Controller
Con GCLB y un objeto del tipo Ingress tenemos un Load Balancer de capa 7 (L7). Podemos redirigir el tráfico hacía un servicio u otro, dependiendo del host y el path de la solicitud. Esto es un mapeo uno-a-uno. Una misma solicitud siempre será redirigida hacia el mismo servicio, que irá a parar al mismo set de pods (backends).


Esta es una forma un poco rígida de gestionar el tráfico. Por ejemplo, para redirigir el 5% del tráfico a una versión “canary” de la aplicación, habría que crear 1 pod “canary” por cada 19 de la aplicación principal, y configurarlos para que sean apuntados por el mismo servicio. Aunque no hagan falta 20 pods para respaldar el tráfico, para conseguir el 95-5 deseado, es la única forma de conseguirlo.
Con Istio, esto es bastante más cómodo. Lo que hace Istio Kubernetes es añadir otro salto entre el servicio y el backend, dando una flexibilidad considerable. Se pueden definir tantos “sub-servicios” como necesarios, en cuyo caso el servicio haría un balanceo de carga homogénea entre los backends de cada “sub-servicio”, y si quisiéramos redirigir un 5% del tráfico a los backends de un “sub-servicio” específico, lo definiríamos explícitamente, al crearlo.


En la imagen de arriba, se puede ver que el Servicio 1 tiene dos versiones. Si no se especifica explícitamente, el tráfico será enviado por igual a las dos versiones. El Servicio 2 enviará un 95% de las solicitudes a la versión 1, y el 5% a la versión 2. Así, con 3 backends, se puede conseguir una versión “canary” sin complicarse.
También se puede configurar este comportamiento con headers. Por ejemplo, se puede forzar que las solicitudes desde un iPhone sean redirigidos a una versión de la aplicación, mientras que las solicitudes desde un Android, son respondidos por otra. El concepto de “sub-servicio”, en Istio, es el subset de un host,que se especifica en un VirtualService.
Network Policy Controller
Las NetworkPolicies son las reglas internas del clúster con respecto quién puede hablar con quién. El objeto NetworkPolicy permite agrupar un grupo de pods, por sus labels y aplicarles políticas de ingress, egress, o ambos. La política se aplica denegando todo tráfico hacia el grupo de pods seleccionado, y se permite el tráfico desde tres fuentes:
- Pods de un namespace. Cualquier pod que haya sido creado en un namespace específico, puede comunicarse con el grupo de pods.
- Pods con ciertos labels. Cualquier pod, desde cualquier namespace, con ciertos labels, puede comunicarse con el grupo de pods.
- Tráfico desde un bloque de IPs. Típicamente serían IPs internos, no pertenecientes al clúster. Pueden ser IPs internos al clúster, pero en ese caso sería más conveniente enfocarlo como los dos puntos anteriores.
Hay que decir que las NetworkPolicies son objetos bastante robustos y desaprovechados. El único inconveniente es que el controlador es de terceros y hay que buscar e instalar uno.
En Istio, no se configura nada directamente para este propósito, sino que pasa naturalmente al configurar las rutas. Como los proxies Envoy, dentro de la malla, están configurados para aceptar tráfico solo desde fuentes específicas, el resultado es similar, aunque con otro enfoque.
La gestión de logs y la monitorización de Istio Kubernetes, de la forma que lo hace, es algo nuevo, así que no se puede realmente comparar con ninguna otra solución. Quizás con Stackdriver (dentro de GCP), pero son de diferentes envergaduras, así que no haremos esa comparación en este artículo.
Conclusión
Personalmente encontramos Istio una herramienta bastante cómoda y potente con que trabajar. Como una navaja suiza. Aunque no tengamos un clúster grande, el hecho de que los objetos estén integrados directamente en Kubernetes, la flexibilidad de enrutar el tráfico, la aplicación de políticas de cumplimiento, la gesta de logs y la monitorización hacen que Istio Kubernetes definitivamente sea de considerar para añadir a nuestra caja de herramientas.