# Controlador de red Overlay


El controlador de red `overlay` crea una red distribuida entre múltiples hosts del daemon de Docker. Esta red se sitúa por encima de (se superpone a) las redes específicas del host, lo que permite que los contenedores conectados a ella se comuniquen de forma segura cuando el cifrado está habilitado. Docker gestiona de manera transparente el enrutamiento de cada paquete hacia y desde el host del daemon de Docker correcto y el contenedor de destino correcto.

Puedes crear redes `overlay` definidas por el usuario utilizando `docker network create`, de la misma manera que puedes crear redes `bridge` definidas por el usuario. Los servicios o contenedores se pueden conectar a más de una red a la vez. Los servicios o contenedores solo pueden comunicarse a través de las redes a las que están conectados.

Las redes overlay se utilizan a menudo para crear una conexión entre servicios de Swarm, pero también puedes utilizarlas para conectar contenedores independientes que se ejecutan en diferentes hosts. Al utilizar contenedores independientes, sigue siendo necesario utilizar el modo Swarm para establecer una conexión entre los hosts.

Esta página describe las redes overlay en general y cuando se utilizan con contenedores independientes. Para obtener información sobre overlay para servicios de Swarm, consulta [Gestionar redes de servicios de Swarm](/engine/swarm/networking/).

## Requisitos

Los hosts de Docker deben formar parte de un swarm para utilizar redes overlay, incluso al conectar contenedores independientes. Los siguientes puertos deben estar abiertos entre los hosts participantes:

- `2377/tcp`: Plano de control de Swarm (configurable)
- `4789/udp`: Tráfico overlay (configurable)
- `7946/tcp` y `7946/udp`: Comunicación entre nodos (no configurable)

## Crear una red overlay

La siguiente tabla enumera los puertos que deben estar abiertos para cada host que participe en una red overlay:

| Puertos | Descripción |
| :--- | :--- |
| `2377/tcp` | El puerto predeterminado del plano de control de Swarm, es configurable con [`docker swarm join --listen-addr`](/reference/cli/docker/swarm/join/#listen-addr) |
| `4789/udp` | El puerto predeterminado para el tráfico overlay, configurable con [`docker swarm init --data-path-addr`](/reference/cli/docker/swarm/init/#data-path-port) |
| `7946/tcp`, `7946/udp` | Utilizados para la comunicación entre nodos, no son configurables |

Para crear una red overlay a la que se puedan conectar contenedores de otros hosts de Docker, ejecuta el siguiente comando:

```console
$ docker network create -d overlay --attachable mi-overlay-conectable
```

La opción `--attachable` permite que tanto los contenedores independientes como los servicios de Swarm se conecten a la red overlay. Sin la opción `--attachable`, solo los servicios de Swarm podrán conectarse a la red.

Puedes especificar el rango de direcciones IP, la subred, la puerta de enlace y otras opciones. Consulta `docker network create --help` para obtener más detalles.

## Cifrar el tráfico en una red overlay

Utiliza el flag `--opt encrypted` para cifrar los datos de la aplicación transmitidos a través de la red overlay:

```console
$ docker network create \
  --opt encrypted \
  --driver overlay \
  --attachable \
  mi-red-multi-host-conectable
```

Esto habilita el cifrado IPsec a nivel de la red de área local extensible virtual (VXLAN). Este cifrado conlleva una penalización de rendimiento no despreciable, por lo que debes probar esta opción antes de utilizarla en producción.

> [!WARNING]
>
> No conectes contenedores Windows a redes overlay cifradas.
>
> El cifrado de redes overlay no es compatible con Windows. Swarm no informa de ningún error cuando un host de Windows intenta conectarse a una red overlay cifrada, pero la red para los contenedores Windows se verá afectada de la siguiente manera:
>
> - Los contenedores Windows no pueden comunicarse con contenedores Linux en la red.
> - El tráfico de datos entre contenedores Windows en la red no se cifra.

## Conectar un contenedor a una red overlay

Añadir contenedores a una red overlay les otorga la capacidad de comunicarse con otros contenedores sin tener que configurar el enrutamiento en los hosts individuales del daemon de Docker. Un requisito previo para hacer esto es que los hosts se hayan unido al mismo Swarm.

Para unirte a una red overlay llamada `multi-host-network` con un contenedor `busybox`:

```console
$ docker run --network multi-host-network busybox sh
```

> [!NOTE]
>
> Esto solo funciona si la red overlay es conectable (creada con el flag `--attachable`).

## Descubrimiento de contenedores

La publicación de puertos de un contenedor en una red overlay abre los puertos a otros contenedores en la misma red. Los contenedores se pueden descubrir realizando una búsqueda DNS utilizando el nombre del contenedor.

| Valor del flag | Descripción |
| :--- | :--- |
| `-p 8080:80` | Mapea el puerto TCP 80 del contenedor al puerto `8080` de la red overlay. |
| `-p 8080:80/udp` | Mapea el puerto UDP 80 del contenedor al puerto `8080` de la red overlay. |
| `-p 8080:80/sctp` | Mapea el puerto SCTP 80 del contenedor al puerto `8080` de la red overlay. |
| `-p 8080:80/tcp -p 8080:80/udp` | Mapea el puerto TCP 80 del contenedor al puerto TCP `8080` de la red overlay, y mapea el puerto UDP 80 del contenedor al puerto UDP `8080` de la red overlay. |

## Límite de conexiones para redes overlay

Debido a las limitaciones establecidas por el kernel de Linux, las redes overlay se vuelven inestables y las comunicaciones entre contenedores pueden interrumpirse cuando se ubican 1000 contenedores en el mismo host.

Para obtener más información sobre esta limitación, consulta [moby/moby#44973](https://github.com/moby/moby/issues/44973#issuecomment-1543747718).

## Ejemplos de uso

Esta sección proporciona ejemplos prácticos para trabajar con redes overlay. Estos ejemplos abarcan servicios de swarm y contenedores independientes en múltiples hosts de Docker.

### Requisitos previos

Todos los ejemplos requieren al menos un swarm de un solo nodo. Inicializa uno ejecutando `docker swarm init` en el host. También puedes ejecutar estos ejemplos en swarms de múltiples nodos.

### Utilizar la red overlay predeterminada

Este ejemplo muestra cómo funciona la red overlay predeterminada con los servicios de swarm. Crearás un servicio `nginx` y examinarás la red desde la perspectiva de los contenedores del servicio.

#### Requisitos previos para la configuración de múltiples nodos

Esta guía paso a paso requiere tres hosts de Docker que puedan comunicarse entre sí en la misma red sin que ningún cortafuegos bloquee el tráfico entre ellos:

- `manager`: Funciona como manager y worker.
- `worker-1`: Funciona solo como worker.
- `worker-2`: Funciona solo como worker.

Si no tienes tres hosts disponibles, puedes configurar tres máquinas virtuales en un proveedor de la nube con Docker instalado.

#### Crear el swarm

1. En el `manager`, inicializa el swarm. Si el host tiene una sola interfaz de red, el flag `--advertise-addr` es opcional:

   ```console
   $ docker swarm init --advertise-addr=<IP-DEL-MANAGER>
   ```

   Guarda el token de unión que se muestra para utilizarlo con los workers.

2. En el `worker-1`, únete al swarm:

   ```console
   $ docker swarm join --token <TOKEN> \
     --advertise-addr <IP-DEL-WORKER-1> \
     <IP-DEL-MANAGER>:2377
   ```

3. En el `worker-2`, únete al swarm:

   ```console
   $ docker swarm join --token <TOKEN> \
     --advertise-addr <IP-DEL-WORKER-2> \
     <IP-DEL-MANAGER>:2377
   ```

4. En el `manager`, enumera todos los nodos:

   ```console
   $ 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
   ```

   Filtra por rol si es necesario:

   ```console
   $ docker node ls --filter role=manager
   $ docker node ls --filter role=worker
   ```

5. Enumera las redes de Docker en todos los hosts. Cada uno tiene ahora una red overlay llamada `ingress` y una red bridge llamada `docker_gwbridge`:

   ```console
   $ 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
   ```

La red `docker_gwbridge` conecta la red `ingress` a la interfaz de red del host de Docker. Si creas servicios sin especificar una red, estos se conectarán a `ingress`. Se recomienda utilizar redes overlay independientes para cada aplicación o grupo de aplicaciones relacionadas.

#### Crear los servicios

1. En el `manager`, crea una nueva red overlay:

   ```console
   $ docker network create -d overlay nginx-net
   ```

   La red overlay se crea automáticamente en los nodos worker cuando ejecutan tareas de servicio que la necesitan.

2. En el `manager`, crea un servicio Nginx con 5 réplicas conectado a `nginx-net`:

   > [!NOTE]
   > Los servicios solo se pueden crear en un manager.

   ```console
   $ docker service create \
     --name mi-nginx \
     --publish target=80,published=80 \
     --replicas=5 \
     --network nginx-net \
     nginx
   ```

   El modo de publicación `ingress` predeterminado significa que puedes navegar al puerto 80 en cualquier nodo y conectarte a una de las 5 tareas de servicio, incluso si no se ejecutan tareas en ese nodo.

3. Supervisa el progreso de la creación del servicio:

   ```console
   $ docker service ls
   ```

4. Inspecciona la red `nginx-net` en todos los hosts. La sección `Containers` enumera todas las tareas de servicio conectadas a la red overlay desde ese host.

5. Desde el `manager`, inspecciona el servicio:

   ```console
   $ docker service inspect mi-nginx
   ```

   Observa la información sobre puertos y puntos de conexión (endpoints).

6. Crea una segunda red y actualiza el servicio para que la utilice:

   ```console
   $ docker network create -d overlay nginx-net-2
   $ docker service update \
     --network-add nginx-net-2 \
     --network-rm nginx-net \
     mi-nginx
   ```

7. Verifica que la actualización haya finalizado:

   ```console
   $ docker service ls
   ```

   Inspecciona ambas redes para verificar que los contenedores se movieron de `nginx-net` a `nginx-net-2`.

   > [!NOTE]
   > Las redes overlay se crean automáticamente en los nodos worker del swarm según sea necesario, pero no se eliminan automáticamente.

8. Limpiar:

   ```console
   $ docker service rm mi-nginx
   $ docker network rm nginx-net nginx-net-2
   ```

### Utilizar una red overlay definida por el usuario

Este ejemplo muestra el enfoque recomendado para los servicios de producción utilizando redes overlay personalizadas.

#### Requisitos previos

Se asume que el swarm ya está configurado y que te encuentras en un nodo manager.

#### Pasos

1. Crea una red overlay definida por el usuario:

   ```console
   $ docker network create -d overlay mi-overlay
   ```

2. Inicia un servicio utilizando la red overlay, publicando el puerto 80 en el puerto 8080:

   ```console
   $ docker service create \
     --name mi-nginx \
     --network mi-overlay \
     --replicas 1 \
     --publish published=8080,target=80 \
     nginx:latest
   ```

3. Verifica que la tarea del servicio esté conectada a la red:

   ```console
   $ docker network inspect mi-overlay
   ```

   Comprueba la sección `Containers` para ver la tarea del servicio `mi-nginx`.

4. Limpiar:

   ```console
   $ docker service rm mi-nginx
   $ docker network rm mi-overlay
   ```

### Utilizar una red overlay para contenedores independientes

Este ejemplo demuestra el descubrimiento de contenedores mediante DNS entre contenedores independientes en diferentes hosts de Docker utilizando una red overlay.

#### Requisitos previos

Necesitas dos hosts de Docker que puedan comunicarse entre sí con los siguientes puertos abiertos entre ellos:

- Puerto TCP 2377
- Puerto TCP y UDP 7946
- Puerto UDP 4789

Este ejemplo se refiere a los hosts como `host1` y `host2`.

#### Pasos

1. Configurar el swarm:

   En `host1`, inicializa un swarm:

   ```console
   $ docker swarm init
   Swarm initialized: current node (vz1mm9am11qcmo979tlrlox42) is now a manager.

   To add a worker to this swarm, run the following command:

       docker swarm join --token SWMTKN-1-5g90q48weqrtqryq4kj6ow0e8xm9wmv9o6vgqc5j320ymybd5c-8ex8j0bc40s6hgvy5ui5gl4gy 172.31.47.252:2377
   ```

   En `host2`, únete al swarm utilizando el token de la salida anterior:

   ```console
   $ docker swarm join --token <tu_token> <tu_direccion_ip>:2377
   This node joined a swarm as a worker.
   ```

   Si la unión falla, ejecuta `docker swarm leave --force` en `host2`, verifica la configuración de red y del cortafuegos, e inténtalo de nuevo.

2. En `host1`, crea una red overlay conectable:

   ```console
   $ docker network create --driver=overlay --attachable test-net
   uqsof8phj3ak0rq9k86zta6ht
   ```

   Toma nota del ID de red devuelto.

3. En `host1`, inicia un contenedor interactivo que se conecte a `test-net`:

   ```console
   $ docker run -it --name alpine1 --network test-net alpine
   / #
   ```

4. En `host2`, enumera las redes disponibles. Observa que `test-net` aún no existe:

   ```console
   $ docker network ls
   NETWORK ID          NAME                DRIVER              SCOPE
   ec299350b504        bridge              bridge              local
   66e77d0d0e9a        docker_gwbridge     bridge              local
   9f6ae26ccb82        host                host                local
   omvdxqrda80z        ingress             overlay             swarm
   b65c952a4b2b        none                null                local
   ```

5. En `host2`, inicia un contenedor interactivo en segundo plano (detached) que se conecte a `test-net`:

   ```console
   $ docker run -dit --name alpine2 --network test-net alpine
   fb635f5ece59563e7b8b99556f816d24e6949a5f6a5b1fbd92ca244db17a4342
   ```

   > [!NOTE]
   > El descubrimiento automático de contenedores mediante DNS solo funciona con nombres de contenedor únicos.

6. En `host2`, verifica que `test-net` se haya creado con el mismo ID de red que en `host1`:

   ```console
   $ docker network ls
   NETWORK ID          NAME                DRIVER              SCOPE
   ...
   uqsof8phj3ak        test-net            overlay             swarm
   ```

7. En `host1`, haz ping a `alpine2` desde dentro de `alpine1`:

   ```console
   / # ping -c 2 alpine2
   PING alpine2 (10.0.0.5): 56 data bytes
   64 bytes from 10.0.0.5: seq=0 ttl=64 time=0.600 ms
   64 bytes from 10.0.0.5: seq=1 ttl=64 time=0.555 ms

   --- alpine2 ping statistics ---
   2 packets transmitted, 2 packets received, 0% packet loss
   round-trip min/avg/max = 0.555/0.577/0.600 ms
   ```

   Los dos contenedores se comunican a través de la red overlay que conecta los dos hosts. También puedes ejecutar otro contenedor en `host2` y hacer ping a `alpine1`:

   ```console
   $ docker run -it --rm --name alpine3 --network test-net alpine
   / # ping -c 2 alpine1
   / # exit
   ```

8. En `host1`, cierra la sesión de `alpine1` (lo que detiene el contenedor):

   ```console
   / # exit
   ```

9. Limpiar. Debes detener y eliminar los contenedores en cada host de forma independiente:

   En `host2`:

   ```console
   $ docker container stop alpine2
   $ docker network ls
   $ docker container rm alpine2
   ```

   Al detener `alpine2`, `test-net` desaparece de `host2`.

   En `host1`:

   ```console
   $ docker container rm alpine1
   $ docker network rm test-net
   ```

## Siguientes pasos

- Aprende sobre la [red desde el punto de vista del contenedor](/engine/drivers/)
- Aprende sobre las [redes bridge independientes](/engine/network/drivers/overlay/bridge/)
- Aprende sobre las [redes Macvlan](/engine/network/drivers/overlay/macvlan/)

