Compartir comentarios
Las respuestas se generan en base a la documentación.

Controlador de red Bridge

Una red bridge de Docker tiene una subred IPv4 y, opcionalmente, una subred IPv6. Cada contenedor conectado a la red bridge tiene una interfaz de red con direcciones en las subredes de la red. De forma predeterminada:

  • Permite el acceso de red sin restricciones a los contenedores en la red desde el host y desde otros contenedores conectados a la misma red bridge.
  • Bloquea el acceso desde contenedores en otras redes y desde fuera del host de Docker.
  • Utiliza enmascaramiento (masquerading) para proporcionar acceso a redes externas a los contenedores. Los dispositivos en las redes externas del host solo ven la dirección IP del host de Docker.
  • Soporta la publicación de puertos, donde el tráfico de red se reenvía entre los puertos del contenedor y los puertos en las direcciones IP del host. Se puede acceder a los puertos publicados desde fuera del host de Docker, a través de sus direcciones IP.

En términos de Docker, una red bridge utiliza un puente de software que permite que los contenedores conectados a la misma red bridge se comuniquen, al tiempo que proporciona aislamiento de los contenedores que no están conectados a esa red bridge. De forma predeterminada, el controlador bridge de Docker instala automáticamente reglas en la máquina host para que los contenedores conectados a diferentes redes bridge solo puedan comunicarse entre sí utilizando puertos publicados.

Las redes bridge se aplican a los contenedores que se ejecutan en el mismo host del daemon de Docker. Para la comunicación entre contenedores que se ejecutan en diferentes hosts del daemon de Docker, puedes gestionar el enrutamiento a nivel de sistema operativo o puedes utilizar una red overlay.

Al iniciar Docker, se crea automáticamente una red bridge predeterminada (también llamada bridge), y los contenedores recién iniciados se conectan a ella a menos que se especifique lo contrario. También puedes crear redes bridge personalizadas definidas por el usuario. Las redes bridge definidas por el usuario son superiores a la red bridge predeterminada.

Diferencias entre los bridges definidos por el usuario y el bridge predeterminado

  • Los bridges definidos por el usuario proporcionan resolución automática de DNS entre contenedores.

    Los contenedores en la red bridge predeterminada solo pueden acceder entre sí mediante direcciones IP, a menos que utilices la opción --link, la cual se considera heredada (legacy). En una red bridge definida por el usuario, los contenedores pueden resolverse entre sí por nombre o alias.

    Imagina una aplicación con un front-end web y un back-end de base de datos. Si nombras a tus contenedores web y db, el contenedor web puede conectarse al contenedor db en db, independientemente de en qué host de Docker se esté ejecutando la pila de la aplicación.

    Si ejecutas la misma pila de aplicaciones en la red bridge predeterminada, debes crear manualmente enlaces entre los contenedores (utilizando el flag heredado --link). Estos enlaces deben crearse en ambas direcciones, por lo que puedes ver que esto se vuelve complejo con más de dos contenedores que necesitan comunicarse. Como alternativa, puedes manipular los archivos /etc/hosts dentro de los contenedores, pero esto genera problemas que son difíciles de depurar.

  • Los bridges definidos por el usuario proporcionan un mejor aislamiento.

    Todos los contenedores a los que no se les especifica un --network se conectan a la red bridge predeterminada. Esto puede ser un riesgo, ya que pilas, servicios o contenedores no relacionados pueden comunicarse entre sí.

    El uso de una red definida por el usuario proporciona una red delimitada en la que solo los contenedores conectados a esa red pueden comunicarse.

  • Los contenedores se pueden conectar y desconectar de las redes definidas por el usuario al vuelo.

    Durante la vida de un contenedor, puedes conectarlo o desconectarlo de redes definidas por el usuario sobre la marcha. Para eliminar un contenedor de la red bridge predeterminada, debes detener el contenedor y volver a crearlo con diferentes opciones de red.

  • Cada red definida por el usuario crea un bridge configurable.

    Si tus contenedores utilizan la red bridge predeterminada, puedes configurarla, pero todos los contenedores usarán la misma configuración, como el MTU y las reglas de iptables. Además, la configuración de la red bridge predeterminada se realiza fuera del propio Docker y requiere reiniciar Docker.

    Las redes bridge definidas por el usuario se crean y configuran mediante docker network create. Si diferentes grupos de aplicaciones tienen diferentes requisitos de red, puedes configurar cada bridge definido por el usuario por separado a medida que lo creas.

  • Los contenedores vinculados en la red bridge predeterminada comparten variables de entorno.

    Originalmente, la única forma de compartir variables de entorno entre dos contenedores era vincularlos utilizando el flag --link. Este tipo de uso compartido de variables no es posible con las redes definidas por el usuario. Sin embargo, existen mejores formas de compartir variables de entorno. Algunas ideas:

    • Varios contenedores pueden montar un archivo o directorio que contenga la información compartida, utilizando un volumen de Docker.
    • Se pueden iniciar varios contenedores juntos utilizando docker-compose y el archivo de compose puede definir las variables compartidas.
    • Puedes utilizar servicios de swarm en lugar de contenedores independientes y aprovechar los secrets y configs compartidos.

Los contenedores conectados a la misma red bridge definida por el usuario exponen efectivamente todos los puertos entre sí. Para que un puerto sea accesible a contenedores o hosts que no son de Docker en redes diferentes, ese puerto debe ser publicado utilizando el flag -p o --publish.

Opciones

La siguiente tabla describe las opciones específicas del controlador que puedes pasar a --opt al crear una red personalizada utilizando el controlador bridge.

OpciónPredeterminadoDescripción
com.docker.network.bridge.nameNombre de la interfaz que se utilizará al crear el puente Linux.
com.docker.network.bridge.enable_ip_masqueradetrueHabilita el enmascaramiento de IP.
com.docker.network.host_ipv4
com.docker.network.host_ipv6
Dirección que se utilizará para el NAT de origen. Consulta Filtrado de paquetes y cortafuegos.
com.docker.network.bridge.gateway_mode_ipv4
com.docker.network.bridge.gateway_mode_ipv6
natControla la conectividad externa. Consulta Filtrado de paquetes y cortafuegos.
com.docker.network.bridge.enable_icctrueHabilita o deshabilita la conectividad entre contenedores (inter-container connectivity).
com.docker.network.bridge.host_binding_ipv4todas las direcciones IPv4 e IPv6IP predeterminada al vincular puertos de contenedores.
com.docker.network.driver.mtu0 (sin límite)Establece la Unidad Máxima de Transmisión (MTU) de la red de los contenedores.
com.docker.network.container_iface_prefixethEstablece un prefijo personalizado para las interfaces del contenedor.
com.docker.network.bridge.inhibit_ipv4falseEvita que Docker asigne una dirección IP al bridge.

Algunas de estas opciones también están disponibles como flags para la CLI de dockerd, y puedes utilizarlas para configurar el bridge docker0 predeterminado al iniciar el daemon de Docker. La siguiente tabla muestra qué opciones tienen flags equivalentes en la CLI de dockerd.

OpciónFlag
com.docker.network.bridge.name-
com.docker.network.bridge.enable_ip_masquerade--ip-masq
com.docker.network.bridge.enable_icc--icc
com.docker.network.bridge.host_binding_ipv4--ip
com.docker.network.driver.mtu--mtu
com.docker.network.container_iface_prefix-

El daemon de Docker admite un flag --bridge, que puedes utilizar para definir tu propio bridge docker0. Utiliza esta opción si deseas ejecutar varias instancias del daemon en el mismo host. Para obtener más detalles, consulta Ejecutar múltiples daemons.

Dirección predeterminada de vinculación del host

Cuando no se proporciona una dirección de host en las opciones de publicación de puertos como -p 80 o -p 8080:80, el comportamiento predeterminado es hacer que el puerto 80 del contenedor esté disponible en todas las direcciones del host, tanto IPv4 como IPv6.

La opción del controlador de red bridge com.docker.network.bridge.host_binding_ipv4 se puede utilizar para modificar la dirección predeterminada para los puertos publicados.

A pesar del nombre de la opción, es posible especificar una dirección IPv6.

Cuando la dirección de vinculación predeterminada es una dirección asignada a una interfaz específica, el puerto del contenedor solo será accesible a través de esa dirección.

Establecer la dirección de vinculación predeterminada en :: significa que los puertos publicados solo estarán disponibles en las direcciones IPv6 del host. Sin embargo, establecerla en 0.0.0.0 significa que estará disponible en las direcciones IPv4 e IPv6 del host.

Para restringir un puerto publicado únicamente a IPv4, la dirección debe incluirse en las opciones de publicación del contenedor. Por ejemplo, -p 0.0.0.0:8080:80.

Gestionar un bridge definido por el usuario

Utiliza el comando docker network create para crear una red bridge definida por el usuario.

$ docker network create mi-red

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

Utiliza el comando docker network rm para eliminar una red bridge definida por el usuario. Si hay contenedores conectados actualmente a la red, desconéctalos primero.

$ docker network rm mi-red

¿Qué está sucediendo realmente?

Cuando creas o eliminas un bridge definido por el usuario, o conectas o desconectas un contenedor de un bridge definido por el usuario, Docker utiliza herramientas específicas del sistema operativo para gestionar la infraestructura de red subyente (como añadir o eliminar dispositivos bridge o configurar reglas de iptables en Linux). Estos detalles deben considerarse detalles de implementación. Deja que Docker encuentre tus redes definidas por el usuario por ti.

Conectar un contenedor a un bridge definido por el usuario

Al crear un nuevo contenedor, puedes especificar uno o más flags --network. Este ejemplo conecta un contenedor Nginx a la red mi-net. También publica el puerto 80 del contenedor en el puerto 8080 del host de Docker, para que los clientes externos puedan acceder a ese puerto. Cualquier otro contenedor conectado a la red mi-net tiene acceso a todos los puertos del contenedor mi-nginx, y viceversa.

$ docker create --name mi-nginx \
  --network mi-net \
  --publish 8080:80 \
  nginx:latest

Para conectar un contenedor en ejecución a un bridge definido por el usuario existente, utiliza el comando docker network connect. El siguiente comando conecta un contenedor mi-nginx que ya está en ejecución a una red mi-net que ya existe:

$ docker network connect mi-net mi-nginx

Desconectar un contenedor de un bridge definido por el usuario

Para desconectar un contenedor en ejecución de un bridge definido por el usuario, utiliza el comando docker network disconnect. El siguiente comando desconecta el contenedor mi-nginx de la red mi-net.

$ docker network disconnect mi-net mi-nginx

Utilizar IPv6 en una red bridge definida por el usuario

Al crear tu red, puedes especificar el flag --ipv6 para habilitar IPv6.

$ docker network create --ipv6 --subnet 2001:db8:1234::/64 mi-net

Si no proporcionas una opción --subnet, se elegirá automáticamente un prefijo de Dirección Local Única (ULA).

Redes bridge solo IPv6

Para omitir la configuración de la dirección IPv4 en el bridge y en sus contenedores, crea la red con la opción --ipv4=false y habilita IPv6 utilizando --ipv6.

$ docker network create --ipv6 --ipv4=false red-v6

La configuración de la dirección IPv4 no se puede deshabilitar en la red bridge predeterminada.

Utilizar la red bridge predeterminada

La red bridge predeterminada se considera un detalle heredado de Docker y no se recomienda para su uso en producción. Su configuración es una operación manual y presenta inconvenientes técnicos.

Conectar un contenedor a la red bridge predeterminada

Si no especificas una red mediante el flag --network y especificas un controlador de red, tu contenedor se conectará a la red bridge predeterminada de forma automática. Los contenedores conectados a la red bridge predeterminada pueden comunicarse entre sí, pero solo por dirección IP, a menos que estén vinculados mediante el flag heredado --link.

Configurar la red bridge predeterminada

Para configurar la red bridge predeterminada, debes especificar las opciones en daemon.json. A continuación, se muestra un ejemplo de daemon.json con varias opciones especificadas. Especifica únicamente los ajustes que necesites personalizar.

{
  "bip": "192.168.1.1/24",
  "fixed-cidr": "192.168.1.0/25",
  "mtu": 1500,
  "default-gateway": "192.168.1.254",
  "dns": ["10.20.1.2", "10.20.1.3"]
}

En este ejemplo:

  • La dirección del bridge es "192.168.1.1/24" (de bip).
  • La subred de la red bridge es "192.168.1.0/24" (de bip).
  • Las direcciones de los contenedores se asignarán desde "192.168.1.0/25" (de fixed-cidr).

Utilizar IPv6 con la red bridge predeterminada

IPv6 se puede habilitar para el bridge predeterminado utilizando las siguientes opciones en daemon.json, o sus equivalentes en la línea de comandos.

Estas tres opciones solo afectan al bridge predeterminado, no son utilizadas por las redes definidas por el usuario. Las direcciones que se muestran a continuación son ejemplos del rango de documentación de IPv6.

  • Se requiere la opción ipv6.
  • La opción bip6 es opcional; especifica la dirección del bridge predeterminado, que será utilizada como puerta de enlace predeterminada por los contenedores. También especifica la subred para la red bridge.
  • La opción fixed-cidr-v6 es opcional; especifica el rango de direcciones que Docker puede asignar automáticamente a los contenedores.
    • El prefijo normalmente debe ser /64 o más corto.
    • Para experimentar en una red local, es mejor utilizar un prefijo de Dirección Local Única (ULA) (que coincida con fd00::/8) en lugar de un prefijo de Enlace Local (Link Local) (que coincida con fe80::/10).
  • La opción default-gateway-v6 es opcional. Si no se especifica, el valor predeterminado es la primera dirección en la subred fixed-cidr-v6.
{
  "ipv6": true,
  "bip6": "2001:db8::1111/64",
  "fixed-cidr-v6": "2001:db8::/64",
  "default-gateway-v6": "2001:db8:abcd::89"
}

Si no se especifica bip6, fixed-cidr-v6 define la subred para la red bridge. Si no se especifica bip6 ni fixed-cidr-v6, se elegirá un prefijo ULA.

Reinicia Docker para que los cambios surtan efecto.

Límite de conexiones para redes bridge

Debido a las limitaciones establecidas por el kernel de Linux, las redes bridge se vuelven inestables y las comunicaciones entre contenedores pueden interrumpirse cuando se conectan 1000 contenedores o más a una sola red.

Para obtener más información sobre esta limitación, consulta moby/moby#44973.

Omitir la configuración de la dirección IP del bridge

Al bridge se le asigna normalmente la dirección --gateway de la red, que se utiliza como la ruta predeterminada desde la red bridge hacia otras redes.

La opción com.docker.network.bridge.inhibit_ipv4 te permite crear una red sin asignar la dirección de puerta de enlace IPv4 al bridge. Esto resulta útil si deseas configurar manualmente la dirección IP de la puerta de enlace para el bridge. Por ejemplo, si añades una interfaz física a tu bridge y necesitas que tenga la dirección de la puerta de enlace.

Con esta configuración, el tráfico norte-sur (hacia y desde la red bridge) no funcionará a menos que hayas configurado manualmente la dirección de la puerta de enlace en el bridge o en un dispositivo conectado a él.

Esta opción solo se puede utilizar con redes bridge definidas por el usuario.

Ejemplos de uso

Esta sección proporciona ejemplos prácticos para trabajar con redes bridge.

Utilizar la red bridge predeterminada

Este ejemplo muestra cómo funciona la red bridge predeterminada. Iniciará dos contenedores alpine en el bridge predeterminado y probará cómo se comunican.

Note

No se recomienda la red bridge predeterminada para producción. Utiliza en su lugar redes bridge definidas por el usuario.

  1. Listar las redes actuales:

    $ docker network ls
    
    NETWORK ID          NAME                DRIVER              SCOPE
    17e324f45964        bridge              bridge              local
    6ed54d316334        host                host                local
    7092879f2cc8        none                null                local
    

    Se muestra la red bridge predeterminada, junto con host y none.

  2. Iniciar dos contenedores alpine ejecutando ash. Los flags -dit significan en segundo plano (detached), interactivo y con un TTY. Dado que no has especificado un flag --network, los contenedores se conectan a la red bridge predeterminada.

    $ docker run -dit --name alpine1 alpine ash
    $ docker run -dit --name alpine2 alpine ash
    

    Verificar que ambos contenedores estén en ejecución:

    $ docker container ls
    
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    602dbf1edc81        alpine              "ash"               4 seconds ago       Up 3 seconds                            alpine2
    da33b7aa74b0        alpine              "ash"               17 seconds ago      Up 16 seconds                           alpine1
    
  3. Inspeccionar la red bridge para ver los contenedores conectados:

    $ docker network inspect bridge
    

    La salida muestra ambos contenedores conectados, con sus direcciones IP asignadas (172.17.0.2 para alpine1 y 172.17.0.3 para alpine2).

  4. Conectarse a alpine1:

    $ docker attach alpine1
    
    / #
    

    Mostrar las interfaces de red para alpine1 desde dentro del contenedor:

    # ip addr show
    
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host
           valid_lft forever preferred_lft forever
    27: eth0@if28: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
        link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.2/16 scope global eth0
           valid_lft forever preferred_lft forever
    

    En este ejemplo, la interfaz eth0 tiene la dirección IP 172.17.0.2.

  5. Desde dentro de alpine1, verificar que puedes conectarte a Internet:

    # ping -c 2 google.com
    
    PING google.com (172.217.3.174): 56 data bytes
    64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.841 ms
    64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.897 ms
    
    --- google.com ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 9.841/9.869/9.897 ms
    
  6. Hacer ping al segundo contenedor por su dirección IP:

    # ping -c 2 172.17.0.3
    
    PING 172.17.0.3 (172.17.0.3): 56 data bytes
    64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.086 ms
    64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.094 ms
    
    --- 172.17.0.3 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.086/0.090/0.094 ms
    

    Esto funciona. Ahora intenta hacer ping por el nombre del contenedor:

    # ping -c 2 alpine2
    
    ping: bad address 'alpine2'
    

    En la red bridge predeterminada, los contenedores no pueden resolverse entre sí por nombre.

  7. Desconectarse de alpine1 sin detenerlo utilizando CTRL+p CTRL+q.

  8. Limpiar: detener los contenedores y eliminarlos.

    $ docker container stop alpine1 alpine2
    $ docker container rm alpine1 alpine2
    

    Los contenedores detenidos pierden sus direcciones IP.

Utilizar redes bridge definidas por el usuario

Este ejemplo muestra cómo las redes bridge definidas por el usuario proporcionan un mejor aislamiento y resolución automática de DNS entre contenedores.

  1. Crear la red alpine-net:

    $ docker network create --driver bridge alpine-net
    
  2. Listar las redes de Docker:

    $ docker network ls
    
    NETWORK ID          NAME                DRIVER              SCOPE
    e9261a8c9a19        alpine-net          bridge              local
    17e324f45964        bridge              bridge              local
    6ed54d316334        host                host                local
    7092879f2cc8        none                null                local
    

    Inspeccionar la red alpine-net:

    $ docker network inspect alpine-net
    

    Esto muestra la puerta de enlace de la red (por ejemplo, 172.18.0.1) y que aún no hay contenedores conectados.

  3. Crear cuatro contenedores. Tres se conectan a alpine-net y uno se conecta al bridge predeterminado. Luego, conecta un contenedor a ambas redes:

    $ docker run -dit --name alpine1 --network alpine-net alpine ash
    $ docker run -dit --name alpine2 --network alpine-net alpine ash
    $ docker run -dit --name alpine3 alpine ash
    $ docker run -dit --name alpine4 --network alpine-net alpine ash
    $ docker network connect bridge alpine4
    

    Verificar que todos los contenedores estén en ejecución:

    $ docker container ls
    
    CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
    156849ccd902        alpine              "ash"               41 seconds ago       Up 41 seconds                           alpine4
    fa1340b8d83e        alpine              "ash"               51 seconds ago       Up 51 seconds                           alpine3
    a535d969081e        alpine              "ash"               About a minute ago   Up About a minute                       alpine2
    0a02c449a6e9        alpine              "ash"               About a minute ago   Up About a minute                       alpine1
    
  4. Inspeccionar ambas redes de nuevo para ver qué contenedores están conectados:

    $ docker network inspect bridge
    

    Los contenedores alpine3 and alpine4 están conectados a la red bridge.

    $ docker network inspect alpine-net
    

    Los contenedores alpine1, alpine2 y alpine4 están conectados a alpine-net.

  5. En las redes definidas por el usuario, los contenedores pueden resolverse entre sí por nombre. Conéctate a alpine1 y realiza la prueba:

    Note

    El descubrimiento automático de servicios solo resuelve nombres de contenedores personalizados, no los nombres predeterminados generados automáticamente.

    $ docker container attach alpine1
    
    # ping -c 2 alpine2
    
    PING alpine2 (172.18.0.3): 56 data bytes
    64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.085 ms
    64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.090 ms
    
    --- alpine2 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.085/0.087/0.090 ms
    
    # ping -c 2 alpine4
    
    PING alpine4 (172.18.0.4): 56 data bytes
    64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.076 ms
    64 bytes from 172.18.0.4: seq=1 ttl=64 time=0.091 ms
    
    --- alpine4 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.076/0.083/0.091 ms
    
  6. Desde alpine1, no puedes conectarte a alpine3 porque está en una red diferente:

    # ping -c 2 alpine3
    
    ping: bad address 'alpine3'
    

    Tampoco puedes conectarte por dirección IP. Si la IP de alpine3 es 172.17.0.2:

    # ping -c 2 172.17.0.2
    
    PING 172.17.0.2 (172.17.0.2): 56 data bytes
    
    --- 172.17.0.2 ping statistics ---
    2 packets transmitted, 0 packets received, 100% packet loss
    

    Desconéctate de alpine1 usando CTRL+p CTRL+q.

  7. Dado que alpine4 está conectado a ambas redes, puede llegar a todos los contenedores. Sin embargo, debes utilizar la dirección IP de alpine3:

    $ docker container attach alpine4
    
    # ping -c 2 alpine1
    
    PING alpine1 (172.18.0.2): 56 data bytes
    64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.074 ms
    64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.082 ms
    
    --- alpine1 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.074/0.078/0.082 ms
    
    # ping -c 2 alpine2
    
    PING alpine2 (172.18.0.3): 56 data bytes
    64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.075 ms
    64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.080 ms
    
    --- alpine2 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.075/0.077/0.080 ms
    
    # ping -c 2 alpine3
    ping: bad address 'alpine3'
    
    # ping -c 2 172.17.0.2
    
    PING 172.17.0.2 (172.17.0.2): 56 data bytes
    64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.089 ms
    64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.075 ms
    
    --- 172.17.0.2 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.075/0.082/0.089 ms
    
  8. Verificar que todos los contenedores puedan conectarse a Internet:

    # ping -c 2 google.com
    
    PING google.com (172.217.3.174): 56 data bytes
    64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.778 ms
    64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.634 ms
    
    --- google.com ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 9.634/9.706/9.778 ms
    

    Desconéctate con CTRL+p CTRL+q y repite para alpine3 y alpine1 si lo deseas.

  9. Limpiar:

    $ docker container stop alpine1 alpine2 alpine3 alpine4
    $ docker container rm alpine1 alpine2 alpine3 alpine4
    $ docker network rm alpine-net
    

Siguientes pasos