jueves, 21 de julio de 2016

REDES EN DOCKER

Las conexiones de los contenedores son creadas utilizando redes. Estas son llamadas “Docker Networking” y fueron introducidas en Docker 1.9. Docker Redes permite que podamos configurar nuestras propias redes a través de las cuales los contenedores pueden comunicarse. Básicamente, esto complementa la red docker0 existente por defecto con nuevas redes gestionadas por el usuario. Es importante destacar que los contenedores pueden comunicarse entre ellos a través del host y la configuración de las redes puede ser totalmente personalizada. Docker Redes también se integra con Docker compose y Swarm.

El soporte de red también es pluggable o enchufable, lo que significa que puede agregar controladores de red para soportar topologías específicas y marcos de redes de proveedores como Cisco y VMware.

Vamos a ver un sencillo ejemplo de cómo utilizar una aplicación web y contenedores. Para utilizar las redes Docker, primero tenemos que crear una red y luego ejecutar el contenedor dentro de esa red.

$ docker network create app
3395f15bf73e310b7ef4330187398a56c87c4b5b278494ec3adb7423578df839

Hemos utilizado el comando docker network para crear una red puente llamada app. Nos devuelve un ID para nuestra red. Entonces podemos inspeccionar esta red utilizando el comando “docker network inspect”.

$ docker network inspect app
[
    {
        "Name": "app",
        "Id": "3395f15bf73e310b7ef4330187398a56c87c4b5b278494ec3adb7423578df839",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {}
            ]
        },
        "Containers": {},
        "Options": {}
    }
]

Podemos ver que nuestra nueva red es una red local, un puente muy similar a nuestra red docker0 y que en la actualidad no hay contenedores ejecutándose dentro de la red.
Además de crear una red de puente que sólo existe en un único host, también podemos crear redes superpuestas (overlay), lo que nos permite abarcar varios host.
Podemos enumerar todas las redes actuales utilizando el comando “docker network ls”.

$ docker network ls
NETWORK ID          NAME                DRIVER
cb1379376867        host                host               
3395f15bf73e        app                 bridge             
bb419a78dd86        bridge              bridge             
b6fa624cb73c        none                null

y también podemos eliminar una red con el comando “docker network rm”.
Vamos a añadir algunos contenedores a nuestra red comenzando por un contenedor mysql

$ docker run --net=app --name mimysql -e MYSQL_ROOT_PASSWORD=clave123 -d mysql

Hemos creado un nuevo contenedor llamado mimysql, usando la imagen por defecto de la última versión de mysql, también hemos especificado un nuevo parámetro –net. El parámetro –net especifica una red para que utilice nuestro contenedor.
Ahora, si volvemos a ejecutar el comando “docker network inspect”, veremos mucha más información:

$ docker network inspect app
[
    {
        "Name": "app",
        "Id": "3395f15bf73e310b7ef4330187398a56c87c4b5b278494ec3adb7423578df839",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {}
            ]
        },
        "Containers": {
            "e995e69fc19cb92d64dd802e59744256bf450685e4738866c77d2283877e1b12": {
                "EndpointID": "3a6c17ad1c30aa00b074d11183f7cfbc7c74c0e45846863391ebb69af78f5f49",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {}
    }
]

Ya, dentro de nuestra red, podemos ver un contenedor con una dirección MAC y una dirección IP, 172.18.0.2.
Ahora vamos a ejecutar un contenedor con una aplicación en la red que acabamos de crear, en este caso, vamos a utilizar la imagen por defecto de wordpress, que está alojada en docker hub.

$ docker run --net=app --name miwordpress -t -i -p 8080:80 wordpress /bin/bash

Hemos ejecutado un contenedor llamado miwordpress dentro de la red app. Hemos ejecutado de forma interactiva para poder mirar dentro lo que está sucediendo. A medida que el contenedor se inicia dentro de la red de aplicaciones, Docker habrá tomado nota de todos los demás contenedores que se ejecutan dentro de esa red y poblará sus direcciones en el DNS local mediante el fichero /etc/hosts. Vamos a verlo dentro del contenedor que acabamos de ejecutar:

root@4f3cdb6d7626:/var/www/html# cat /etc/hosts
172.18.0.3  4f3cdb6d7626
127.0.0.1   localhost
::1   localhost ip6-localhost ip6-loopback
fe00::0     ip6-localnet
ff00::0     ip6-mcastprefix
ff02::1     ip6-allnodes
ff02::2     ip6-allrouters
172.18.0.2  mimysql
172.18.0.2  mimysql.app

Podemos ver que el archivo /etc/hosts contiene la dirección IP del contenedor wordpress y una entrada para localhost. También contiene dos entradas para el contenedor mimysql. La primera entrada, es el nombre de host y la dirección IP del contenedor mimysql, 172.18.0.2. El segundo, añade la red app como un sufijo de dominio para la red. Cualquier host en la red app puede ser resuelto por nombrehost.app, en este caso mimysql.app. Vamos a probarlo:

root@4f3cdb6d7626:/var/www/html# ping mimysql.app
PING mimysql.app (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.113 ms
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.224 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.179 ms

Es importante destacar que si se reinician los contenedores, entonces su información de la dirección IP se actualizará en el archivo /etc/hosts. Esto significa que el cambio de los contenedores subyacentes no tendrá un impacto en el funcionamiento de nuestra aplicación.
Ahora vamos a eliminar nuestro contenedor y ejecutarlo de nuevo como servicio para utilizar nuestro wordpress

$ docker run --net=app --name miwordpress -p 8080:80 -e WORDPRESS_DB_HOST=mimysql:3306 -e WORDPRESS_DB_PASSWORD=clave123 -d wordpress
6042dc762061131c376626c23d5f9c4b0d02cba2e6e3912339c6507415159e4c

y vamos a nuestro navegador para ver si funciona:

Figura 14. Pantalla de instalación de wordpress.
Fuente: Elaboración propia

Y aquí tenemos nuestro sitio wordpress funcionando en menos de un minuto:

Figura 15. Pantalla de wordpress instalado.

Fuente: Elaboración propia

También podemos añadir contenedores que están ya en ejecución a contenedores existentes usando el comando “docker network connect”. Vamos a añadir un contenedor existente a nuestra red app.  Como tenemos un contenedor que se llama web, vamos a conectarlo.

$ docker network connect app web

Ahora vamos a comprobar la red app.

$ docker network inspect app
[
    {
        "Name": "app",
        "Id": "3395f15bf73e310b7ef4330187398a56c87c4b5b278494ec3adb7423578df839",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {}
            ]
        },
        "Containers": {
            "6042dc762061131c376626c23d5f9c4b0d02cba2e6e3912339c6507415159e4c": {
                "EndpointID": "e9e6b25da5ec45926654246398ed69b2dfa1055a4120631deaeba5a0eaf847c5",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "783b2527f17f191b824098b72966534bde9fa06ef907410ef830d54d0623051f": {
                "EndpointID": "fffc03dcb3ccdc82196d2c64c6a59f0993484e3c2e3c68cd3f0d61f7cdc3b065",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            },
            "e995e69fc19cb92d64dd802e59744256bf450685e4738866c77d2283877e1b12": {
                "EndpointID": "3a6c17ad1c30aa00b074d11183f7cfbc7c74c0e45846863391ebb69af78f5f49",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {}
    }
]

El fichero /etc/hosts en todos nuestros contenedores contiene información de DNS local para los contenedores miwordpress, mimysql y web.
También podemos desconectar un contenedor de una red utilizando el comando “docker network disconnect”.

$ docker network disconnect app web

Esto elimina el contenedor web de la red app.

Los contenedores pueden estar en múltiples redes a la vez para poder crear modelos de redes muy complejas.

1 comentario:

  1. Excelente artículo, me ayudo a despejar muchas dudas del uso de redes con docker. Muchas gracias

    ResponderEliminar