Durante las pasadas semanas he estado trabajando en implementar una infraestructura escable para una aplicación de Laravel 9 utilizando Docker. El principal objetivo era poder desplegar la aplicación en múltiples servidores de manera ordenada y eficiente.
En la anterior versión contaba con dos instancias EC2 que se distribuían mediante un Elastic Balancer, pero eran servidores independientes y cualquier cambio en un servidor se debía hacer después manualmente en el otro, lo cual era un engorro y llevaba a errores fácilmente.
Con el conjunto de servicios Amazon Elastic Container Registry + Amazon Elastic Container Service + Fargate se puede conseguir una infraestructura serverless en la que Amazon se encarga de crear y destruir instancias según las necesidades de la aplicación. Para ello se establece un número mínimo de servidores, un máximo (opcional pero recomendable) y las condiciones para la creación de nuevas instancias (cierto uso de CPU o de memoria).
El primer paso para conseguir este objetivo es dockerizar la aplicación. Con Docker lo que se consigue es que la estructura del servidor sea explícita y escrita en un archivo legible por una máquina. Todos los pasos para configurar el servidor se pueden entender y replicar en cualquier instalación de Docker.
Para crear la imagen live del proyecto, utilicé la guía de learn2torials.com, que era la más completa porque ya incluía instrucciones para ejecutar composer y el scheduler, algo que la mayoría de otros tutoriales omitían.
Una vez con la imagen construida, se prueba que funciona localmente y posteriormente hay que preparar el proceso de deployment para dicha imagen. Yo utilizo siempre buddy.works. Tan solo hay que definir un pipeline con dos acciones: una que construye la imagen y la sube a Amazon ECR, y otra que comunica a Amazon ECS que debe hacer un nuevo deployment.
Antes de configuar Buddy, tenemos que crear un repositorio en ECR y crear un cluster en ECS. El repositorio es el lugar donde se alojarán las imágenes. ECS es el director de orquesta que se encarga de crear nuevos servidores utilizando las imágenes que hayamos seleccionado. Tal y como lo he entendido, es el equivalente a docker-compose, pero directamente relacionado con los servicios de Amazon.
En ECS crearemos un cluster, que es la manera de agrupar una serie de contenedores y servidores. A cada servidor ECS lo llama “Tarea”, y a cada regla lo llama “Servicio”. Un servicio es un conjunto de reglas para crear tareas. Un cluster puede tener varias reglas difentes. A la hora de crear tareas, Amazon nos da dos opciones: utilizar instancias normales de EC2, o utilizar Fargate para abstraer completamente la creación de instancias. Si queremos una infraestructura realmente escalable lo ideal es Fargate, porque no tenemos que preocuparnos de crear las instancias y de mantenerlas. Aunque tiene un coste ligeramente más elevado.
El último paso una vez tengamos el servicio y las tareas funcionando, es conectar todo esto a un Elastic Load Balancer, habilitar HTTPS y ya podremos acceder al cluster de servidores desde ese endpoint. Amazon se encargará de balancear la carga entre cada servidor y de ir creando o borrando servidores a medida que el uso de la aplicación así lo requiera.
Con esto se consigue un sistema altamente replicable y escalable, aunque se renuncia a facilidad para hacer debugging de errores, los despliegues son más lentos al ser escalonados, y en general la complejidad aumenta.
Sin comentarios todavía