Docker – Networking y comandos básicos
Todo sistema informático necesita tener conectividad con otros sistemas de donde pueda tomar datos y hacia donde pueda brindar sus servicios. Los contenedores son sistemas «encapsulados», por decirlo de algún modo simple, pero no por eso deben quedar desconectados de otros sistemas ya sean físicos, virtuales o en contenedores. Es por ello que Docker brinda un buen manejo en redes de datos. En el presente artículo se mostrará cómo se configuran las redes de datos en contenedores Docker.
Índice de artículo
Tipos de redes
Primero debemos mencionar que al momento de instalar el Docker Engine en un sistema host, se crean automáticamente 3 redes denominadas «none«, «host» y «bridge«.
La red «none» es una red donde el contenedor no tiene otra interfaz de red que la de localhost.
La red «bridge» es la red por defecto de docker y todos los contenedores creados pertenecerán a esta red si es que no se especifica alguna otra. Es la que utiliza la red configurada en la interfaz docker0 del servidor donde se encuentra instalado docker.
La red «host» es utilizada por contenedores que no se aíslan de la máquina host donde se encuentra instalado docker. Esto significa que toma todas las interfaces de red configuradas en la máquina host. Por lo tanto, si el contenedor tiene un servicio en el puerto 80, la máquina host brindará ese servicio.
El comando docker que maneja la configuración de red es «docker network
«.
Para listar las redes configuradas y disponibles en un host se debe ejecutar el comando «docker network ls
«.
Todas las configuraciones de los contenedores docker se guardan en archivos del tipo JSON. Y el comando para poder leer los archivos de configuración de una red creada en docker se debe ejecutar el comando «docker network inspect nombre_de_red
«.
La salida de la red bridge va a ser similar a la siguiente.
dcalbo@dcalbo-NTB ~ $ docker network inspect bridge [ { "Name": "bridge", "Id": "de180f3be6a5a710bdf9b81a2c5f3f8b9d9f9927fa333da222db0b2d69c7315c", "Created": "2017-06-12T18:59:46.947780708-03:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "Containers": { "28db43f2b175372040822b5e2caecf7ffb041508b4fa1d144de6c1d74b19e326": { "Name": "bridge2", "EndpointID": "d89ad9c9cccb493ea6937f59d8ffc892c170ae1ca21b432e2f1be05243408903", "MacAddress": "02:42:ac:12:00:03", "IPv4Address": "172.18.0.3/16", "IPv6Address": "" }, "66f828b6084cf620c8255f8e9fa23b02c4cbd13d139cc04909c0953aff21d436": { "Name": "bridge1", "EndpointID": "6477bdcdb14ef7c4dcd350593f00d42d48c40111ef8b6712e5ddbb609ad8a1e1", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" } }, "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": {} } ]
Crear redes
Podemos crear nuestro propia red para el fin que necesitemos, por ejemplo tener una subred en una DMZ (Zona Desmilitarizada) para un server de base de datos que brinda servicio a un sitio web que se encuentra en una red pública. El comando para crear redes en docker es «docker network create --subnet 10.10.1.0/24 nombre_red
«.
dcalbo@dcalbo-NTB ~ $ docker network ls NETWORK ID NAME DRIVER SCOPE 1c059d3b5765 bridge bridge local 57629dace93c dmz bridge local 79eecea4ae70 host host local 3a6376494e97 none null local
Conectar redes
Con el comando «docker network connect nombre_red nombre_container
» se puede conectar en caliente un contenedor a una red disponible.
Luego de conectar un contenedor a una red, podremos ver su configuración inspeccionando la configuración del contenedor.
dcalbo@dcalbo-NTB ~ $ docker inspect bridge1 [ {... "Config": { "Hostname": "bridge1", ... }, "NetworkSettings": { ... "Gateway": "172.18.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.18.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:12:00:02", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "1c059d3b5765055cc4ae72f97e8851957aa1605b0f6c46439f8defae7aa47f46", "EndpointID": "0768462d1671569bfbe1381410c5da5100916e0abd30aca305d059a2d66a9b5b", "Gateway": "172.18.0.1", "IPAddress": "172.18.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:12:00:02" }, "dmz": { "IPAMConfig": {}, "Links": null, "Aliases": [ "e5876ce09b33" ], "NetworkID": "57629dace93c808aa05b27a572f4b82538f448216e4a3781416374a528aef58c", "EndpointID": "7fe74b8e4349e08195befa2d159e1e34a1a9c94bbbd95d065cf967421d496d26", "Gateway": "10.10.1.254", "IPAddress": "10.10.1.1", "IPPrefixLen": 24, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:0a:0a:01:01" } ... } ]
Exponer puertos
Al crear un contenedor se puede exponer los puertos en los que dará servicio. Esto es solamente a modo informativo para la configuración lo cual indica que esos puertos estarán disponibles en el contenedor, pero no indica que esos puertos estarán respondiendo peticiones de servicio. El comando para exponer puertos es «docker run -itd --expose 80 --expose 443 --name nombre_contenedor nombre_imagen
«.
Para poder verificar la configuración de un contenedor y ver su archivo JSON se utiliza el comando «docker inspect nombre_contenedor
«.
dcalbo@dcalbo-NTB ~ $ docker inspect web [ ... "NetworkSettings": { ... "Ports": { "443/tcp": null, "80/tcp": null }, ... } } ]
Publicar puertos
Para que un puerto responda a peticiones en un servidor, se lo debe publicar. Para esto se debe utilizar la variable «-p» al crear un contenedor. Existen 3 formas de publicar un puerto.
La primera es con el comando «docker run -itd -p 80 nombre_imagen
«. De este modo el puerto 80 del contenedor estará respondiendo en un puerto aleatorio de la máquina host.
El comando para verificar los puertos que se encuentran publicados en un contenedor es «docker port ID/nombre_imagen
»
dcalbo@dcalbo-NTB ~ $ docker port random 80/tcp -> 0.0.0.0:32768
El segundo método es con el comando «docker run -itd -p 8080:80 nombre_imagen
«. De este modo el puerto 80 del contenedor estará publicado en el puero 8080 de la máquina host. Es así que podemos determinar de un modo arbitrario el puerto de la máquina host que estará respondiendo al puerto del contenedor.
Si deseamos conocer si un puerto en particular de un contenedor se encuentra publicado, podemos especificar el puerto con el comando «docker port nombre_imagen Puerto
«.
dcalbo@dcalbo-NTB ~ $ docker port web80 80 0.0.0.0:8080
En esta tercera opción todos los puertos expuestos en el contenedor serán publicados en puertos aleatorios de la máquina host. El comando es «docker run -itd -P nombre_imagen
«.
Podemos ver los puertos asignados con el comando «docker port nombre_imagen
» o inspeccionando la configuración del contenedor.
dcalbo@dcalbo-NTB ~ $ docker inspect sshweb [ ... "NetworkSettings": { ... "Ports": { "22/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "32770" } ], "443/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "32769" } ] }, ... ]
Linkear contenedores
Cuando se crea un nodo de contenedores es necesario que esos contenedores puedan conectarse entre sí por IP o por nombre de host. Pero como ya se dijo, si un contenedor se apaga al iniciarse nuevamente se generan nuevos parámetros como el ID y la IP que utiliza.
Para poder salvar este problema, existe la funcionalidad de «linkear«, enlazar, uno o más contenedores que permitirá que cada vez que uno de los contenedores enlazados se apague y se encienda, no importe la IP que el motor docker le asigne ya que se conectarán por el nombre de contenedor. Toda la magia necesaria la realiza el motor docker, como por ejemplo las reglas de ruteo, las reglas dns, etc.
Para poder enlazar contenedores se debe utilizar la variable «–link» al crear un contenedor con el comando «docker run -itd --link ID/contenedor01 --name contenedor01 -h contenedor02 debian
«.
En el siguiente video se muestra de manera práctica lo dicho en el presente artículo.
Recuerden comentar y compartir sus experiencias para poder incrementar el conocimiento de cada uno de nosotros.
Enlace útiles
Docker: www.docker.com
Twitter: @ApuntesIT
Youtube: https://www.youtube.com/channel/UCh_k8K1wP31GfOFdYJj5Eeg
Dailymotion: http://www.dailymotion.com/apuntesit
Trabajando desde el año 1990 en el mercado de la tecnología. Técnico en Electrónica. Administrador de Sistemas. Administrador de Redes. Técnico en telecomunicaciones. Técnico de plataforma satelital. Incursiono en el Software Libre desde mediados del 1997. Desde entonces utilicé varias distribuciones GNU/Linux comenzando con un RedHat 5.0
Formé parte del Core Team y miembro del grupo de desarrollo del Proyecto UTUTO.