Docker macvlan vs ipvlan: Container Networking - 夜莺博客

Docker macvlan vs ipvlan: Container Networking

Docker's default bridge network is NAT-based, which is fine until a container needs to look like a real device on the wire — an IDS sensor that must see true source addresses, a monitoring box that must answer ARP as itself, or a licence server pinned to a MAC. The macvlan and ipvlan drivers both put containers directly on the LAN segment, and the difference between them decides whether your deployment works on your hardware. This article compares the two drivers on the axes that actually break in production and gives working configurations for each.

The one-line difference and why it drives everything

macvlan gives every container its own MAC address on the parent NIC. ipvlan shares the host's single MAC and varies only the IP. That single design choice cascades: MAC table size on switches, switch port-security behaviour, cloud hypervisor filtering, and whether the host itself can reach the containers.

Creating both networks

docker network create -d macvlan \
  --subnet=192.168.1.0/24 --gateway=192.168.1.1 \
  --ip-range=192.168.1.240/28 \
  -o parent=eth0 macnet

docker run -d --name web1 --network macnet --ip 192.168.1.245 nginx:1.25

docker network create -d ipvlan \
  --subnet=192.168.1.0/24 --gateway=192.168.1.1 \
  --ip-range=192.168.1.240/28 \
  -o parent=eth0 -o ipvlan_mode=l2 ipvnet

docker run -d --name web2 --network ipvnet --ip 192.168.1.246 nginx:1.25

Reserve an address range outside the DHCP pool. An overlapping lease is the most common cause of "intermittent packet loss" that turns out to be a duplicate address, and it presents as a ping that works and then does not.

What stops working

docker run -d --name web1 --network macnet -p 8080:80 --ip 192.168.1.245 nginx:1.25
# Error response from daemon: publish requires containers to run in the default network

Port publishing relies on Docker managing iptables NAT rules. macvlan and ipvlan containers bypass that path by design, so publishing fails — the container is directly on the wire and needs no NAT. Firewalling must therefore happen at the host or on switch ACLs, because these containers are reachable from the LAN with nothing in front of them.

Host-to-container reachability

With macvlan in bridge mode the host cannot reach its own containers. This is kernel behaviour, not a bug: the host's namespace is isolated from the macvlan children it creates. The fix is a shim interface on the same parent NIC.

ip link add mac0 link eth0 type macvlan mode bridge
ip addr add 192.168.1.239/32 dev mac0
ip link set mac0 up
ip route add 192.168.1.240/28 dev mac0

Persist it with a systemd oneshot unit or the equivalent in your network configuration management; a shim that disappears on reboot is worse than none, because monitoring will report the containers as unreachable from the host while they serve traffic perfectly to everyone else.

Choosing between them

  • Need a distinct MAC per container (hardware-pinned licensing, ARP-based probes, multi-tenant L2 isolation) — use macvlan.
  • Switch port-security limits MAC count — use ipvlan L2; macvlan will trip the limit as soon as a second container starts, and the switch will err-disable the port.
  • Running on AWS, Azure or GCP — avoid macvlan. Most cloud SDNs drop frames whose source MAC does not match the vNIC binding, and the failure is silent: no error, no log, just vanished packets. ipvlan works because it reuses the parent MAC.
  • Multi-tenant with no broadcast exposure — ipvlan L3 routes between subnets and removes ARP and broadcast entirely. The trade-off is that DHCP client broadcasts and mDNS stop working, so plan on static addressing.
  • Multi-host — neither driver spans hosts. Use an overlay network instead.

Proxmox and virtualisation notes

If your Docker host is a VM, the bridge must permit multiple MACs. On Proxmox that means enabling MAC spoofing on the virtual NIC — without it the bridge drops macvlan traffic. Bonding the parent interface is strongly recommended; a single parent NIC turns every container network on the host into a single point of failure, which is the same argument that applies to tagged bridges and LACP bonds documented in Proxmox VE VLAN-aware bridge and LACP bond.

For the host bridge these containers depend on, and the packet-level view when traffic does not reach them, see packet-level Linux troubleshooting with ss, netstat and tcpdump.

原文链接:https://dev.to/oleksandr_kuryzhev_42873f/configure-docker-macvlan-and-ipvlan-for-dedicated-lan-ips-2lam