Prácticas recomendadas para conectar los servicios de Amazon ECS en una VPC - Amazon Elastic Container Service

Prácticas recomendadas para conectar los servicios de Amazon ECS en una VPC

Al utilizar las tareas de Amazon ECS en una VPC, puede dividir las aplicaciones monolíticas en partes independientes que se pueden implementar y escalar de forma independiente en un entorno seguro. Esta arquitectura se conoce como arquitectura orientada a servicios (SOA) o microservicios. Sin embargo, puede resultar difícil garantizar que todas estas partes, tanto dentro como fuera de una VPC, puedan comunicarse entre sí. Existen diversos enfoques para facilitar la comunicación, cada uno con sus respectivas ventajas y desventajas.

Uso de Service Connect

Recomendamos Service Connect, que proporciona la configuración de Amazon ECS para la detección de servicios, la conectividad y la supervisión del tráfico. Con Service Connect, sus aplicaciones pueden utilizar nombres abreviados y puertos estándar para conectarse a los servicios del mismo clúster o a otros clústeres, incluso a través de VPC dentro de la misma región. Para obtener más información, consulte Amazon ECS Service Connect.

Cuando utiliza Service Connect, Amazon ECS administra todas las partes de la detección de servicios: crea los nombres que se pueden descubrir, administra dinámicamente las entradas de cada tarea a medida que se inician y se detienen las tareas y ejecuta un agente en cada tarea que está configurado para descubrir los nombres. La aplicación puede buscar los nombres mediante la funcionalidad estándar para los nombres de DNS y establecer conexiones. Si su aplicación ya lo hace, no tendrá que modificarla para usar Service Connect.

Diagrama que muestra la arquitectura de una red que utiliza Service Connect.
Los cambios solo se realizan durante las implementaciones.

Usted proporciona la configuración completa dentro de cada definición de servicio y tarea. Amazon ECS administra los cambios en esta configuración en cada implementación de servicio para garantizar que todas las tareas de una implementación se comporten de la misma manera. Por ejemplo, un problema común con el DNS en la detección de servicios es el control de una migración. Si cambia un nombre de DNS para que apunte a las nuevas direcciones IP de reemplazo, es posible que pase el tiempo máximo de TTL antes de que todos los clientes comiencen a usar el nuevo servicio. Con Service Connect, la implementación del cliente actualiza la configuración sustituyendo las tareas del cliente. Puede configurar el disyuntor de implementación y otras configuraciones de implementación para que afecten a los cambios de Service Connect de la misma manera que cualquier otra implementación.

Uso de la detección de servicios

Otro enfoque para la comunicación de servicio a servicio es la comunicación directa mediante la detección de servicios. En este enfoque, puede utilizar la integración de detección de servicios AWS Cloud Map con Amazon ECS. Mediante la detección de servicios, Amazon ECS sincroniza la lista de tareas iniciadas en AWS Cloud Map, que mantiene un nombre de host DNS que se resuelve en las direcciones IP internas de una o más tareas de ese servicio en particular. Otros servicios de Amazon VPC pueden usar este nombre de host DNS para enviar tráfico directamente a otro contenedor mediante su dirección IP interna. Para obtener más información, consulte Detección de servicios.

Diagrama que muestra la arquitectura de una red que utiliza una detección de servicios.

En el diagrama anterior, hay tres servicios. El service-a-local tiene un contenedor y se comunica con el service-b-local, que tiene dos contenedores. El service-b-local también debe comunicarse con el service-c-local, que tiene un contenedor. Cada contenedor de estos tres servicios puede usar los nombres DNS internos desde AWS Cloud Map para buscar las direcciones IP internas de un contenedor del servicio descendente con el que necesita comunicarse.

Este enfoque de comunicación de servicio a servicio proporciona una baja latencia. A primera vista, este enfoque es sencillo porque no hay componentes adicionales entre los contenedores. El tráfico viaja directamente de un contenedor al otro.

Este enfoque es adecuado cuando se utiliza el modo de red awsvpc, en el que cada tarea tiene su propia dirección IP única. La mayoría de los programas solo admiten el uso de registros A de DNS, que se resuelven directamente en las direcciones IP. Cuando se utiliza el modo de red awsvpc, la dirección IP de cada tarea es un registro A. Sin embargo, si utiliza el modo de red bridge, es posible que varios contenedores compartan la misma dirección IP. Además, las asignaciones dinámicas de puertos hacen que a los contenedores se les asignen números de puerto de forma aleatoria en esa única dirección IP. En este punto, un registro A ya no es suficiente para la detección de servicios. También debe usar un registro SRV. Este tipo de registro puede hacer un seguimiento de las direcciones IP y los números de puerto, pero requiere que configure las aplicaciones de forma adecuada. Es posible que algunas aplicaciones prediseñadas que utilice no admitan registros SRV.

Otra ventaja del modo de red awsvpc es que tiene un grupo de seguridad único para cada servicio. Puede configurar este grupo de seguridad para permitir las conexiones entrantes únicamente desde los servicios ascendentes específicos que necesitan comunicarse con ese servicio.

La principal desventaja de la comunicación directa entre servicios mediante la detección de servicios es que se debe implementar una lógica adicional para llevar a cabo reintentos y solucionar los errores de conexión. Los registros de DNS tienen un período de vida (TTL) que controla el periodo durante el que se almacenan en caché. El registro DNS tarda algún tiempo en actualizarse y la caché en caducar para que las aplicaciones puedan recoger la última versión del registro DNS. Por lo tanto, su aplicación podría terminar resolviendo el registro DNS para que apunte a otro contenedor que ya no está allí. Su aplicación debe gestionar los reintentos y tener una lógica para ignorar los backends defectuosos.

Uso de un equilibrador de carga interno

Otro enfoque para la comunicación entre servicios es utilizar un equilibrador de carga interno. El equilibrador de carga interno reside completamente dentro de la VPC y solo los servicios dentro de la VPC pueden acceder a él.

Diagrama que muestra la arquitectura de una red que utiliza un equilibrador de carga interno.

El equilibrador de carga mantiene una alta disponibilidad mediante la implementación de recursos redundantes en cada subred. Cuando un contenedor de serviceA necesita comunicarse con un contenedor de serviceB, abre una conexión con el equilibrador de carga. Luego, el equilibrador de carga abre una conexión a un contenedor del service B. El equilibrador de carga actúa como un punto centralizado para gestionar todas las conexiones entre los servicios.

Si un contenedor del serviceB se detiene, el equilibrador de carga puede retirar ese contenedor del grupo. El equilibrador de carga también realiza comprobaciones de estado de cada uno de los objetivos intermedios de su grupo y puede eliminar automáticamente los objetivos defectuosos del grupo hasta que vuelvan a estar en buen estado. Las aplicaciones ya no necesitan conocer la cantidad de contenedores descendentes. Solo abren sus conexiones a través del equilibrador de carga.

Este enfoque es ventajoso para todos los modos de red. El equilibrador de carga puede realizar un seguimiento de las direcciones IP cuando se usa el modo de red de awsvpc, así como de las combinaciones más avanzadas de direcciones IP y puertos cuando se usa el modo de red de bridge. Distribuye el tráfico de manera uniforme entre todas las combinaciones de direcciones IP y puertos, incluso si varios contenedores están alojados en la misma instancia de Amazon EC2, pero en puertos diferentes.

La única desventaja de este enfoque es el costo. Para garantizar una alta disponibilidad, el equilibrador de carga debe tener recursos en cada zona de disponibilidad. Esto implica un costo adicional debido a la sobrecarga de pagar por el equilibrador de carga y por la cantidad de tráfico que maneja.

Sin embargo, puede reducir los costos generales si varios servicios comparten un equilibrador de carga. Esto es particularmente útil para los servicios de REST que utilizan un equilibrador de carga de aplicación. Puede crear reglas de enrutamiento basadas en rutas que dirijan el tráfico a diferentes servicios. Por ejemplo, /api/user/* podría dirigir el tráfico a un contenedor que forma parte del servicio de user, mientras que /api/order/* podría dirigir el tráfico al servicio de order asociado. Con este enfoque, solo paga por un equilibrador de carga de aplicación y dispone de una URL coherente para su API. Sin embargo, puede dividir el tráfico en varios microservicios del backend.