Docker Swarm con Docker Machine, Alta-Disponibilidad

Publicado el 30/11/2017
Tiempo estimado de lectura: 8 minutos

Docker Swarm con Docker Machine, Alta Disponibilidad

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.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.

Docker Swarm Visualizer

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:

Configuración fichero hosts

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.yml dc-helloworld

Actualicemos nuestra aplicación Visualizer y veremos algo similar a la siguiente imagen:

Docker Swarm Visualizer

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.

DockerCloud Hello World

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.

Docker Swarm - Balanceador de Carga

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

Docker Swarm - Etiquetas a los Nodos

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.yml dc-helloworld

Docker Swarm - Estrategia de propagación

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.

Enlaces de referencia

Publicado el 30/11/2017