red key_value dondocker

Como hacer redes con Docker. Primeros pasos

Como ya hemos comentado Docker crea una interfaz de red propia con el nombre de docker0. Esta red tiene un rango típico: 174.17.0.1/24. Las primeras versiones de Docker presentaban problemas de seguridad o más bien de confiabilidad ya que cualquier contenedor de un host podía tener acceso a cualquier contenedor del mismo.

La versiones más modernas permiten crear distintas subredes y aislar perfectamente grupos de contenedores para no permitir accesos no autorizados.

Tipos de red.

Para mostrar los tipos de red disponibles por defecto en Docker, sólo hay que ejecutar:

>_ docker network ls
NETWORK ID          NAME                DRIVER
eb2291dd0b63        bridge              bridge              
b9e68dd550d4        host                host                
ccc5be97afaf        none                null                

Estas los las distintas redes que tenemos configuradas por defecto en nuestro host.

  • host representa la red del propio equipo y haría referencia a eth0
  • bridge representa la red docker0 y a ella se contectan todos los contendeores por defecto.
  • none significa que el contenedor no se incluye en ninguna red y si verificaramos esto con el comando ifconfig dentro del contenedor veríamos que solo tiene la interfaz de loopback lo.

Bridge en detalle.

Podemos ver en detalle que parametros tiene cada red usando docker network inspect <red>.

>_ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "eb2291dd0b63bce452f37518c1ba4d248568301f9862f58fdc6c6c403779879c",
        "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,
        "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": {}
    }
]

Podemos comprobar como por defecto crear una subred (clase B) que iría desde la 172.17.0.1 a la 172.17.255.254. Pudiendo albergar 65534 contenedores.

Por otro lado vemos como el campo Containers está vacío ya que inicialmente no tenemos ningún contenedor en funcionamiento. Tras crear 2 contenedores veremos lo siguiente:

>_ docker run -itd --name=container1 busybox
d7555b818efc201e4715d1e17bde340eaabf788450d9f83682365efad13a2205
>_ docker run -itd --name=container2 busybox
5450fab33b65f1d4b1446e0464ea6e9084399d5ba71e1b74224a4c1759f96b7b
>_ docker network inspect bridge
[
        ...
        "Internal": false,
        "Containers": {
            "5450fab33b65f1d4b1446e0464ea6e9084399d5ba71e1b74224a4c1759f96b7b": {
                "Name": "container2",
                "EndpointID": "c42d1a88508472e2c12920141216404233abc3fd14c1fb8fb5982fc1aecb863c",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "d7555b818efc201e4715d1e17bde340eaabf788450d9f83682365efad13a2205": {
                "Name": "container1",
                "EndpointID": "52e12690fdf6a6f1f20e95969c7bb7e9339f00e8421b77e2cb7bf4d2ed04d83f",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.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": {}
    }
]

Ahora vemos como tenemos dos contenedores que pertenecen a la red 172.17.0.1/16 cualquiera de los dos puede ver al otro. Incluso si siguiésemos creando más contenedores estos se verían todos con todos.

Entonces, ¿cómo podemos aislar en subredes?

Redes definidas por nosotros.

Para poder aislar contenedores es necesario definir una red para esos contenedores que sea distinta de la red bridge por defecto. Para ello usamos:

>_ docker network create --driver bridge aislada
>_ docker network ls
NETWORK ID          NAME                DRIVER
646b570ec240        aislada             bridge              
eb2291dd0b63        bridge              bridge              
b9e68dd550d4        host                host                
ccc5be97afaf        none                null  

Podemos ver que tenemos una nueva red que vamos a usar para aislar un tercer contenedor. Lo único que tendremos que hacer es definirlo a la hora de crear el contenedor.

>_ docker run --net=aislada -itd --name=container3 busybox 
>_ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
1fe5aaddb049        busybox             "sh"                16 seconds ago      Up 14 seconds                           container3
5450fab33b65        busybox             "sh"                9 minutes ago       Up 9 minutes                            container2
d7555b818efc        busybox             "sh"                9 minutes ago       Up 9 minutes                            container1

Como vemos hay 3 contenedores, dos en la red por defecto y uno en la nueva red.

Dibujo de las dos redes aisladas

Podemos comprobar como desde el contenedor 2 no podemos hacer ping al 3:

>_ docker attach container1
#_ ping -w3 172.18.0.2
--- 172.18.0.2 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss

Esta forma de aislar contenedores nos puede ser útil para pequeñas redes de contenedores todos dentro de un único host. Pero, ¿qué pasa cuando queremos tener más contenedores y nuestro host se queda pequeño?

Necesitamos añadir más hosts y crear una red superpuesta o lo que se llama overlay network.

Redes suprahost o superpuestas

Como ya hemos hablado la red superpuesta sirve para unir varios host de una manera segura utilizando VXLAN. Esta librería permite hacer esto, incluso permite desarrollar nuestros propios drivers.

Para crear una red overlay es imprescindible disponer de un servicio de almacenamiento key-value como Consul , Etcd , o ZooKeeper .

Este servicio se instala en uno de los nodos mientras que en el resto se instala el servicio de Docker.

Host key-value

Estos son los puertos necesarios para usar el servicio de key-value.

Protocolo Puerto Descripción
udp 4789 Nivel de datos (VXLAN)
tcp/udp 7946 Nivel de control

Desde el punto de vista de cada nodo, es necesario configurar el daemon de Docker para que use la red superpuesta. Los parámetros de configuración son los siguientes:

  • –cluster-store=PROVIDER://URL especifica la dirección del servicio key-value
  • –cluster-advertise=HOST_IP|HOST_IFACE:PORT Ip o intefaz del host dentro del cluster
  • –cluster-store-opt=KEY-VALUE OPTIONS diversas opciones como el certificado TLS o los tiempos de búsqueda de nodos.

Para crear la red overlay usamos:

>_ docker network create --driver overlay my-multi-host-network

Y ahora en cada nodo cuando queramos levantar un contenedor tendremos que usar la red definida como overlay.

>_ docker run -itd --net=my-multi-host-network busybox

Para desarrollo de aplicaciones, testing o integración continua nos servirá perfectamente con la redes que vienen creadas por defecto. Sin embargo si queremos definir más de un servicio en un host o tener un enjambre de host para tener un scalamiento horizontal necesitaremos definir este tipo de redes y conviene conocer estas opciones.

En el siguiente post propondremos un ejemplo de desplegar una aplicación multi-host ya que en este se ha tocado el tema un poco por encima y sin un ejemplo practico.

Por otro lado en la página de Docker puedes encontrar más información respecto al uso de las redes docker

Leave a comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *