Redes en Docker

Siguiendo con las entradas relacionadas con Docker en esta ocasión vamos a tratar la gestión de redes.

Tipos de redes

En docker existen distintos tipos de redes, las cuales se interconectan utilizando lo que se conoce como drivers. Los distintos tipos de drivers que podemos utilizar son:

  • Bridge: Es el driver por defecto y está destinado a aplicaciones que corren en contenedores independientes que necesitan comunicarse entre ellos. Cada contenedor tendrá su propia red que será independiente a la del host donde residen.
  • Host: Se utiliza también para contenedores independientes pero al contrario que con el driver Bridge en esta ocasión eliminamos el aislamiento entre el contenedor y el host utilizando por tanto ambos el mismo direccionamiento IP.
  • Overlay: Es una red virtual que se ejecuta a su vez sobre otra red, para que me entendéis es algo parecido a la creación de VLAN en una red física, y se utiliza principalmente con el modo Swarm.
  • Macvlan: Este driver permite asignar una dirección MAC a un contenedor consiguiendo que éste simule ser un host físico en la red.
  • None: Este modo es el que se especifica cuando un contenedor tiene deshabilitada todas las redes.

En esta entrada me voy a centrar en enseñaros el uso del driver Bridge y más adelante, en otra entrada, os explicaré el uso del driver Overlay ya que estos son los más utilizados.

Creación de una red utilizando el driver Bridge

Para este ejemplo vamos a crear lo siguiente:

  • Dos subredes independientes.
  • Dos contenedores creados a partir de la imagen oficial ubuntu:lastest aunque personalizada por mi para incluir el comando ping. Sino sabes como personalizarla te recomiendo te pases por esta entrada donde explico como hacerlo.

Creación nuevas subredes

Vamos a crear 2 subredes independientes 192.168.10.0/24 y 192.168.20.0/24 a las cuales denominaremos Red10 y Red20 respectivamente.

[root@localhost sergio.portillo]# docker network create --driver bridge --subnet=192.168.10.0/24 --ip-range=192.168.10.0/24 Red10
50664340effe9789dd1400d83271a5439ea3a25aefb972ec30065022b1843f48
[root@localhost sergio.portillo]# docker network create --driver bridge --subnet=192.168.20.0/24 --ip-range=192.168.20.0/24 Red20
7f1658b0761878550f2fcd6c927f06c31efb5129db2697f7d225d93b15aabe5d

Comprobamos que efectivamente existen nuestras 2 nuevas subredes.

[root@localhost sergio.portillo]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
50664340effe        Red10               bridge              local
7f1658b07618        Red20               bridge              local
b845414fde6a        bridge              bridge              local
cd05e2059b23        host                host                local
8211b5098575        none                null                local

Creación de contenedores

Una vez hemos creado las subredes el siguiente paso será crear los contenedores.

Serán 2 contenedores al que uno le llamaremos Ubuntu10 y le asignaremos la subred Red10 y al otro le llamaremos Ubuntu20 y le asignaremos la subred Red 20, los crearemos en modo interactivo (-it) y en segundo plano (-d)

[root@localhost sergio.portillo]# docker container run -itd --name Ubuntu10 --network Red10 tutorialesit/ubuntu-ip-nano
26375289a798cced6e0bdb0e819e1877d67ff84450dda63ac1744a67bc4013d1
[root@localhost sergio.portillo]# docker container run -itd --name Ubuntu20 --network Red20 tutorialesit/ubuntu-ip-nano
85aeebb8778ee49ab0d0805278eac896098a24fa9d3bdb88aebda004405e0542

Comprobamos que ambos contenedores se encuentran levantados.

[root@localhost sergio.portillo]# docker ps
CONTAINER ID        IMAGE                         COMMAND             CREATED             STATUS              PORTS               NAMES
85aeebb8778e        tutorialesit/ubuntu-ip-nano   "/bin/bash"         17 seconds ago      Up 16 seconds                           Ubuntu20
26375289a798        tutorialesit/ubuntu-ip-nano   "/bin/bash"         45 seconds ago      Up 42 seconds                           Ubuntu10

Y que tienen asignadas sus redes correspondientes, es decir, el contenedor Ubuntu10 debe tener asignada la subred Red10 y el contenedor Ubuntu 20 debe tener asignada la subred Red20.

[root@localhost sergio.portillo]# docker container inspect Ubuntu10
....
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "83ea7fb09e0447467e2e9e09f21d217fb337991e01961c7de2681daf1c909049",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/83ea7fb09e04",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "Red10": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "e90279460e98"
                    ],
                    "NetworkID": "91ab905a30ebd1f128f4fbec8f6202f20e4f542ccafaee69d8e251984480154c",
                    "EndpointID": "a3cbd1ac5fa8a0b597154e62024f8e93142ddc0476db2bf08d2b5fafb4b2cc9b",
                    "Gateway": "192.168.10.1",
                    "IPAddress": "192.168.10.2",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:c0:a9:0a:02",
                    "DriverOpts": null
                }
[root@localhost sergio.portillo]# docker container inspect Ubuntu20
...
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "076e0b9c8b08e1d0ebe17b50e88e594a17de2ab08915d223679cd7e728b4e842",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/076e0b9c8b08",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "Red20": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "058c3c3529bd"
                    ],
                    "NetworkID": "97af351f089af1089b9c3922b70a38963d498ecca86ccc6e06584c3ea077c21a",
                    "EndpointID": "f241b42766c1e83d8b2fb001dd9ae07944f619062bcbf4af2b77c60a5c8787f8",
                    "Gateway": "192.168.20.1",
                    "IPAddress": "192.168.20.2",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:c0:a9:14:02",
                    "DriverOpts": null
                }

Como podéis observar la primera IP de cada rango corresponderá con la puerta de enlace que utilizarán nuestros contenedores.

Comprobación conectividad

Vamos a comprobar que ambos contenedores tienen conectividad entre los miembros de su propia subred pero no pueden verse entre ellos al encontrarse en subredes distintas.

Comprobación contenedor Ubuntu10

Nos conectamos a la consola del contenedor y lanzamos un ping a la puerta de enlace de ambas subredes (10 y 20) y vemos que tenemos respuesta:

[root@localhost sergio.portillo]# docker exec -it Ubuntu10 bash
root@af3de69c1a06:/# ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.116 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.173 ms
64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=0.073 ms
64 bytes from 192.168.10.1: icmp_seq=4 ttl=64 time=0.197 ms
^C
--- 192.168.10.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3112ms
rtt min/avg/max/mdev = 0.073/0.139/0.197/0.048 ms

root@af3de69c1a06:/# ping 192.168.20.1
PING 192.168.20.1 (192.168.20.1) 56(84) bytes of data.
64 bytes from 192.168.20.1: icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from 192.168.20.1: icmp_seq=2 ttl=64 time=0.172 ms
64 bytes from 192.168.20.1: icmp_seq=3 ttl=64 time=0.228 ms
64 bytes from 192.168.20.1: icmp_seq=4 ttl=64 time=0.313 ms
^C
--- 192.168.20.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3108ms
rtt min/avg/max/mdev = 0.088/0.200/0.313/0.081 ms


En cambio si lanzamos un ping a la IP de nuestro contenedor que se encuentra en la subred 20 podremos comprobar que no tenemos acceso confirmando así que los contenedores de ambas subredes no son accesibles entre ellos:

root@af3de69c1a06:/# ping 192.168.20.2
PING 192.168.20.2 (192.168.20.2) 56(84) bytes of data.
^C
--- 192.168.20.2 ping statistics ---
9 packets transmitted, 0 received, 100% packet loss, time 8179ms

Espero os haya sido de utilidad.

Entradas relacionadas

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.