overlay networks Innovación

Uso de redes Overlay en Docker: Guía de configuración

06/05/20 13 min. de lectura

Docker y la contenerización han revolucionado la manera de desplegar aplicaciones y servicios y ya es habitual en DevOps y SysOps. Sin embargo, las funciones de redes que ofrece docker siguen siendo las grandes desconocidas. 

En este artículo aprenderás qué funciones de networking te ofrece docker y cómo aprovechar docker swarm y las redes overlay para mejorar y simplificar tus despliegues en entornos distribuidos. 

Contenidos

¿Qué es una red overlay?

Una “red overlay” es una red virtual que se ejecuta a su vez sobre otra red. Los dispositivos de dicha red no detectan que están funcionando en una red overlay. Las VPNs tradicionales, por ejemplo, son redes overlay que se ejecutan sobre Internet.

El término “overlay” sólo ha llegado a ser ampliamente utilizado (en lugar de VPN) después de que se hayan desarrollado otras tecnologías, aparte de PPTP o L2TP, diseñadas específicamente para ejecutar redes virtuales en entornos Cloud. Para estos casos se han diseñado protocolos como VXLAN o GENEVE que responden a necesidades concretas.

El tema recogido en este documento se trata con más profundidad en https://docs.docker.com/network/. Este documento resume la información clave disponible en esa página web.

¿Que es una red superpuesta?

Controladores de red en Docker

Docker ofrece diferentes controladores de red:

  • Bridge 🏛 : el controlador de red predeterminado. Las redes bridge normalmente se utilizan cuando las aplicaciones se ejecutan en contenedores independientes que necesitan comunicarse en el mismo host.
  • Host ⚙️ : elimina el aislamiento de red entre el contenedor y el host de Docker y utiliza directamente el sistema red del host.
  • Overlay ⛓ : conecta varios demonios de Docker entre sí para crear una red virtual plana entre hosts donde se puede establecer la comunicación entre un servicio swarm y un contenedor independiente, o entre dos contenedores independientes de diferentes demonios de Docker. Esta estrategia elimina la necesidad de realizar el enrutamiento entre estos contenedores a nivel de sistema operativo.
  • Macvlan 🔩 : las redes Macvlan permiten asignar una dirección MAC a un contenedor, haciéndolo parecer un dispositivo físico en la red.
  • None ❌ : deshabilita la configuración de red del contenedor.

Casos de uso de controladores

Las redes bridge definidas por el usuario ofrecen mejores resultados en los casos en los que se necesitan varios contenedores para comunicarse en el mismo host de Docker.

Las redes host son la mejor opción cuando la pila de red del contenedor no debe ser aislada de la del servidor Docker, pero se quiere seguir manteniendo otras funciones de aislamiento del contenedor.

Las redes overlay son ideales cuando se necesita que los contenedores se ejecuten en diferentes hosts de Docker para comunicarse, o cuando varias aplicaciones que trabajen juntas utilizando servicios swarm.

Las redes Macvlan son la mejor opción cuando se está migrando desde una configuración VM o cuando se necesita que los contenedores parezcan hosts físicos en la red, cada uno con una dirección MAC única.

En muchas ocasiones las implementaciones que se ejecutan en varios demonios de Docker no incluyen el diseño de sus redes. Sin embargo, pueden verse muy beneficiadas al usar overlays por varias razones:

  • Todo el tráfico en el overlay entre diferentes hosts puede cifrarse fácilmente.
  • Todos los contenedores en un overlay comparten el mismo espacio de nombres. Esto permite evitar soluciones extrañas, tales como el empleo de extrahosts o políticas de nombres internos y externos.
  • No es necesario preocuparse por la administración del enrutamiento en el nivel de overlay.

Configuración de redes superpuestas de Docker

Requisitos previos 👍

  • Reglas de firewall para demonios de Docker que utilizan redes overlay:
    • Es necesario que los siguientes puertos estén abiertos al tráfico hacia y desde cada host de Docker que participe en una red superpuesta:
      • El puerto TCP 2377 para las comunicaciones de administración del clúster.
      • El puerto TCP y UDP 7946 para la comunicación entre nodos.
      • El puerto UDP 4789 para el tráfico de la red superpuesta.
    • En algunos sistemas Linux es posible que sea necesario abrir los puertos en el firewall del host. Esto puede hacerse con firewalld en sistemas como RedHat o con iptables. A continuación aparece un ejemplo de cómo implementarlo en RedHat:
                                                      $ sudo firewall-cmd --add-port=2377/tcp --permanent 
                                                      $ sudo firewall-cmd --add-port=7946/tcp --permanent
                                                      $ sudo firewall-cmd --add-port=7946/udp --permanent
                                                      $ sudo firewall-cmd --add-port=4789/udp –permanent
                                                      $ sudo firewall-cmd --reload
  • Antes de poder crear una red overlay, es necesario inicializar el demonio Docker como un administrador swarm utilizando docker swarm init o combinándolo con un swarm existente utilizando docker swarm join. Cualquiera de estos métodos crea una red overlay de entrada por defecto. Es necesario hacer esto incluso aunque no esté previsto utilizar servicios swarm. Después pueden crearse otras redes overlay definidas por el usuario.

Configuración 🤝

Vamos a configurar una red que conecta tres contenedores en tres hosts de Docker diferentes. Aquí el objetivo no es crear swarms sino mejorar la red de contenedores independientes que se ejecutan en diferentes hosts.

  1. Crea un swarm.

En host1:

                                                  $ docker swarm init

El token que devuelve el comando se necesitará más adelante. Host1 se convierte en el manager del swarm.

En host2 y host3:

                                                  $ docker swarm join --token <TOKEN> <IP-ADDRESS-OF-MANAGER>:2377
  1. Comprueba en host1 (porque es el manager) que el swarm está listo:
                                                 $ docker node ls
                                                 ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
                                                 d68ace5iraw6whp7llvgjpu48 *   ip-172-31-34-146    Ready               Active              Leader
                                                 nvp5rwavvb8lhdggo8fcf7plg     ip-172-31-35-151    Ready               Active
                                                 ouvx2l7qfcxisoyms8mtkgahw     ip-172-31-36-89     Ready               Active

  1. Verifica las redes por defecto en host1 (porque es el manager):
                                                 $ docker network ls
                                                 NETWORK ID          NAME                DRIVER              SCOPE
                                                 495c570066be        bridge              bridge              local
                                                 961c6cae9945        docker_gwbridge     bridge              local
                                                 ff35ceda3643        host                host                local
                                                 trtnl4tqnc3n        ingress             overlay             swarm
                                                 c8357deec9cb        none                null                local
  1. Si no se necesita cifrado de datos: en host1 (porque es el manager) crear la red overlay (por ejemplo, my_net). El indicador “attachable” es necesario para permitir que los contenedores standalone se conecten a my_net:
                                                 $ docker network create -d overlay –-attachable my_net
  1. Por defecto, todo el tráfico de administración del swarm está cifrado con AES en modo GCM. Para cifrar también el tráfico de datos de la aplicación hay que añadir “–opt encrypted” al comando anterior. De este modo se crearán túneles IPSEC entre los hosts de Docker. El cifrado también empleará AES-GCM con una rotación de claves de 12 horas. El cifrado de redes overlay no está contemplado en los hosts Windows.
                                                $ docker network create –-opt encrypted -d overlay –-attachable my_net
  1. Después de realizar todos estos pasos habrás logrado establecer una red overlay con el nombre my_net que incluye tres hosts de Docker diferentes.
  2. Haz la prueba. Crea tres contenedores de prueba para confirmar que se pueden alcanzar entre si y que los nombres se resuelven correctamente dentro de la red overlay.
  3. En host1:
                                               $ docker run -it --name alpine1 --network my-net alpine
                                               / #
  1. En host2:
                                               $ docker run -it --name alpine2 --network my-net alpine
                                               / #
  1. En host3:
                                              $ docker run -it --name alpine3 --network my-net alpine
                                              / #
  1. Ahora comprueba la conectividad entre ellos. Deberías recibir respuestas a todos estos comandos, demostrando que los contenedores se alcanzan entre sí y resuelven los nombres correctamente:

a) En host1:

                                              / # ping alpine2
                                              PING alpine2 (10.0.0.5): 56 data bytes
                                              64 bytes from 10.0.0.5: seq=0 ttl=64 time=0.500 ms
                                              / # ping alpine3
                                              PING alpine3 (10.0.0.6): 56 data bytes
                                              64 bytes from 10.0.0.6: seq=0 ttl=64 time=0.500 ms

b) En host2:

                                               / # ping alpine1
                                               PING alpine2 (10.0.0.4): 56 data bytes
                                               64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.500 ms
                                               / # ping alpine3
                                               PING alpine3 (10.0.0.6): 56 data bytes
                                               64 bytes from 10.0.0.6: seq=0 ttl=64 time=0.500 ms

c) En host3:

                                              / # ping alpine1
                                              PING alpine2 (10.0.0.4): 56 data bytes
                                              64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.500 ms
                                              / # ping alpine2
                                              PING alpine3 (10.0.0.5): 56 data bytes
                                              64 bytes from 10.0.0.5: seq=0 ttl=64 time=0.500 ms
  1. Ahora puedes salir de los contenedores alpine y eliminarlos.
Configuración de una red superpuesta

Diseñar la arquitectura de los swarm managers 👨🏽‍🔧

Este es un resumen de la arquitectura de swarm manager. Encontrarás más información en: https://docs.docker.com/engine/swarm/admin_guide/

Managers y workers

Los nodos manager de swarm se ocupan de administrar el swarm y almacenar su estado. Esto significa que si se pierden los manager, los servicios swarm seguirán en funcionamiento, aunque no será posible realizar cambios o trabajos de administración. Para recuperar la gestión será necesario crear un nuevo grupo. 

Por ello, en entornos de producción deberás plantear la configuración de varios  manager que proporcionen alta disponibilidad a la gestión del swarm. 

Arquitectura de los administradores de enjambres

Los nodos manager mantienen la consistencia del estado del swarm utilizando una implementación del protocolo de consenso Raft. Como hemos visto en el ejemplo anterior, pueden ejecutar contenedores, aunque también puedes impedirlo para aliviar su carga. Tienes más detalles en la documentación. También pueden ser degradados a nodos de trabajo con docker node demote. 

Los nodos worker sólo ejecutan contenedores, pero pueden ser promovidos a administradores en caso de que sea necesario. Por ejemplo, si un manager se deshabilita para realizar labores de mantenimiento. Puedes hacerlo con docker node promote. 

Alta disponibilidad de managers

El protocolo Raft mantendrá el servicio vivo mientras exista una súper mayoría de nodos manager vivos. Por lo tanto, se recomienda utilizar siempre un número impar de nodos administradores. Observa, como ejemplo, la siguiente tabla (cifras = número de nodos manager). 

Tamaño del swarm Mayoría Tolerancia a fallos
1 1 0
2 2 0
3 2 1
4 3 1
5 3 2

No hay límite en el número de nodos manager. No obstante, el hecho de que existan muchos nodos implicará un mayor retardo para confirmar los cambios de estado, especialmente cuando hay cierta latencia entre ellos, puesto que habrá más nodos que tengan que aceptar las propuestas.

A la hora de desplegar los manager también es necesario tener en cuenta la topología física.

 

Para una configuración en una única región, los manager deberían distribuirse en tres zonas de disponibilidad diferentes. Se podría realizar un diseño con un administrador por zona de disponibilidad para una configuración con 3 nodos o con dos zonas de dos nodos y una zona con un nodo para una configuración de 5 nodos. 

Para una configuración de dos regiones podría plantearse una región con 3 nodos, uno por cada zona de disponibilidad, y otra región con dos nodos (de nuevo, uno por cada zona de disponibilidad). 

A pesar de que el hecho de distribuir los nodos en diferentes regiones mejorará las capacidades de las dos regiones, hay que tener cuidado de no configurar los nodos demasiado alejados, ya que la latencia puede afectar a su rendimiento, tal como he mencionado anteriormente

A pesar de que el hecho de distribuir los nodos en diferentes regiones mejorará las capacidades de las dos regiones, hay que tener cuidado de no configurar los nodos demasiado alejados, ya que la latencia puede afectar a su rendimiento, tal como se ha mencionado anteriormente.

Cómo agregar un manager

La manera de agregar un nodo manager es bastante similar a la manera de agregar un nodo worker. 

En un nodo manager existente, consulta el token necesario para añadir nuevos administradores: 

                                               $ docker swarm join-token manager
                                               To add a manager to this swarm, run the following command:
                                               docker swarm join \
                                               --token SWMTKN-1-61ztec5kyafptydic6jfc1i33t37flcl4nuipzcusor96k7kby-5vy9t8u35tuqm7vh67lrz9xp6 \
                                               W.X.Y.Z:2377

Ahora sólo tienes que ejecutar este comando en el nuevo nodo de Docker que necesitas añadir como manager del swarm. 

Conclusión 🙌

Estos son los fundamentos para implementar y utilizar las redes overlay en Docker. Dejando de lado las peculiaridades de su procedimiento de despliegue, desde el punto de vista de un contenedor, las redes overlay se comportan en gran medida como las redes bridge, y ofrecen muchas características y una gran flexibilidad que permiten simplificar las redes en entornos con varios host de Docker.  

Ten en cuenta que puedes especificar diferentes opciones para crear una nueva red overlay. Consulta “docker network create –help” y https://docs.docker.com/network/overlay/.

En Internet puedes encontrar muchos ejemplos. El siguiente enlace, por ejemplo, te muestra cómo hacer un despliegue de Hyperledger Fabric sobre varios hosts usando docker swarm y redes overlay: https://medium.com/@wahabjawed/hyperledger-fabric-on-multiple-hosts-a33b08ef24f.

jaime gomez

Jaime Gómez García

Santander Global Tech

Architecture and IT & Telecom Infrastructure expert. I learn about the Internet, networks and applied cryptography every day since the mid 90’s.

 

Otros posts