Construir una arquitectura altamente escalable | Amazon Web Services

La idea de empezar esta entrada es que entiendas y aprendas como construir desde cero una plataforma o arquitectura y que sea altamente escalable con amazon web services, todo esto puede ayudarte junto al curso de Docker al que puedes acceder en esta plataforma.

datacenter amazon cristiancasis

A lo largo de mi tiempo como programador me han pedido montar y crear varias arquitecturas altamente escalables y con tolerancia a errores, tenemos la suerte que con Cloud Públicos como Amazon Web Services podemos ser capaces de hacerlo.

¿PARA QUÉ PAGAR 1000 O 2000 USD MENSUALMENTE POR UNA INFRAESTRUCTURA A LA QUE NO LLEGAN TANTOS USUARIOS?

HACIENDO UNA ARQUITECTURA ALTAMENTE ESCALABLE

En este artículo vamos a explicar como hacerlo paso a paso en AWS

Uni de los servicios que ofrece AWS para este tipo de despliegues es AWS ECS, EKS y Fargate, en concreto como se hace con Amazon Container Service (ECS).

No vamos a valorar utilizar otras opciones que no sean servicios propios de AWS, como sería la opción de hacer un despliegue de Openshift en AWS.

MANOS A LA OBRA!

AWS Amazon Elastic Container Service (ECS)

Este servicio es un cluster autoescalado, con alta disponibilidad y multi zona, permite gestionar despliegues de contenedores docker mediante la definición de tareas.

Para que lo entendamos, estas instancias contienen un agente ECS, es el que se comunica con la parte del cluster que ve el usuario en la VPC, que es el lugar donde se despliegan los contenedores, con la parte que no vemos que esta en la infraestructura de AWS.

EL USUARIO DE ESTE SERVICIO PAGA POR LAS INSTANCIAS QUE ESTEN FUNCIONANDO COMO PARTE DEL CLUSTER

Arquitectura de aplicaciones - Amazon Elastic Container Service

DESPLEGAR UN CONTENDOR EN AWS ECS

Lo primero que necesitamos es el contenedor, como ya hemos explicado en post o videos anteriores como se despliega un contendor.

A continuación tenemos que tener un repositorio en Amazon ECR, es el registry de Amazon Web Services, nos permite tener nuestras imagenes almacenadas en un registry privado.

Como ya sabemos las imágenes pueden ser almacenadas con diferentes versiones de dicha imagen, de forma que podemos hacer cambios y que se almacenen a través de diferentes TAG, por ejemplo endpoint/debian:beta

Aquí beta sería el tag de dicha imagen de docker.

Si hablamos de Fargate respecto ECS, la mayor ventaja entra a la hora de como se factura al cliente, mas aun si eres contractor o Freenlace 👇

Se paga por la cantidad de vCPU y memoria que consumen los contenedores desde que se hace el pull hasta que terminan.

Por ultimo AWS hace ya un tiempo implemento en su infraestructura interna AMAZON ELASTIC CONTAINER SERVICE PARA KUBERNETES, esta arquitectura trata de tener unos nodos (Master) que estan en la parte de AWS y otros workers que son los visibles para el usuario.

CREANDO UN CLUSTER ECS 💯

Amazon ECS nos permite crear clusters de contenedores para desplegar y gestionar tareas o servicios

  • Una tarea para Amazon es un contenedor desplegado en el cluster de ECS.
  • Un servicio para Amazon es la definición de la forma de desplegar una tarea.
ecs task cristiancasis

Poco después hay que configurar parametros como..

  • Nombre del cluster.
  • Instancia.
  • Tamaño del cluster.
  • Almacenamiento.
  • Configuración de red.

También es necesario establecer los grupos de seguridad (security group)

Siguiendo todos estos pasos tendríamos nuestro cluster creado

networking ecs cristiancasis

DEFINICIÓN DE TAREA

Aquí definimos todos los parametros que se pueden configurar:

  • CPU
  • Memoria
  • Variables de entorno que va a tener el contenedor al arrancar
  • Puertos
  • Volumenes persistentes

En este caso voy a registrar una Task definition mediante AWS, se puede definir mediante un JSON

{
  "containerDefinitions": [
    {
      "cpu": 512,
      "essential": true,
      "image": "{endpoint}.dkr.ecr.eu-west-1.amazonaws.com/nombre_del_contenedor:latest",
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "nombre_del_contenedor",
          "awslogs-region": "eu-west-2",
          "awslogs-stream-prefix": "nginx"
        }
      },
      "memory": 448,
      "memoryReservation": 256,
      "name": "nginx",
      "portMappings": [
        {
          "hostPort": 9999,
          "containerPort": 80,
          "protocol": "tcp"
        }
      ]
    }
  ],
  "family": "subiendo_mi_contenedor"
}

El nombre del fichero tiene que tener un formato JSON.

Ahora tenemos que definir el driver de los logs con Cloudwatch, es necesario crear:

  • Log group: Es necesario para mandar los logs a un lugar concreto dentro del apartado de Cloudwatch
$ aws ecs register-task-definition --cli-input-json file:///{path_to_file}/fichero_nginx.json

Poco después tendremos nuestra definición visible en el apartado Task.

ecs task cristiancasis

CREANDO UN SERVICIO

El servicio de ECS en AWS permite definir los parámetros de despliegue de ese contenedor que hemos creado anteriormente.

De la misma forma vamos a crearlo con un fichero JSON como el anterior.

{
  "serviceName": "nombre_del_contenedor",
  "cluster" : "nombre_del_contenedor",
  "taskDefinition": "nombre_del_contenedor",
  "deploymentConfiguration":{
    "maximumPercent": 200,
    "minimumHealthyPercent": 0
  },
  "desiredCount": 1
 }

Una idea muy interesante esta en desplegarlo en Cloudformation junto a un LoadBalancer.

La instrucción a ejecutar sería:

aws ecs create-service –cli-input-json file:///{path_to_file}/servicio.json*
autoscaling ecs cristiancasis

Una vez que tenemos desplegado la aplicación en la Pestaña Servicio veremos el contenedor y en el apartado Network Bindings tenemos el enlace que tenemos que usar para acceder desde el navegador al contenedor.

microservicios cristiancasis

¿LISTO PARA PRODUCCIÓN?

Podemos ver el proceso tan facil que es desplegar un contenedor y un cluster ECS en AWS y pensando que en pocos pasos es posible de automatizarse.

Para un entorno productivo todo lo anterior no es viable, debido a que para eso cada entorno debería de tener al menos dos desireCount que validen la disponibilidad del otro servicio, de forma que se cae podremos garantizar la disponibilidad del servicio.

Otra opción muy interesante es DistinctInstance, sirve para que todos los contenedores de un mismo servicio no vayan a un mismo nodo de forma que si el nodo se «cae» o «apaga» el servicio siga disponible sin ningún costo para el cliente.

En el caso de tener varios servicios, si se necesita exponer un servicio de forma pública, es necesario crear un Application Load Balancer, este balanceador de carga se encarga de distribuir la carga entre los diferentes contenedores de un servicio.

load balancer en aws cristiancasis

Es necesario crear un Listener que esta establecido en el balanceo del puerto deseado, al igual que una regla que esta conectada al Target group que es el «health check» del LoadBalancer.

"loadBalancers": [
    {
      "containerName": "nginx_default",
      "containerPort": 80,
      "targetGroupArn": "{target_group_arn}"
    }
  ]

Es recomendado por nosotros usar Terraform o Cloudformation o herramientas similares para crear LoadBalancer, listener, reglas y demás elementos.

CONCLUSIÓN FINAL

En este articulo, hemos hablado de como desplegar un servicio en AWS (Amazon Web Services) tiene un proceso bastante sencillo pero que es necesario conocer para no cometer errores, tenemos varias formas de realizarlo.

Hay ciertos puntos que son necesarios valorar:

  • La facilidad de desplegar pensando en la alta disponibilidad.
  • Integrar ciertos servicios necesarios como LoadBalancer,DNS,ECR…
  • Automatizar el despliegue de servicios a través de servicios como Cloudformation o terraform.
  • Mantener todos los cambios en nuestra infraestructura a través de gitlab e integración continua.
  • Usar una sintaxis entendible para el programador y acorde a Docker y Kubernetes a traves de ficheros en forma YAML.

Por último punto recomendamos usar kubernetes para todos los futuros proyectos ya que es una idea muy buena de tener una infraestructura escalable y 100% flexible de forma que podemos tener varios entornos para testar los cambios en cada entorno y no tener errores en producción.