Seguimos con los posts de docker y ahora toca uno sobre el tema de networking.
La necesidad básica es la de publicar a Internet un servidor web con nginx. En lugar de definir la IP pública al servidor docker nos interesa ponerla dentro del contenedor de nginx y luego que él sea el que tenga acceso al resto de máquinas.
El servidor de docker con el que estoy trabajando es una máquina física con debian con una IP de guifi (10.90.234.170) y en el datacenter donde está en la VLAN 138 está el rango de IP públicas (5.10.205.128/27).
Crear la network
Docker por defecto trae 3 networks, por defecto cuando creamos un contenedor nuevo asigna la red bridge (driver bridge) 172.17.0.0/16
root@wezen02:~# docker network ls NETWORK ID NAME DRIVER SCOPE f9e3dcfa1e06 bridge bridge local 262f24ac9f10 host host local c4572142389a none null local
Para crear una nueva red y vincularla a la vlan correspondiente usaremos lo siguiente:
# docker network create -d macvlan -o parent=eno1.138 public
Cuando creamos una nueva red docker le asigna un rango por defecto correlativo al último rango creado, por ejemplo 172.18.0.0/16 pero nos interesa que cuando asignemos ésta network a un contenedor le asigne una IP de nuestro rango público.
# docker network rm public # docker network create -d macvlan -o parent=eno1.138 public --subnet=5.10.205.128/27 --gateway=5.10.205.129 --ip-range 5.10.205.152/29
Con –subnet indicamos la red en la que trabaja la network, –gateway la puerta de enlace de nuestro router e –ip-range el rango que asignará automáticamente a los contenedores cuando los creemos sin especificar ninguna IP.
Asignar la network a un contenedor
Para asignar una network a un contenedor lo podremos hacer de varias formas.
La primera es crear un contenedor con la red por defecto bridge y luego conectarle la red
# docker run -dti --name nginx -p 80:80 --restart=always nginx # docker network connect public nginx
O la otra es asignarle la red al crear el contenedor
# docker run -dti --name nginx -p 80:80 --restart=always --network=public nginx d94856846939bc657cab982b972fe943532eed3803beb40ef35e3241ff2c9d28 # docker exec -ti nginx /bin/bash root@d94856846939:/# ifconfig eth0: flags=4163mtu 1500 inet 5.10.205.152 netmask 255.255.255.224 broadcast 5.10.205.159 ether 02:42:05:0a:cd:98 txqueuelen 0 (Ethernet) RX packets 6639 bytes 9096369 (8.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4618 bytes 370924 (362.2 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 6 bytes 542 (542.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 6 bytes 542 (542.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 root@d94856846939:/# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 5.10.205.129 0.0.0.0 UG 0 0 0 eth0 5.10.205.128 0.0.0.0 255.255.255.224 U 0 0 0 eth0
Tendremos la opción también de definir una IP de forma estática
# docker run -dti --name nginx -p 80:80 --restart=always --network=public --ip 5.10.205.153 nginx 3a3d06e249854dcbb812b3ec755b067eb9ab8a424f2d4dd9f4e1b17dd5c6ed69 # docker exec -ti nginx /bin/bash root@3a3d06e24985:/# ifconfig eth0: flags=4163mtu 1500 inet 5.10.205.153 netmask 255.255.255.224 broadcast 5.10.205.159 ether 02:42:05:0a:cd:98 txqueuelen 0 (Ethernet) RX packets 5907 bytes 9049480 (8.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 4595 bytes 370493 (361.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 6 bytes 542 (542.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 6 bytes 542 (542.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 root@3a3d06e24985:/# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 5.10.205.129 0.0.0.0 UG 0 0 0 eth0 5.10.205.128 0.0.0.0 255.255.255.224 U 0 0 0 eth0
Otros comandos que nos pueden interesar para ésta parte son:
# docker network inspect public # docker inspect nginx # docker inspect nginx |grep 'IPAddress' "SecondaryIPAddresses": null, "IPAddress": "", "IPAddress": "5.10.205.153", # docker inspect nginx |grep 'Gateway' "Gateway": "", "IPv6Gateway": "", "Gateway": "5.10.205.129", "IPv6Gateway": "", # docker inspect nginx |grep 'Port' "PortBindings": { "HostPort": "80" "PublishAllPorts": false, "ExposedPorts": { "Ports": {},
Comentar que gracias al funcionamiento de docker, se podrá resolver desde éste contenedor los otros contenedores por su nombre de contenedor, así que en el caso de éste nginx nos referiremos a los otros contenedores por su nombre de contenedor y no su IP.
Otros links de interés para seguir investigando sobre éste tema:
docker documentation: docker network create
docker documentation: docker network connect
docker documentation: Use macvlan networks
docker documentation: Disable networking for a container
oddbit: USING DOCKER MACVLAN NETWORKS
dockertips: Redes en Docker