Mecanismos para exponer APIs alojadas en ECS

Mecanismos para exponer APIs alojadas en ECS

Introducción

Luego de familiarizarnos con el proceso de despliegue en ECS empezamos a explorar las opciones que teníamos para exponer nuestros microservicios al mundo exterior, lo cual resultó ser más interesante de lo que pensamos inicialmente, por eso decidimos dejar la experiencia en este Blog ya que por el camino nos encontramos con un par de conceptos y técnicas nuevas que valen la pena documentar.

1. Empezando por lo mas tosco: "Asignar direcciones ip públicas a cada task"

Así como dice el título, al empezar con ECS nos dimos cuenta que podemos asignar una dirección IP pública directamente al container, esto es, siempre y cuando hayamos elegido el modo de red recomendado "awsvpc".

De esta forma cada task desplegado expondrá sus puertos sobre esta IP pública de acuerdo a los filtros de su Security Group, lo cual nos parece extremadamente versátil ya que nos evita mucho trabajo de cañería en cuentas de prueba, pero también nos parece extremadamente peligroso ya que el task estará atendiendo conexiones de cualquiera que conozca su IP sin restricciones, siendo esta última la frase clave de este esquema "sin restricciones", ya que con pocas restricciones se puede acelerar notablemente los tiempos de desarrollo pero dejando a cambio grandes agujeros de seguridad.

Otra desventaja obvia de este esquema es el hecho de que las IPs públicas pueden cambiar así que de ninguna manera debería ser considerado como un esquema final.


2. A lo más tradicional: "Elastic Load Balancers"

Esta es la forma más común de exponer servicios en AWS, desde sus inicios los Loadbalancers siempre formaron parte del stack de cualquier arquitectura mínimamente resiliente, por lo cual se fueron adaptando con el tiempo a brindar sus servicios a todas las tecnologías de AWS como lo es el ECS.

Si elegimos este esquema AWS creará una instancia ya sea de NLB o ALB a la cual se registrarán automáticamente los tasks desplegados y el LB se encargará de controlar su estado, solicitar despliegues a ECS en caso de healthchecks fallidos y balancear la carga entre las N tasks del servicio.Finalmente este LB podrá ser expuesto a internet de dos formas dependiendo del "Scheme" seleccionado a la hora de crearlo, que puede ser:

  1. Internet-facing: Aquí el loadbalancer se expone directamente a internet mediante una IP pública.
  2. Internal: El loadbalancer se despliega con una IP privada, aquí queda a cargo del equipo de red elegir la forma final de exponerlo a internet.

3. Organizando el caos: "Cloud Map con tasks públicas"

Inicialmente esta sección debía quedar como anexo a la opción 1 donde cada task tiene su propia dirección IP, pero pensandolo bien, este esquema permite darle más versatilidad al esquema original lo que lo convierte en un esquema extremadamente sencillo y escalable para tasks de bajo riesgo, por eso decidimos separarlo en su sección aparte.

Dijimos que una desventaja del esquema 1 era el hecho de que las IP públicas no son estables, esto se soluciona con Cloud Map, el cual hace de intermediario entre ECS y Route53 para reflejar cambios en las IPs del backend en los registros DNS del servicio.

Por ejemplo, supongamos que tenemos el dominio granja.animales.com y 2 tasks: conejo y gallina, cada uno con 4 réplicas, totalizando 8. Para este caso solo con direcciones IP públicas a cada task se vuelve imposible tener estabilidad ya que en cada despliegue o caída inesperada de un task también cambiarán las IPs.

Aquí es donde viene al rescate el DNS disfrazado de Cloud Map, en el cual creamos el namespace "granja.animales.com" y luego en ECS elegimos este namespace como destino para nuestros servicios conejo y gallina, una vez desplegados, Cloud Map creará automáticamente estas entradas DNS:

  1. conejo.granja.animales.com:
    1. A 1.2.3.4
    2. A 1.3.3.5
    3. A 1.3.5.2
    4. A 2.4.2.2
  2. gallina.granja.animales.com:
    1. A 4.3.2.2
    2. A 43.22.2.2
    3. A 4.5.2.2
    4. A 4.55.4.22

Donde cada A corresponde a una IP pública de un task, esto a su vez se irá actualizando automáticamente a medida que los tasks vayan rotando a través de su ciclo de vida, por lo cual logramos dar un orden al caos.

4. Lo ideal: "API Gateway"

Finalmente llegamos a la opción recomendada para exponer APIs en AWS, una API expuesta a través del API gateway cuenta con las siguientes ventajas:

  1. Monitoreo integrado
  2. Performance garantizado
  3. Flexibilidad para el despliegue de varias versiones de APIs
  4. Integración con IAM, Cognito, OIDC y OAuth2

Al ser un servicio administrado por AWS, el API Gateway necesita ciertos componentes para poder conectarse al backend ECS dependiendo del tipo de API creado, por ejemplo un caso típico es el siguiente:

  1. Se tiene el servicio en ECS configurado con el siguiente DNS de service discovery: api1.system.internal
  2. Este servicio se encuentra en una red privada sin acceso a internet.
  3. Se tiene un VPC Link creado en la red privada.
  4. El API Gateway tiene una ruta api1.system.com apuntando al recurso api1.system.internal a través del Private Link.

En este caso el componente extra es el VPC Link, que expone los recursos de la red privada al servicio de API Gateway.El VPC Link también permite al API Gateway conectarse a otros endpoints como por ejemplo Loadbalancers.

Como siempre los invitamos a suscribirse y dejar sus comentarios. Hasta la próxima.

Read more