Docker swam II

Arquitectura del cluster

Continuando con la entrada anterior vamos a profundizar en algunos de los aspectos que ya hemos visto.

Como vimos, en un cluster swam hay 2 tipos de nodos: manager y workers.

Para comenzar, en la entrada anterior vimos como crear un cluster de 3 nodos, con 1 manager y 2 workers. Para un entorno de pruebas está bien, pero si el manager nos fallase, aunque los servicios podrían seguir funcionando, perdiriamos la administración y tendriamos que recuperar el cluster creando uno nuevo.

Para tener una infraestructura con una mayor disponibilidad, deberíamos de crear un cluster con varios nodos como manager. De esta forma, teniendo multiples managers, podemos permitirnos la pérdida o fallo de alguno de ellos sin comprometer la infraestructura. Docker recomienda un número impar de nodos manager, de esta forma, en el evento de un particionado de red en 2 grupos, se mantiene un quorum entre los nodos. Los nodos de tipo manager utilizan Raft para elegir el lider del cluster.

Swarm mode cluster

  • Un cluster con N managers tolera el fallo de (N-1)/2 nodos
  • Un cluster con 3 managers tolera el fallo un nodo. Si perdemos 2 nodos no hay quorum entre los restantes.
  • Un cluster con 5 managers tolera el fallo de 2 nodos. Si perdemos 3 nodos no hay quorum entre los restantes.
Número de managers Mayoría Fault Tolerance
1 1 0
2 2 0
2 2 1
4 3 1
5 3 2
6 4 2
7 4 3
  • Docker recomienda un máximo de 7 managers

Además del número de nodos, tenemos que tener en cuenta la topología física del datacenter o datacenters en los que se ejecutan los nodos, de forma que tengamos en cuenta las zonas (datacenter, rack, chasis…) en los que se ejecutan los nodos para mantener el quorum en el caso de fallo o mantenimiento de alguna de esas zonas.

Número de managers Ejemplo de reparto en 3 zonas de disponibilidad
3 1-1-1
5 2-2-1
7 3-2-2
9 3-3-3

Por defecto, los servicios se pueden ejecutar en cualquiera de los nodos del cluster, ya sea worker o manager. Para entornos pequeños o de laboratorio, no es un gran problema si vigilamos el uso de los recursos en los manager, pero puede ser una buena idea evitar que los servicios se ejecuten en los  manager, limitando sus funciones a las propias de manager. Para ello, utilizamos la opción drain en los nodos manager

 

Creación del cluster

Para crear un cluster como el que vimos en la imagen anterior (3 managers y 7 nodos). Para completar la infraestructura, vamos a utilizar etiquetas (labels) para añadir información sobre la topología física a los nodos del cluster. Ejecutamos los siguientes comandos:

 

  • Creación del cluster

 

  • Añadimos los managers

  • Añadimos los workers

  • Nodos Managers-only

 

  • Estado del cluster

 

Etiquetar los nodos

Para añadir información de tipo metadata a los objetos Docker, tenemos la opción de utilizar etiquetas (labels) Siguiendo el ejemplo del cluster, vamos a etiquetar los nodos añadiendo información referente a:

  • Entorno: vamos a dedicar unos nodos del cluster a desarrollo (dev), otros a test, otros a preproduccion (pre) y otros a produccion (pro)
  • Ubicación: vamos a indicar con una etiqueta su ubicación física, por ejemplo el datacenter (dc1 y dc2)

A continuación vamos a ver como utilizar esta información para ubicar los servicios en los diferentes nodos.

Para añadir etiquetas a los nodos utilizamos el comando:

Por ejemplo, si en la arquitectura anterior queremos asignar las siguientes etiquetas

 

Ejecutamos:

 

Para poder ver las etiquetas que tiene un nodo, ejecutamos el comando “inspect” para cada nodo

 

Ubicación de los servicios

Ahora vamos a desplegar servicios en el cluster, gestionando la ubicación de los contenedores, entre otros parámetros, con las etiquetas que hemos creado. Para gestionar la ubicación de los contenedores tenemos varias opciones:

  • Especificar el número de réplicas de un servicio. Esta opción únicamente nos permite indicar el número de instancias pero no su ubicación

Como podemos ver, hemos indicado que se creen 5 réplicas del contenedor grafana y se ha creado en los nodos 5, 6, 7, 8 y 10. No hemos indicado ningún parámetro para establecer la ubicación de los contenedores y swarm ha decidido colocarlos en esos 5 nodos (de los 7 disponibles)

 

  • Servicio global (Global service). Esta opción permite indicar que existirá un contenedor del servicio en cada uno de los nodos del cluster.

Indicando el parámetro “–mode global” vemos que se ha creado un contenedor en cada uno de los 7 nodos de tipo worker

  • Utilizar los recursos de cpu y memoria. Esta opción permite indicar los recursos que tienen que tener disponibles los nodos para poder ubicar los contenedores del servicio

En este caso, estamos intentando crear 5 réplicas en nodos en los que se puedan reservar 3 CPUs y 9GB de RAM. Cómo sólo 3 de los 7 workers cumplen esos requerimientos (los nodos 8, 9 y 10), las tareas se pueden ejecutar en esos nodos pero no se pueden crear todas las réplicas, por lo que el servicio se queda en estado pendiente hasta que haya nodos disponibles para ejecutar las tareas.

 

  • Placement constraints. Esta opción permite indicar en que nodos específicos se ejecutaran los contenedores. Estos contenedores cumplen la condición de metadatos indicada. Esta opción puede generar que los despliegues fallen al no haber nodos disponibles que cumplan la condición.

En este caso hemos indicado que queremos que se utilicen unicamente los nodos cuya etiqueta dc sea igual a dc1 (–constraint node.labels.dc==dc1) Como los workers que cumplen este requerimiento son los nodos 5, 7 y 9, vemos que las 5 tareas se han creado en esos 3 nodos.

 

  • Placement preferences. Esta opción permite utilizar un algoritmo para repartir los contenedores entre los nodos disponibles. Actualmente, el único algoritmo disponible es “spread” que intenta repartir los contenedores en un mismo número entre los nodos disponibles. En este caso, a diferencia de la opción “placement constraint”, los servicios se despliegan aunque no se pueda cumplir con la preferencia.

Ahora estamos indicando que queremos 6 replicas, que se ejecuten sólo en los nodos etiquetados como pro y que reparta los nodos de forma equitativa según el valor de la etiqueta dc. Podemos comprobar que se han creado las 6 tareas, 1 en el nodo 8, 2 en el nodo 10 (3 en dc2) y 3 en el nodo 9 (3 en dc1)

 

Una respuesta a “Docker swam II”

  1. Buenas Roberto, muy buenos articulos! estoy más o menos implementando lo mismo que tu y es bueno saber que no estaba tan errado en el planteamiento de la arquitectura!!!

    En algun momento me gustaría consultarte algunos puntos como el almacenamiento compartido y que DDBB utilizas con grafana. Entre Dockers monte un NFS, pero no se si es la mejor opción y por otro lado utilizar los plugins no se si es mejor o peor.

    Nuevamente, muy buen post!

    Mariano

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.