Compartir comentarios
Las respuestas se generan en base a la documentación.

Controlador de red Macvlan

Algunas aplicaciones, en especial las heredadas o aquellas que monitorizan el tráfico de red, esperan estar conectadas directamente a la red física. En este tipo de situaciones, puedes utilizar el controlador de red macvlan para asignar una dirección MAC a la interfaz de red virtual de cada contenedor, haciendo que parezca una interfaz de red física conectada directamente a la red física. En este caso, debes designar una interfaz física en tu host de Docker para utilizarla con Macvlan, así como la subred y la puerta de enlace de la red. Incluso puedes aislar tus redes Macvlan utilizando diferentes interfaces de red físicas.

Compatibilidad de plataformas y requisitos

  • El controlador macvlan solo funciona en hosts Linux. No es compatible con Docker Desktop para Mac o Windows, ni con Docker Engine en Windows.
  • La mayoría de los proveedores de la nube bloquean las redes macvlan. Es posible que necesites acceso físico a tus equipos de red.
  • Requiere al menos la versión 3.9 del kernel de Linux (se recomienda la versión 4.0 o posterior).
  • El controlador macvlan no es compatible con el modo rootless (sin privilegios de root).

Consideraciones

  • Podrías degradar involuntariamente tu red debido al agotamiento de direcciones IP o a la "propagación de VLAN" (VLAN spread), una situación que ocurre cuando tienes una cantidad excesivamente alta de direcciones MAC únicas en tu red.
  • Tus equipos de red deben ser capaces de admitir el "modo promiscuo", donde a una sola interfaz física se le pueden asignar múltiples direcciones MAC.
  • Si tu aplicación puede funcionar mediante un bridge (en un solo host de Docker) o una red overlay (para comunicarse a través de múltiples hosts de Docker), estas soluciones podrían ser mejores a largo plazo.
  • Los contenedores conectados a una red macvlan no pueden comunicarse directamente con el host, esto es una restricción del kernel de Linux. Si necesitas comunicación entre el host y los contenedores, puedes conectar los contenedores a una red bridge además de a la red macvlan. También es posible crear una interfaz macvlan en el host con la misma interfaz padre y asignarle una dirección IP en la subred de la red de Docker.

Opciones

La siguiente tabla describe las opciones específicas del controlador que puedes pasar a --opt al crear una red utilizando el controlador macvlan.

OpciónPredeterminadoDescripción
macvlan_modebridgeEstablece el modo Macvlan. Puede ser uno de los siguientes: bridge, vepa, passthru, private
parentEspecifica la interfaz padre (parent) que se utilizará.

Crear una red Macvlan

Al crear una red Macvlan, esta puede estar en modo bridge o en modo bridge troncal 802.1Q.

  • En el modo bridge, el tráfico de Macvlan pasa a través de un dispositivo físico en el host.
  • En el modo bridge troncal 802.1Q, el tráfico pasa a través de una subinterfaz 802.1Q que Docker crea sobre la marcha. Esto te permite controlar el enrutamiento y el filtrado a un nivel más granular.

Modo bridge

Para crear una red macvlan que se conecte mediante un puente con una interfaz de red física determinada, utiliza --driver macvlan con el comando docker network create. También debes especificar la interfaz padre (parent), que es la interfaz por la que pasará físicamente el tráfico en el host de Docker.

$ docker network create -d macvlan \
  --subnet=172.16.86.0/24 \
  --gateway=172.16.86.1 \
  -o parent=eth0 pub_net

Si necesitas excluir direcciones IP para que no se utilicen en la red macvlan, como cuando una dirección IP determinada ya está en uso, utiliza --aux-addresses:

$ docker network create -d macvlan \
  --subnet=192.168.32.0/24 \
  --ip-range=192.168.32.128/25 \
  --gateway=192.168.32.254 \
  --aux-address="mi-router=192.168.32.129" \
  -o parent=eth0 macnet32

Modo bridge troncal 802.1Q

Si especificas un nombre de interfaz parent que incluya un punto, como eth0.50, Docker lo interpretará como una subinterfaz de eth0 y creará la subinterfaz automáticamente.

$ docker network create -d macvlan \
    --subnet=192.168.50.0/24 \
    --gateway=192.168.50.1 \
    -o parent=eth0.50 macvlan50

Utilizar IPvlan en lugar de Macvlan

Una red ipvlan creada con la opción -o ipvlan_mode=l2 es similar a una red macvlan. La diferencia principal es que el controlador ipvlan no asigna una dirección MAC a cada contenedor; la pila de red de capa 2 es compartida por los dispositivos en la red ipvlan. Por lo tanto, los contenedores utilizan la dirección MAC de la interfaz padre.

La red verá menos direcciones MAC y la dirección MAC del host se asociará con la dirección IP de cada contenedor.

La elección del tipo de red depende de tu entorno y tus requisitos. Existen algunas notas sobre las ventajas y desventajas en la documentación del kernel de Linux.

$ docker network create -d ipvlan \
    --subnet=192.168.210.0/24 \
    --gateway=192.168.210.254 \
     -o ipvlan_mode=l2 -o parent=eth0 ipvlan210

Utilizar IPv6

Si has configurado el daemon de Docker para permitir IPv6, puedes utilizar redes macvlan de doble pila IPv4/IPv6.

$ docker network create -d macvlan \
    --subnet=192.168.216.0/24 --subnet=192.168.218.0/24 \
    --gateway=192.168.216.1 --gateway=192.168.218.1 \
    --subnet=2001:db8:abc8::/64 --gateway=2001:db8:abc8::10 \
     -o parent=eth0.218 \
     -o macvlan_mode=bridge macvlan216

Ejemplos de uso

Esta sección proporciona ejemplos prácticos para trabajar con redes macvlan, incluyendo el modo bridge y el modo bridge troncal 802.1Q.

Note

Estos ejemplos asumen que tu interfaz Ethernet es eth0. Si tu dispositivo tiene un nombre diferente, utiliza ese en su lugar.

Ejemplo de modo bridge

En el modo bridge, tu tráfico fluye a través de eth0 y Docker enruta el tráfico a tu contenedor utilizando su dirección MAC. Para los dispositivos en tu red, tu contenedor parecerá estar físicamente conectado a la red.

  1. Crea una red macvlan llamada mi-macvlan-net. Modifica los valores de subnet, gateway y parent para que coincidan con tu entorno:

    $ docker network create -d macvlan \
      --subnet=172.16.86.0/24 \
      --gateway=172.16.86.1 \
      -o parent=eth0 \
      mi-macvlan-net
    

    Verifica que la red se haya creado:

    $ docker network ls
    $ docker network inspect mi-macvlan-net
    
  2. Inicia un contenedor alpine y conéctalo a la red mi-macvlan-net. Los flags -dit inician el contenedor en segundo plano. El flag --rm elimina el contenedor cuando este se detiene:

    $ docker run --rm -dit \
      --network my-macvlan-net \
      --name my-macvlan-alpine \
      alpine:latest \
      ash
    
  3. Inspecciona el contenedor y observa la clave MacAddress dentro de la sección Networks:

    $ docker container inspect my-macvlan-alpine
    

    Busca una salida similar a:

    "Networks": {
      "my-macvlan-net": {
        "Gateway": "172.16.86.1",
        "IPAddress": "172.16.86.2",
        "IPPrefixLen": 24,
        "MacAddress": "02:42:ac:10:56:02",
        ...
      }
    }
  4. Comprueba cómo ve el contenedor sus propias interfaces de red:

    $ docker exec my-macvlan-alpine ip addr show eth0
    
    9: eth0@tunl0: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:10:56:02 brd ff:ff:ff:ff:ff:ff
    inet 172.16.86.2/24 brd 172.16.86.255 scope global eth0
       valid_lft forever preferred_lft forever
    

    Comprueba la tabla de enrutamiento:

    $ docker exec my-macvlan-alpine ip route
    
    default via 172.16.86.1 dev eth0
    172.16.86.0/24 dev eth0 scope link  src 172.16.86.2
    
  5. Detén el contenedor (Docker lo eliminará automáticamente) y elimina la red:

    $ docker container stop my-macvlan-alpine
    $ docker network rm mi-macvlan-net
    

Ejemplo de modo bridge troncal 802.1Q

En el modo bridge troncal 802.1Q, tu tráfico fluye a través de una subinterfaz de eth0 (llamada eth0.10) y Docker enruta el tráfico a tu contenedor utilizando su dirección MAC. Para los dispositivos de red de tu red, el contenedor parecerá estar físicamente conectado a la red.

  1. Crea una red macvlan llamada mi-8021q-macvlan-net. Modifica los valores de subnet, gateway y parent para que coincidan con tu entorno:

    $ docker network create -d macvlan \
      --subnet=172.16.86.0/24 \
      --gateway=172.16.86.1 \
      -o parent=eth0.10 \
      mi-8021q-macvlan-net
    

    Verifica que la red se haya creado y tenga como padre eth0.10. Puedes usar ip addr show en el host de Docker para verificar que la interfaz eth0.10 existe:

    $ docker network ls
    $ docker network inspect mi-8021q-macvlan-net
    
  2. Inicia un contenedor alpine y conéctalo a la red mi-8021q-macvlan-net:

    $ docker run --rm -itd \
      --network mi-8021q-macvlan-net \
      --name my-second-macvlan-alpine \
      alpine:latest \
      ash
    
  3. Inspecciona el contenedor y observa la clave MacAddress:

    $ docker container inspect my-second-macvlan-alpine
    

    Busca la sección Networks con la dirección MAC.

  4. Comprueba cómo ve el contenedor sus propias interfaces de red:

    $ docker exec my-second-macvlan-alpine ip addr show eth0
    
    11: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:10:56:02 brd ff:ff:ff:ff:ff:ff
    inet 172.16.86.2/24 brd 172.16.86.255 scope global eth0
       valid_lft forever preferred_lft forever
    

    Comprueba la tabla de enrutamiento:

    $ docker exec my-second-macvlan-alpine ip route
    
    default via 172.16.86.1 dev eth0
    172.16.86.0/24 dev eth0 scope link  src 172.16.86.2
    
  5. Detén el contenedor y elimina la red:

    $ docker container stop my-second-macvlan-alpine
    $ docker network rm mi-8021q-macvlan-net