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,
- Bridge. La red standard que usarán todos los contenedores.
- Host. El contenedor usará el mismo IP del servidor real que tengamos.
- 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