/ HOWTO

Redes en Docker.


Configuraciones de redes usando Docker.


Al instalar Docker, se configura automáticamente para usar la red 172.17.0.xx, el propio servidor docker es 172.17.0.1 y cada contenedor corriendo adquiere un IP posterior al último (172.17.0.2-254).

Al arrancar un contenedor podremos averiguar cual es la IP asignada con este comando, indicando al final el HASH del contenedor. En este caso nos dice 172.17.0.2.

# docker inspect -f ' { {range.NetworkSettings.Networks } } { { .IPAddress } } { { end } } ' 092d7808fec2
172.17.0.2

Existen 3 redes preconfiguradas en Docker,

  1. Bridge. La red standard que usarán todos los contenedores.
  2. Host. El contenedor usará el mismo IP del servidor real que tengamos.
  3. None. Se utiliza para indicar que un contenedor no tiene asignada una red.
# docker network ls
NETWORK ID          NAME                DRIVER
7fca4eb8c647        bridge              bridge
9f904ee27bf5        none                null
cf03ee007fb4        host                host

Vemos las características de la red Bridge.

# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "fc913afec58e88174c0c0ad3303c127491c5ecd7f4781efaa72328533fda3849",
        "Created": "2017-10-30T14:13:13.416938504+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

En la red Host, veremos menos parámetros.

# docker network inspect host
[
    {
        "Name": "host",
        "Id": "cfa3166b7c218240aca2dd26b2d30907dab6797901a11f80af5582b2bc3be95b",
        "Created": "2017-10-21T14:19:11.014158975+02:00",
        "Scope": "local",
        "Driver": "host",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": []
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

Ahora crearemos una nueva red

# docker network create test
6ed3a8fb0a4e754aabdee1b97179f7a044e6f065faa3671d22e506c2f55293c4

Y veremos que existe con el nombre “test” y usará el driver Bridge.

# docker network ls
NETWORK ID          NAME                 DRIVER              SCOPE
fc913afec58e        bridge               bridge              local
cfa3166b7c21        host                 host                local
d2cfae0f64d8        none                 null                local
6ed3a8fb0a4e        test                 bridge              local

El rango que usa es 172.18.0.x

# docker network inspect test
[
    {
        "Name": "test",
        "Id": "6ed3a8fb0a4e754aabdee1b97179f7a044e6f065faa3671d22e506c2f55293c4",
        "Created": "2017-10-30T17:38:29.996067055+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

Cada nueva red que creemos usará una nueva subred (172.19, 172.20, 172.21 … etc)

Crearemos una red nueva, que se podrá usar para aislar ciertos contenedores, en este caso será la 172.19.0.xx

#docker network create --driver bridge mi_red

A partir de crear nuevas redes, las podemos utilizar en contenedores, si arrancamos dos contenedores indicando que usen esa red con “–network xxx” ambos obtendrán un IP de ese rango (172.19.0.2 y 3) y se verán entre si.

# docker run -d -P --name Contenedor_Nombre --network mi_red imagen_uno

En nuestro caso los datos de esta segunda nueva red son

# docker network inspect mi_red
[
    {
        "Name": "mi_red",
        "Id": "428da0f3c44cdb575e0e46afcf162d75dc1d9a1c6b20127020a6f47f6632f641",
        "Created": "2017-10-30T17:41:05.937502728+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

También podemos borrar esa nueva red.

# docker network rm mi_red

En nuestro equipo real, podremos verificar que el rango 172.18.0.1 está activo y nuestro servidor real posee el IP 172.18.0.1

# ping 172.18.0.1 -c 3
PING 172.18.0.1 (172.18.0.1) 56(84) bytes of data.
64 bytes from 172.18.0.1: icmp_seq=1 ttl=64 time=0.084 ms
64 bytes from 172.18.0.1: icmp_seq=2 ttl=64 time=0.070 ms
64 bytes from 172.18.0.1: icmp_seq=3 ttl=64 time=0.094 ms

--- 172.18.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2017ms
rtt min/avg/max/mdev = 0.070/0.082/0.094/0.014 ms

Correremos dos contenedores en la misma red standard ( bridge ).

# docker start ubussh1
# docker start ubussh2

Veremos que tienen asignados las IPs

"IPAddress": "172.17.0.2",
y
"IPAddress": "172.17.0.3",

En uno de ellos habíamos modificado el límite de memoria, nos indica que tenemos en uso el 6.74%, el otro contenedor tiene como límite la RAM del equipo real.

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
05b2d9947b11        ubussh2             0.00%               1.629MiB / 7.685GiB   0.02%               4.28kB / 138B       0B / 0B             1
ce7aea05b590        ubussh1             0.00%               1.078MiB / 16MiB      6.74%               3.71kB / 138B       0B / 0B             1

Ahora conectaremos ambos contenedores a otra red creada manualmente (mi_net), obtendrán los IPs 172.18.0.2 y 3

# docker network connect --link ubussh1:red2 test ubussh2
# docker network connect --link ubussh2:red2 test ubussh1

Verificamos que IPs tienen asignados.

# docker inspect ubussh1
"Name": "/ubussh1",
...
"Networks": {
    "bridge": {
        "IPAddress": "172.17.0.2",
    },
    "test": {
        "Links": [
            "ubussh2:test"
        ],
        "Aliases": [
            "ce7aea05b590"
        ],
        "IPAddress": "172.18.0.2",

El otro contenedor

# docker inspect ubussh2
...
"Networks": {
    "bridge": {
        "IPAddress": "172.17.0.3",
    },
    "test": {
        "IPAMConfig": {},
        "Links": [
            "ubussh1:test"
        ],
        "IPAddress": "172.18.0.3",

También podemos eliminar una de las redes virtuales que hemos creado con

# docker network rm test
Error response from daemon: network test id 428da0f3c44cdb575e0e46afcf162d75dc1d9a1c6b20127020a6f47f6632f641 has active endpoints

Como hay contenedores que la están usando, no nos permite eliminar esa red.

# docker stop ubussh1
# docker stop ubussh2
# docker network rm test

Pero ahora que hemos borrado la red llamada “test”, ambos contenedores no arrancarán correctamente.

# docker start ubussh2
Error response from daemon: No such network: test
Error: failed to start containers: ubussh2
# docker start ubussh1
Error response from daemon: No such network: test
Error: failed to start containers: ubussh1

Ahora ambos contenedores podrán arrancar y se verán por la red standard “bridge”.

# docker network disconnect test ubussh1
# docker network disconnect test ubussh2

# docker start ubussh1
ubussh1

# docker start ubussh2
ubussh2

Existe un comando para eliminar todas las redes que no estén siendo usadas por contenedores. No hay deshacer…

# docker network prune
WARNING! This will remove all networks not used by at least one container.
Are you sure you want to continue? [y/N] n

Subscríbete y recibirás los últimos artículos semanalmente en tu email.