Como controlar un Application Gateway desde AKS
Esta entrada está escrita por Jorge Turrado, un crack tanto en lo personal como en lo profesional. Es un placer que haya elegido mi blog para publicar esa entrada. Si quieres leer más cosas publicadas por Jorge, pásate por su blog: Fixed Buffer. ¡Gracias!
Es un gusto poder estar aquí en el blog del grandísimo Eduard Tomas, el cual me ha abierto sus puertas encantado para escribir sobre un tema que personalmente me ha resultado muy interesante y útil. Os pongo en situación.
En los últimos meses he participado en un proyecto con una arquitectura típica trabajando con Kubernetes, teníamos nuestro nginx ingress controller desde el que enrutabamos el tráfico hacia los diferentes servicios y de ahí hacia sus respectivos pods. Todo esto trabajando sobre la nube de Microsoft, es decir, en AKS. En un momento dado, se tomo la decisión de poner por delante del AKS un Application Gateway (de aquí en adelante agw) que enrutase el tráfico de internet hacia el cluster. El escenario final con el que íbamos a trabajar era algo similar a esto:
Por si no conocéis Application Gateway, es un servicio de Azure que hace de “proxy inverso” y permite ciertas configuraciones de seguridad. Esto es muy útil a la hora de exponer ciertas partes de una red virtual privada hacia internet teniendo un control sobre lo que esta expuesto. En este caso un AKS, pero también podrían ser diferentes máquinas virtuales,etc…
Por hacer un breve resumen, las peticiones llegan al agw y desde ahí se reenvían al cluster, nginx recibe la petición y la enruta hacia el servicio correspondiente, y este último hacia el pod que le toca. Hemos añadido una capa más de seguridad a nuestro cluster al colocarlo detrás de un agw, pero hemos añadido un salto de red más que si nuestro escenario expusiera directamente el nginx. Aunque esto puede ser totalmente irrelevante en la gran mayoría de los casos, el salto extra esta ahí y tiene su coste.
Esto tiene una mejor solución (sino no estaría escribiendo esto), y consiste en utilizar el propio ingress controller que ofrece Microsoft para trabajar directamente contra el agw. Este ingress controller se llama “Application Gateway Ingress Controller” (de ahora en adelante agic). La manera de funcionar de este controlador consiste en analizar los objetos ingress que le pertenecen y realizar despliegues directamente sobre el agw. Con esto lo que vamos a conseguir es que el tráfico se enrute desde el agw directamente hacia los pods, evitándonos así 2 saltos de red. El nuevo planteamiento es algo similar a esto:
El código fuente de agic esta disponible en GithHub para poder echarle una ojeada.
Prerrequisitos
Contar esto es muy fácil, pero yo soy más de los que piensa que es mejor ver que oir, vamos a poner en marcha agic desde 0. Para eso, vamos a necesitar de varias cosas. Por supuesto un AKS y un Application Gateway (¿a qué nadie se lo imaginaba?), pero además también vamos a necesitar que ambos estén conectados a una red privada virtual (de aquí en adelante vnet) y dar permisos a agic para ver y editar el agw.
No es necesario que AKS y agw esten en la misma vnet, pueden estar desplegados en diferentes vnets sin ningún problema, pero en ese caso será necesario hacer los peerings correspondientes entre las redes para que las peticiones puedan viajar desde agw hasta el cluster.
Para los más veteranos en manejo de AKS, conoceréis que existen 2 tipos modos de manejar las identidades en un cluster de Kubernetes de Azure, utilizando un service principal o una identidad manejada. Esto mismo es aplicable también a como dar permisos sobre agic, que soporta los dos escenarios. Personalmente soy de los que opinan que es mejor gestionar permisos desde una identidad manejada que desde un service principal, y como me gusta complicarme vida, es el modelo que vamos a utilizar aquí. Por tanto, la lista de cosas que vamos a necesitar en cuanto a infraestructura es:
- Grupo de recursos
- Red Privada Virtual
- AKS
- Application Gateway
- Asignación de permisos para las identidad manejada de AKS
Una vez que tenemos claro lo que necesitamos desplegar antes de meternos en harina dentro del cluster, vamos con ello. Lo primero que vamos a hacer es desplegar el grupo de recursos con:
|
|
Disclaimer: Los rangos de las redes, tamaños y nodos del cluster, etc… los he elegido muy arbitrariamente, en cada caso concreto es necesario evaluar los rangos necesarios. El único requisito clave es que el agw debe ser como mínimo Standard_v2 y por tanto el sku de la IP pui también debe ser Standard.
Sobre ese grupo de recursos vamos a desplegar una vnet con dos subredes (una para el AKS y otra para agw) ejecutando:
|
|
Lo siguiente va a ser desplegar ya el cluster de AKS, para ello basta con ejecutar:
|
|
Importante: La asignación del rol “Network Contributor” es obligatoria al haber elegido el despliegue del cluster utilizando una identidad manejada en lugar de un service principal. En caso de que no se haga, el cluster tendrá fallos durante la operación.
Ya casí hemos terminado de desplegar infraestructura, solo nos queda la parte relativa al agw, la cual vamos a desplegar ejecutando:
|
|
Si todo ha ido bien, deberíamos poder ir al portal de Azure y encontrarnos algo como esto:
Requisitos
Después de un rato, ya tenemos la infraestructura lista para empezar a desplegar agic. Como decía antes, agic tiene 2 modos de autenticarse en Azure, utilizando un service principal o útilizando una identidad manejada. El hecho de que elijamos un sistema u otro va a cambiar la manera de proceder. Si elegimos utilizar un service principal, vamos a tener que crearlo y asignarle los permisos. En caso de utilizar una identidad manejada, vamos a tener que crearla y asignarle los permisos. ¿Dónde cambia entonces el proceso? Pues en que si utilizamos una entidad manejada, vamos a necesitar añadir al cluster un proxy de autenticación para que esa identidad pueda trabajar. Esto lo vamos a conseguir desplegando antes de agic ese proxy que en nuestro caso va a ser AAD-Pod-Identity.
En resumen, vamos a necesitar:
- Una entidad manejada
- Asignación de permisos (tanto a la nueva identidad como al cluster)
- Desplegar AAD-Pod-Identity
Lo primero que vamos a hacer es crear nuestra nueva identidad manejada con el comando:
|
|
Ahora, son 5 las asignaciones de roles que tenemos que realizar:
- La nueva identidad debe ser Contributor de agw
- La nueva identidad debe ser Reader del grupo de recursos donde se encuentra agw
- La identidad del cluster debe ser Managed Identity Operator de la nueva identidad
- La identidad de Kubelet debe ser contribuidor del grupo de recursos de los nodos
- La identidad de Kubelet debe ser Managed Identity Operator de la nueva identidad
Aunque estos dos últimos puede parecer que no tienen sentido ya que la identidad del cluster ya tiene esos permisos, es necesario para que AAD-Pd-Identity pueda trabajar, para mas info os dejo la issue en GitHub donde se habla del tema
Teniendo claro el camino, vamos con ello. Para eso basta con ejecutar los siguientes comandos:
|
|
Ahora si que hemos terminado de desplegar todo lo que necesitamos en Azure :)
Desplegar AAD-Pod-Identity en el cluster
Ya ha llegado la hora de trabajar en el cluster y vamos a empezar con AAD-Pod-Identity ya que es requisito para agic con el modelo de identidad manejada. Existen varias maneras de desplegar AAD-Pod-Identity en el cluster, pero para esta entrada vamos a optar por la que personalmente me parece más fácil, que es utilizando Helm directamente. Lo primero que vamos a necesitar es obtener el contexto para kubectl, esto lo vamos a conseguir simplemente utilizando az aks get-cred
entials
|
|
A partir de aquí, ya hemos sincronizado el contexto y basta con ejecutar:
|
|
Los valores que configuramos simplemente son para que nuestro aad-pod-identity se despliegue en un namespace concreto en vez de el valor por defecto. Si por el contrario los valores por defecto son suficientes, bastaría con ejecutar
helm install aad-pod-identity aad-pod-identity/aad-pod-identity
Podemos comprobar que esto ha funcionado ejecutando:
|
|
Lo que debería devolvernos algo parecido a esto:
|
|
Desplegar Application-Gateway-Ingress-Controller
Ahora sí que hemos llegado al punto final, ya lo tenemos todo listo para poder desplegar agic y que funcione correctamente. Para poder desplegarlo simplemente tenemos que ejecutar:
|
|
Los valores que estamos configurando son bastante explícitos en cuanto a su significado y que es lo que hay que asignar, pero por las dudas, dejo el enlace a la descripción de los valores.
Sí todo ha ido según se espera, deberíamos obtener una respuesta como esta al ejecutar
|
|
|
|
Probando Application-Gateway-Ingress-Controller
Llegados a este punto, ya tenemos desplegado agic en nuestro cluster y ya solo nos queda probarlo. Antes de empezar con la prueba, es importante conocer que agic soporta anotaciones con configuraciones específicas para el ingress en concreto. Para más información sobre ellas, os recomiendo echarle un ojo a la documentación ya que es un repositorio muy joven y constantemente recibe nuevas características.
Por último, vamos a desplegar una carga de trabajo simple como puede ser:
|
|
Una vez añadido al cluster, agic empezará automáticamente su preceso de actualización. Una vez termine (unos 10-20 segundos), podemos comprobar que el agw se ha configurado correctamente simplemente poniendo en el navegador la ip que hemos creado como ip pública del agw, la cual podemos obtener con el comando:
|
|
Si todo ha ido bien, deberíamos encontrarnos con una web como esta:
Con esto, hemos conseguido desplegar y validar nuestro agic :).
Conclusión
Aunque parece un poco tedioso, agic ofrece una mejora en la gestión del tráfico de nuestras aplicaciones. Es cierto que para poder usarlo es necesario que el agw sea como mínimo un Standard_v2 y que eso vale dinero, por lo que no es habitual montarlo para usar agic. Eso no quiere decir que si ya lo tenemos, utilizar agic sea una opción muy interesante.
Aquí solo he planteado el utilizarlo como ingress por evitar unos saltos de red, pero la realidad es que ofrece más cosas aparte como por ejemplo el decidir que ingress se sirven por la IP pública y cuales por la privada (aunque no por las dos a la vez), o por ejemplo la posibilidad de utilizar las métricas de agw como fuente para un HPA (Horizontal Pod Autoscaler, autoescalado horizontal).
Y con esto me despido, ha sido todo un placer poder compartir agic con todos vosotros, y estaré encantado de vovler para contaros más cosas si Eduard me lo permite :). Por lo pronto, muchas gracias a todos por leerme y a Eduard por dejarme estar aquí.
¡¡Hasta la próxima!!