Introducción
Docker Swarm nos permite brindar servicios de Alta-Disponibilidad para nuestros clientes. El presente artículo mostrará algunas recomendaciones y ejemplos necesarios para lograr brindar servicios con esta característica.
Requisitos
Tener instalado Docker y Docker Machine.
Tener configurado un clúster utilizando Docker Swarm con Docker Machine con un total de 6 nodos (3 manager y 3 worker). Este requisito puede lograrlo utilizando los scripts publicados en el artículo Docker Swarm con Docker Machine, Scripts en este mismo sitio.
Configuraciones del entorno
$ docker version
Client:
Version: 17.11.0-ce
API version: 1.34
Go version: go1.8.3
Git commit: 1caf76c
Built: Mon Nov 20 18:37:39 2017
OS/Arch: linux/amd64
Server:
Version: 17.11.0-ce
API version: 1.34 (minimum version 1.12)
Go version: go1.8.3
Git commit: 1caf76c
Built: Mon Nov 20 18:36:09 2017
OS/Arch: linux/amd64
Experimental: false
Código fuente
El código fuente del artículo se encuentra público en GitHub.
Servicios con Alta-Disponibilidad
Cuando usted tiene servicios publicados en entornos de producción su prioridad debe ser brindar estos servicios de forma continua y sin interrupciones. Para logra este objetivo la infraestructura de sus sistemas debe estar preparada para recuperarse de fallos tanto físicos como de componentes del software sin que el usuario se vea afectado.
La Alta-Disponibilidad (HA) por su siglas en inglés, es la cualidad de un sistema o componente que asegura un alto nivel de rendimiento operativo por un período de tiempo determinado.
Preparar nuestra máquina
Comandos desde el Cliente Docker hacia el Swarm local
Para los próximos pasos necesitamos que nuestro Cliente Docker realice las peticiones al clúster creado con Docker Machine. Para logralo debemos establecer que las peticiones se realicen siempre desde nuestro Cliente Docker hacia el Servidor Docker que se encuentra funcionando en el node1
del clúster. Utilicemos el siguiente comando:
$ eval $(docker-machine env node1)
Comprobemos que se ha realizado el cambio correctamente cuando al listar los máquinas creadas con Docker Machine vemos que el node1
se encuentra activo.
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
node1 * virtualbox Running tcp://192.168.99.100:2376 v17.11.0-ce
node2 - virtualbox Running tcp://192.168.99.101:2376 v17.11.0-ce
node3 - virtualbox Running tcp://192.168.99.102:2376 v17.11.0-ce
node4 - virtualbox Running tcp://192.168.99.103:2376 v17.11.0-ce
node5 - virtualbox Running tcp://192.168.99.104:2376 v17.11.0-ce
node6 - virtualbox Running tcp://192.168.99.105:2376 v17.11.0-ce
Si desea ampliar la información referente a la Arquitectura de Docker puede consultar este enlace.
Docker Swarm desde el navegador
Utilizaremos el proyecto docker swarm visualizer para ver nuestro Swarm desde el navegador. Para lograrlo utilizaremos el fichero visualizer.yml
ubicado en la carpeta stacks
del repositorio. El comando para publicar este servicio quedaría de la siguiente forma:
$ docker stack deploy --compose-file=stacks/visualizer/visualizer.yml visualizer
Revisemos si el servicio se desplegó correctamente:
$ docker stack services visualizer
ID NAME MODE REPLICAS IMAGE PORTS
qxm4w28xr4la visualizer_web replicated 2/2 dockersamples/visualizer:latest *:8080->8080/tcp
Luego accedemos a nuestro navegador utilizando el IP del node1
(192.168.99.100) y el puerto 8080
.
Configurar DNS local
Pasemos a agrupar las diferentes direcciones IP de nuestros nodos bajo una sola dirección web. La dirección web a utilizar será swarm.local
y debemos adicionarla junto a los IPs de las máquinas de Docker en el fichero /etc/hosts
.
Para editar el fichero pueden utilizar el comando:
$ sudo vim /etc/hosts
Adicionar los siguientes datos al fichero:
Una vez salvado el fichero podemos acceder a los sistemas desplegados en el Swarm a través del enlace http://swarm.local/
, como por ejemplo Visualizar Swarm.
Nuestra apliación o servicio
Utilizaremos como aplicación el Hello-World de DockerCloud el cual será desplegado a través del puerto 80.
Utilizaremos esta aplicación para identificar algunos problemas que pudieran dar lugar a interrupciones del servicio para nuestros clientes. Veremos además la sugerencia de solución que podemos implementar haciendo uso de las bondades de Docker Swarm.
Las posibles situaciones de desastre a resolver serán:
- Ruptura del software.
- Sobrecarga de pedidos a un servicio.
- Problemas de infraestructura o hardware.
Ruptura del software
El producto publicado no es perfecto y por lo tanto, pudieran ocurrir interrupciones inesperadas a causa de situaciones como: sobrecarga de usuarios accediendo al sitio al mismo tiempo, la identificación de un bug o caso crítico, la demanda de mayores valores de RAM o CPU, entre otros.
La solución antes estos posibles problemas es crear múltiples instancias de nuestra aplicación para poder seguir brindando el servicios aunque una o varias de ellas se encuentren no disponibles.
Docker Swarm nos permitirá crear múltiples instancias del mismo servicio de forma fácil. La siguiente configuración permitirá desplegar nuestro sistema y podrán identificar fácilmente cómo se especifican las dos réplicas del servicio.
El fichero con la configuración puede ser encontrado en la carpeta stacks
con el nombre dockercloud-hello-world.yml
.
version: '3.4'
services:
web:
image: dockercloud/hello-world
ports:
- target: 80
published: 80
protocol: tcp
mode: ingress
deploy:
mode: replicated
replicas: 2
Iniciemos el servicio con el siguiente comando:
$ docker stack deploy --compose-file=stacks/dockercloud-hello-world/dockercloud-hello-world.yml dc-helloworld
Actualicemos nuestra aplicación Visualizer y veremos algo similar a la siguiente imagen:
Si accedemos a este enlace podremos ver la aplicación Hello World. Si actualizan un par de veces el navegador podrán ver cómo cambia el nombre del contenedor lo que indica que ambas instancias están disponibles.
Sobrecarga de pedidos a un servicio
Cuando tenemos múltiples instancias de un mismo servicio necesitamos balancear la carga que llega a ellas para que ninguna se vea saturada en peticiones. Para suerte nuestra, Docker Swarm resuelve este problema por nosotros pues cuenta con sistema para balancear la carga dentro de su propio núcleo.
Como este balance de carga se encuentra en el núcleo de Docker tenemos la garantía que cada nodo cuenta con uno de estos sistemas. Por lo tanto, si alguno de los nodos deja de funcionar, el Swarm podrá seguir distribuyendo las peticiones a las instancias con menos demanda.
Para consultar más información al respecto pueden consultar este enlace.
Problemas de infraestructura o hardware
Las máquinas virtuales de nuestra infraestructura están ubicadas físicamente en una zona de disponibilidad. Si todos nuestros nodos se encontrasen en la misma zona y ocurre un problema de redes o hardware quedarían todos los servicios del Swarm interrumpidos, por tal motivo, este es otro elemento a tener en cuenta.
Hasta el momento tenemos claro que nuestros nodos deben ser creados en diferentes zonas de disponibilidad pero la próxima pregunta sería:
¿Cómo configuramos nuestro Swarm para que publique los servicios estableciendo un balance entre las diferentes zonas físicas?
La respuesta es agregando Etiquetas a los nodos y Restricciones en el despliegue de los servicios. Veamos un ejemplo en los siguientes pasos.
Agregar etiquetas a los nodos
En el ejemplo se utilizará solamente los 3 nodos Worker y serán distribuidos en 2 zonas físicas: us-east-1 y us-west-1. Los comandos para adicionar las etiquetas a los nodos son:
$ docker node update --label-add zone=us-east-1 node4
$ docker node update --label-add zone=us-east-1 node5
$ docker node update --label-add zone=us-west-1 node6
Agregar restricciones al servicio
Pasemos a configurar el fichero dockercloud-hello-world.yml
donde serán agregados los siguientes elementos:
- Utilizar solamente los nodos worker.
- Estrategia de propagación utilizando las etiquetas
node.labels.zone
. - Crear 6 réplicas del servicio.
version: '3.4'
services:
web:
image: dockercloud/hello-world
ports:
- target: 80
published: 80
protocol: tcp
mode: ingress
deploy:
mode: replicated
replicas: 6
placement:
preferences:
- spread: node.labels.zone
constraints:
- node.role == worker
Actualizar el servicio publicado
Pasemos entonces a actualizar nuestro servicio con las nuevas configuraciones. Para lograrlo debemos utilizar el mismo comando empleado durante la creación del mismo.
$ docker stack deploy --compose-file=stacks/dockercloud-hello-world/dockercloud-hello-world.yml dc-helloworld
Conclusiones
Brindar servicios con Alta Disponibilidad no es tarea fácil, pero tampoco imposible. Con el presente artículo usted tiene a la mano algunas sugerencias y consejos para establecer servicios de Alta Diponibilidad utilizando Docker Swarm.