26 – Cluster de Docker

Te doy la bienvenida al episodio 26 de deployandome, el podcast de tecnología para sysadmins y devops. Soy Rodolfo Pilas y estoy grabando el 20 de febrero de 2018.
Cuando hablamos de un cluster en informática nos referimos a un conjunto de computadoras que se les ha asignado una tarea común;  de esta forma podemos llegar a percibir que se trata de una única computadora o una única unidad que desempeña la tarea.
Estos conjuntos de computadoras en cluster se suelen armar por dos motivos:
  • el primero es dar condiciones de disponibilidad, es decir, que ante la falla de algún componente del cluster, el servicio o la aplicación siga corriendo.
  • el segundo es para mejorar el rendimiento, puede ser
    • o para acortar el tiempo de los procesos,  porque se reparte una tarea grande entre varios miembros del cluster
    • o para atender una mayor demanda, porque se balancea entre los miembros
La necesidad de un cluster está fundada en estos dos conceptos de disponibilidad y rendimiento.
Si tu aplicación puede estar apagada algunos minutos sin que provoque mayor molestia, o tus procesos y aplicaciones funcionan adecuadamente en tiempos "normales", entonces eres de la mayoría que no necesitas un cluster.
Disponer de un cluster no es un tema de élite o de tamaño de empresa, es una tecnología enfocada a resolver estos problemas y no vale la pena el esfuerzo de tener un cluster si no tienes el problema a resolver.
En este episodio de deployándome vamos a abordar tema de correr nuestra aplicación docker en un cluster.

Me refiero tu  servicio o api, corriendo en contenedor docker, que está mantenido entre varias computadoras.
Para entender el tema, creo que nos conviene repasar desde lo simple hasta lo complejo.
En un computador o servidor se pone a correr el servicio Docker Engine que es una tecnología de software libre que permite armar y mantener contenedores corriendo.
Docker Engine junto con Docker Registry, el servicio de repositorio de imágenes de contenedores, permiten armar un flujo de trabajo para crear y poner en contenedores las aplicaciones.
Sabemos que con contenedores docker (me refiero a un Docker Engine y un Docker Registry) tenemos solucionadas algunas cosas y se nos facilitan otras, veámoslo:
  • El despliegue de nuestra aplicación. Ejecutamos `docker run` y la imágen y tendremos esa imagen copiada desde el Docker Registry corriendo como contenedor activo en el Docker Engine.
  • La actualización de esa aplicación y el mantenimiento de versiones, creando nuevas imágenes del contenedor con `docker build` y eventualmente subiéndolo a un Docker Registry central con `docker push`
  • La creación de ambientes de desarrollo, testing, producción y la posibilidad de que esos ambientes sean iguales.
  • El uso de herramientas de continuous integration y continuous deployment para automatizar el flujo de trabajo con nuestras aplicaciones.
Y todo esto solamente por usar Docker, es decir, esto es lo más simple de la infraestructura docker, te lo repito un Docker Engine y un Docker Registry.
Podemos entender esto como la solución base y general para la mayoría de las aplicaciones y los servicios que pueden correr en nuestros servidores.
¿pero qué pasa cuando necesito escalar por una mayor demanda de mi aplicación? Es decir cuando enfrentamos un problema de escalabilidad.
Docker Engine y Docker Registry por si solos no me solucionan el problema de escalabilidad, pero podemos hacer el método digamos simple: ponemos a correr muchos Docker Engine, cada uno en un servidor o computador distinto y cargamos una copia de nuestra contenedor con la aplicación en cada uno de esos Docker Engine.
Obviamente vamos a necesitar repartir a nuestros clientes entre todos esos docker engine, cosa que podemos hacer con un balanceador de tráfico, con un round-robin de DNS o con alguna otra metodología para que cada uno de los Docker Engine tenga la copia del contenedor con mi aplicación trabajando o brindando servicio.
Entonces, podemos solucionar el problema de escalabilidad de esta forma rudimentaria, pero efectiva.
Pero ya te estás dando cuenta que estaremos enfrentando nuevos problemas que requieren ajustes en esta infraestructura.
Por ejemplo, qué sucede si alguno de esos computadores o servidores que tiene un Docker Engine, que corre una copia de nuestro con nuestro contenedor y nuestra aplicación falla, es decir, se ve afectada su disponibilidad.   ¿qué debemos hacer para mantener la calidad de servicio?   ¿cómo el sistema se restablece ante un problema de este tipo?  Y aquí hablamos de la resiliencia.
Pero además, que pasa si nuestro grupo de computadores son, por ejemplo diez.  ¿corremos todas nuestros contenedores diez veces, uno en cada Docker Engine?  ¿no habrá alguna aplicación que perfectamente puede trabajar con dos copias?
Y ¿qué pasa si tenemos una aplicación que solo dos veces al año requiere las diez copias, pero el resto del tiempo perfectamente puede estar ejecutado una sola vez?  (como puede ser un sistema de inscripción para un colegio)
Y aquí me refiero a un tercer problema: la elasticidad.   Que podamos tener dos contenedores con nuestra aplicación y que aumente a diez cuando requiera satisfacer la demanda y vuelva a bajar a dos cuando entre en una etapa ociosa.
Entonces nuestra infraestructura de varios Docker Engine balanceados ya no funciona bien cuando agrego necesidades de disponitilidad, resiliencia y elasticidad.
Aquí es donde un cluster me soluciona estas cuatro características, las tres que acabamos de nombrar y la escalabilidad, todo en forma automática y nativa.

Existen varias posibilidades para tener un cluster para correr contenedores Docker.
Una de las más maduras es Kubernetes, una implementación de software libre para automatizar el despliegue, escala y administración de aplicaciones en contenedores.  Originalmente fue diseñado por Google y actualmente es mantenido por la Cloud Native Computing Foundation.
Otra implementación es Docker Swarm, que es una de las formas más simples de tener un cluster de docker.  Se trata de una funcionalidad del propio Docker Engine que permite armar un cluster.    Desde el punto de vista del administrador para usar docker swarm es el mismo comando docker con la opción service .
Otra opción es tener un cluster que corre Apache Mesos, una implementación de software libre que permite crear y administrar clusters.
También se puede tener un cluster de docker en servicios de nube como ser Amazon ECS (Elastic Container Services) o Azure Container Services.

En futuras ediciones de deployándome pienso abordar alguna de estas implementaciones, pero creo que por ahora te vas haciendo una idea de cuándo y cómo se justifica un cluster para correr tus aplicaciones en contenedores.
Soy Rodolfo Pilas, en twitter me puedes seguir por @pilasguru y te dejo un saludo. Confío que este podcast te haya aportado para mejorar y, como siempre, espero tus inquietudes y sugerencias comentando en deployando.me
Hasta la próxima edición.