Macvlan Networking

Sometimes, you have a legacy application that demands to be on the physical network. It expects to be on the same subnet as your router, your printer, and your database server. It doesn’t want NAT. It doesn’t want a Bridge.

Enter Macvlan.

1. The Virtual Sub-Interface

Macvlan allows you to assign a MAC address to a container, making it appear as a physical device on your network. The Docker host acts like a switch, forwarding traffic directly to the container based on MAC address.

First Principles: Promiscuous Mode

To make this work, the host’s physical interface (e.g., eth0) must be in promiscuous mode (or support multiple MAC addresses). It must accept packets destined for MAC addresses other than its own.

2. Interactive: Macvlan vs Bridge

See the difference in how the router sees your container.

Router (Gateway)
Router's ARP Table
192.168.1.50 → AA:BB:CC:DD:EE:01 (Host)
192.168.1.51 → ??
Docker Host (192.168.1.50)
Container
IP: 172.17.0.2
Bridge Mode: The router ONLY sees the Host's MAC address. Traffic to the container is NAT'd. The container is hidden behind the host.

3. Configuration

To use Macvlan, you must bind it to a physical interface.

# Create Macvlan network attached to eth0
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  pub_net

# Run container with a specific IP
docker run --net=pub_net --ip=192.168.1.51 -it alpine sh

[!CAUTION] Host Connectivity: By default, the host cannot ping a container on its own macvlan network due to security features in the Linux kernel. You need to create a secondary macvlan interface on the host to bridge this gap.

4. Summary

  • L2 Access: Containers appear as physical devices.
  • Performance: Very high (no NAT).
  • Complexity: Requires promiscuous mode and careful IP management.