The Ultimate 2024 Docker VLAN Guide and Tutorial You’ll Ever Need

Today, containers are everywhere from large scale production networks down to small home labs. In docker networking, two of the more advanced options for connecting containers to external networks are the macvlan and ipvlan drivers (docker VLANs). These drivers allow containers to directly connect to a network, almost as if they were separate physical devices. While they’re powerful tools, understanding when to use macvlan or ipvlan can be a bit confusing – especially since ipvlan has both Layer 2 (L2) and Layer 3 (L3) modes, offering different ways to handle IPs and routing.

This guide dives into the key differences between macvlan and ipvlan, including how they manage MAC addresses, isolate broadcasts, and configure routes. You’ll also find step-by-step tutorials on setting up each driver in a real-world scenario with a Docker host and a VLAN subnet. The goal is to make sure these Docker containers are reachable by other devices on the host’s network and also have access to the host’s network resources.

By the end of this article, you’ll be able to choose the best vlan network driver for your needs – whether you’re running a home lab or a production environment. Additionally, I’ve included a troubleshooting section you might want to consult if you’re having trouble with docker’s vlan drivers.

In the past I’ve already written a shorter article on how to configure a docker macvlan.

Contents

Wait, Layer what?

In computer networks, Layer 2 (L2) and Layer 3 (L3) refer to specific layers in the OSI model, which organizes network functions into seven distinct layers. L2, the data link layer, is responsible for direct data transfer between devices on the same local network. It uses MAC (Media Access Control, basically the “physical” address of your network adapter) addresses to identify devices and works within a single broadcast domain. Think of an L2 network as a local network or VLAN where every device can connect as if they’re on the same physical switch—no need for routing.

Layer 3 (L3), on the other hand, is where routing happens. L3 networks use IP addresses to direct data between different networks or subnets, allowing traffic to travel beyond a single local network. Routers operating at L3 handle things like IP addressing and subnetting, ensuring data finds its way across complex networks. This setup is key for managing communication between distinct network segments, giving you more control over traffic flow and security.

We don’t really care about the other layers of the stack in this article, I’ve only included them for context.

Overview of docker’s macvlan and ipvlan Drivers

In docker, L2 and L3 come into play through the macvlan and ipvlan drivers, which most people in the beginning are not aware of. When setting up Docker networks, most people start with the default NAT setup, which works fine for many things. But sometimes, you want containers to act as if they’re fully part of the host’s network. Say, you’re deploying multiple containers that run webUIs on port 80.

You could now start juggling ports around. At a certain point I start to get lost in port numbers. This is where Docker’s macvlan and ipvlan drivers come in. The macvlan driver operates at L2, giving each container its own MAC address and allowing it to act like an independent device on the host’s network.

While both drivers help achieve to make containers look like independent devices on the host’s network, macvlan and ipvlan have their own quirks and strengths. The trick is knowing when to use each and how they work differently – especially since ipvlan supports both L2 and L3 modes, giving it added flexibility.

macvlan Overview

The macvlan driver’s idea is creating separate MAC addresses for each container, making them look like individual devices on the network. Think of it as cloning the host’s network interface and giving each container its own unique MAC address. This setup works really well for situations where containers need to communicate with other devices directly, as if they were plugged into the same switch.

One thing to keep in mind, though, is that macvlan isolates containers from the host itself, meaning they can’t communicate directly with the host’s main interface unless you add extra routing. The tutorial part will also show you how to get host communication back again in a minute or so. But if your goal is to have containers interact with other devices on the network, macvlan is the go-to choice. It’s especially handy in environments that need each container to have its own MAC address, like older networks that rely on MAC-based filtering.

Advantages and Limitations of macvlan

Advantages:

  • Each container has its own MAC address, making them easily identifiable on the network.
  • Containers communicate directly with other devices on the same network, great for L2 setups.
  • Ideal for setups that need individual MAC addresses or MAC-based filtering.

Limitations:

  • Containers can’t talk directly to the host without additional setup.
  • Some network setups might struggle with a lot of MAC addresses, which could limit scalability.

ipvlan Overview

The ipvlan driver is a bit different and, in some ways, more flexible. It offers two modes:

  1. Layer 2 mode
  2. Layer 3 mode

In L2 mode, ipvlan is like macvlan but skips the unique MAC addresses. Instead, all containers share the same MAC address as the host, using IP aliases instead. This can be really helpful in larger networks where managing tons of MAC addresses could become a headache. That’s usually not the case in home networks, but worth noting at this point.

Then there’s L3 mode, which is where ipvlan really stands out. In L3 mode, each docker network gets its own subnet and relies on IP-based routing to connect with external networks. Rather than handling communication at the MAC level, L3 mode manages traffic at the IP level, making it perfect for setups that need a bit more control over traffic flow and network segmentation. It does require some extra routing configuration, though, so it’s best suited for scenarios where you’re comfortable setting up IP routes. To use L3 mode of the ipvlan driver you should definitely have some experience using iptables. Again, in both L2 and L3 mode of the ipvlan driver, container-host communication has to be set up separately.

Advantages and Limitations of ipvlan

Advantages:

  • L2 mode reduces MAC address management, keeping things simpler on networks with MAC constraints.
  • L3 mode allows for IP-based isolation, ideal for controlling traffic and network segments.
  • Works well in setups that don’t require each container to have a unique MAC address.

Limitations:

  • Containers can’t communicate directly with the host due to the ipvlan isolation design.
  • L3 mode can be a bit more complex to set up since it requires configuring IP routing.

Key Differences Between macvlan and ipvlan

While both macvlan and ipvlan can connect containers to a host’s network, they do so in different ways. This impacts how containers communicate with each other, the host, and other devices on the network. We talked about the advantages and limitations of both drivers already. Now let’s look at the main differences, which will help clarify when to choose one over the other.

Network Layers (L2 vs. L3)

The core difference between macvlan and ipvlan is the network layer they operate on. macvlan is an L2 network driver, meaning it assigns each container its own unique MAC address. This allows the container to act like a separate device at the data link layer, which is why macvlan is ideal for simple, local network communication.

ipvlan, on the other hand, can operate at either L2 or L3, so it’s a bit more versatile. In L2 mode, it behaves similarly to macvlan, but without assigning unique MAC addresses to each container. In L3 mode, ipvlan operates at the IP (so, Layer 3 of the OSI model) level rather than the MAC(Layer 2) level, meaning traffic is routed based on IPs rather than MAC addresses. This L3 approach offers more options for network segmentation and traffic control, but also requires setting up IP routing, which can be a whole other can of worms.

MAC Address Assignment

macvlan assigns each container its own MAC address, so it’s perfect for environments that need each device to have a unique (hardware) identity on the network. This is the case for example for networks with MAC-based filtering or setups that expect a unique MAC for each device. A more common service that needs individual MAC addresses for identification is DHCP. Other examples of common services that need individual MAC addresses to function correctly include wake-on-LAN, discovery services like Bonjour, some IoT devices or security cameras.

In contrast, ipvlan shares the host’s MAC address across all containers. This reduces MAC address complexity, which can be an advantage on networks with MAC address limits. Or, if you simply don’t care if the container has an individual MAC address and your routing doesn’t require it. However, this also means containers are not distinguishable at the MAC level, which may not be ideal if unique MACs are needed for network management. If your containers have static IPs and also don’t use DHCP you usually do not need this for networks at home.

Broadcast and Network Isolation

Because macvlan works at L2, containers can send and receive broadcast traffic. This can be useful when containers need to discover each other on the network, such as with certain services that rely on broadcast communication. As mentioned earlier, Bonjour or DHCP do rely on this. However, macvlan also isolates containers from the host network by default, so they can’t directly access the host interface without extra routing (which is quite easy and we’ll get into later).

ipvlan is a bit different here: in both L2 and L3 modes, it inherently isolates container traffic from the host interface. L2 mode allows for some broadcast communication within the ipvlan network, but L3 mode doesn’t handle broadcasts at all—traffic between containers relies solely on IP routing. This makes L3 mode useful for setups where you want strict control over which networks can interact in which way.

Routing and Gateway Configuration

Routing configuration is another key difference. macvlan typically requires minimal routing setup for simple L2 communication, since each container has a unique MAC address on the network. Again, if you want containers to communicate directly with the host, you’ll need to add specific routes. It’s very simple and needs to be done once only.

With ipvlan in L3 mode, more complex routing is often needed. It’s also only a one time things, but here you should know what you’re doing, because the effort is a bit higher and usually there isn’t much of a “one size fits all” solution to this. Each container is on its own subnet, so IP routes must be configured to ensure that traffic can flow between these subnets and the main network. This makes ipvlan L3 mode ideal for setups that need traffic segmentation but also requires a bit more network know-how.

When to use which driver?

So, when should you use which driver now? I think the choice is basically boils down to a few question. I’ve made a small cheat sheet. If you want the PDF, I’ll put a link at the end of the article.

Let’s quickly go through the decision tree.

Access to the host’s network necessary?

There might be cases where you don’t even need access to the host’s network from inside the container. Or cases where the NAT docker provides per default is enough. This likely isn’t the case for you when you’re reading this 😊 But still, sometimes it’s overlooked so I kept it in here.

Is L2 communication needed?

Essentially, do you have any service(s) inside the container that rely on having a unique MAC Layer 2 identity? Unless you’re running a DHCP server or network discovery services inside your containers, this should not be the case. But, maybe you simply cannot to put your network interface into promiscuous mode? This definitely is a requirement for the macvlan driver.

Are there L2 limitations?

There may be scenarios where you only have a limited amount of MAC addresses available for your network or you cannot have a network device in promiscuous mode. In these settings ipvlan L3 is your goto choice, since everything is handled on L3 without any requirements for L2.


Detailed tutorials

For all of the following tutorials, we assume the following setting (where it applies):

  • Debian 12 or later based distribution
  • Network: 192.168.178.0/24
  • Gateway’s IP: 192.168.178.1
  • Docker host’s IP: 192.168.178.10
  • Container subnet: 192.168.178.16/28
  • Container subnet for ipvlan L3: 192.168.177.0/24
  • Shim’s IP: 192.168.178.15
  • Host interface device name is enp0s3

This should be a pretty typical home or small office network setup. The containers will be put into the subnet 192.168.178.16/28 (which covers the IP range .16 through .31). That should be enough for most setups. The “Shim” will have the IP ending in .15. The “Shim” is the network bridge that will the container-host communication. This means that the IPs .11 through .14 can be used for VMs or other things if you want and you still have everything in a neat IP address block. Make sure to adapt these settings to your scenario if necessary. Most if not everything will work for distributions other than debian 12 or newer, too.

As long as the network configuration is ifup/ifdown based, everything here should work for you. Let’s look at how we set up the prerequisites for the vlan drivers.

For all tutorials, make sure that you have IP forwarding enabled

sysctl -w net.ipv4.ip_forward=1

You need to enable this after every reboot. For testing that surely is ok. But for a production system we want this to be on permanently. To make this permanent on debian based distributions follow these steps:

  1. Open the file /etc/sysctl.conf and find the following (usually commented) line:
#net.ipv4.ip_forward=1
  1. Uncomment (remove the preceeding #) the line
  2. Save the changes and reload the services
sysctl -p /etc/sysctl.conf1
/etc/init.d/procps restart

Setup Tutorial: macvlan Configuration

This setup will allow containers to appear as separate devices on the network, each with its own MAC address and IP, so they can communicate directly with other network devices.

Preparations

In order for a network card to listen to multiple MAC addresses, you need to enable promiscuous mode for this interface. Check if promiscuous mode is on with the ip command:

ip -d link

This will output something similar to the image below. In this case the interface enp0s3 has promiscuity 1, which means it already is in promiscuous mode.

In case it says promiscuity 0, enable it by calling

ip link set enp0s3 promisc on

This is not permanent yet, you’d need to enable it after each reboot. We’ll make it permanent later.

Docker macvlan Network Creation

With macvlan, we’ll create a new network interface for each container that connects it directly to the host’s network. Let’s set up this macvlan network in Docker:

docker network create -d macvlan \
   --subnet=192.168.178.0/24 \
   --ip-range=192.168.178.16/28 \
   --gateway=192.168.178.1 \
   -o parent=enp0s3 \
   macvlan_net

Explanation:

  • -d macvlan: Specifies the driver as macvlan.
  • --subnet=192.168.178.0/24: Assigns the macvlan network the specified subnet within the main network.
  • --ip-range=192.168.178.16/28: IP address range docker’s DHCP will supply to the containers.
  • --gateway=192.168.178.1: Sets the network gateway, typically your router.
  • -o parent=enp0s3: Links the macvlan network to the host’s physical network interface.

Container Creation and IP Assignment in macvlan

Now we can launch containers that use the new macvlan network. Each container will be assigned an IP within the .16 - .31 range, which allows them to be addressed individually on the main network.

To launch a container with a specific IP on the macvlan_net network run the following command:

docker run -it --rm --network macvlan_net --ip 192.168.178.16 alpine sh

This command starts an Alpine container with the IP 192.168.178.16. You can substitute the IP .16 with any available IP in the .16 - .31 range. If you leave it empty, docker’s DHCP server will supply a IP within the range specified during network creation to the container.

Testing Network Connectivity with macvlan

After setting up the macvlan network and starting containers, let’s test connectivity to confirm that they can communicate with the host’s network and other devices.

  • Router and Other Network Devices: From within the container, try pinging the router (192.168.178.1) to confirm external network connectivity:
ping 192.168.178.1
  • Host: Try to ping the host (192.168.178.10) from the contiainer. By default, macvlan isolates containers from the host. So this should fail! To allow containers to reach the host directly, additional routing usually is necessary (see “Optional: Enable host access” below).
  • Test Container-to-Container Communication: Launch another container with an IP in the .16 - .31 range, let them ping eachother.

Optional: Enable host access

Since macvlan isolates containers from the host, they can’t directly access the host’s IP (192.168.178.10) by default. Here’s a workaround to enable host-to-container communication:

Create a macvlan bridge interface on the Host: Add a new macvlan interface on the host. Make sure that the new interface has an IP in the same subnet as the containers.

ip link add macvlan-shim link enp0s3 type macvlan mode bridge
ip addr add 192.168.178.15/32 dev macvlan-shim
ip link set macvlan-shim up

ip route add 192.168.178.16/28 dev macvlan-shim

You should now be able to ping the host (192.168.178.10).

Making the changes permanent

For the macvlan driver to permanently function properly, we need to permanently enable three things in the system:

  • Promiscuous mode
  • Bridge interface
  • IP routing between host and container subnet

Promiscuous mode: Debian per default uses ifupdown for network configuration. So your existing network interfaces should already be inside /etc/network/interfaces. To permanently enable promiscuous mode, just append the post-up and pre-down (optional) commands.

auto enp0s3
iface enp0s3 inet static
    address 192.168.178.10
    netmask 255.255.255.0
    gateway 192.168.178.1
    post-up ip link set enp0s3 promisc on
    pre-down ip link set enp0s3 promisc off

This will enable promiscuous mode after starting the interface and disable it before shutting the interface down. Make sure to adapt to your setting.

Bridge interface and routing: These two settings go hand in hand, thus I’ve put them here together. To add the network bridge after every reboot and have the traffic from the host to the containers routed through this interface, add the following to your /etc/network/interfaces:

auto macvlan-shim
iface macvlan-shim inet static
    pre-up ip link add macvlan-shim link enp0s3 type macvlan mode bridge
    address 192.168.178.15
    netmask 255.255.255.240
    post-up ip route add 192.168.178.16/28 dev macvlan-shim
    pre-down ip route del 192.168.178.16/28 dev macvlan-shim
    post-down ip link del macvlan-shim

With these settings in place, everything needed for the macvlan driver should be restored from the next reboot.

Setup Tutorial: ipvlan Configuration (L2 Mode)

Again, make sure that you’ve enabled IP forwarding, otherwise the ipvlan driver will not work.

Docker ipvlan Network Creation (L2 Mode)

Now, let’s create an ipvlan network in docker. The ipvlan L2 mode shares the host’s MAC address. We’ll set up the network to assign IPs from the 192.168.178.16/28 subnet.

docker network create -d ipvlan \
   --subnet=192.168.178.0/24 \
   --gateway=192.168.178.1 \
   -o parent=enp0s3 \
   -o ipvlan_mode=l2 \
   ipvlan_l2_net

Explanation:

  • -d ipvlan: Specifies the driver as ipvlan.
  • --subnet=192.168.178.0/24: Assigns the main network as subnet for the ipvlan network.
  • --gateway=192.168.178.1: Sets the gateway to the router.
  • -o parent=enp0s3: Links the ipvlan network to the host’s main interface.
  • -o ipvlan_mode=l2: Configures the ipvlan network in L2 mode.

From what I know, you cannot restrict the IP address range docker’s DHCP server supplies to the containers when you’re using the ipvlan driver. You have to manually make sure that you do not supply IP addresses to the containers that are already used in the host network.

Container Creation and IP Assignment in ipvlan L2 Mode

With the ipvlan network set up, you can launch containers on this network. To avoid IP address conflicts, each container will be assigned an IP from the .16 - .31 range within the subnet manually.

Example: Launch a container with a specific IP on the ipvlan_l2_net network.

docker run -it --rm --network ipvlan_l2_net --ip 192.168.178.16 alpine sh

This command starts an Alpine container with the IP 192.168.178.16. If you’re trying all tutorials in this article and already followed the macvlan tutorial, make sure the IP is available or use a different one. You can assign other IPs within the .16 - .31 range as needed.

Testing Network Connectivity with ipvlan L2 Mode

Now that the container is set up, it’s time to test its connectivity to confirm it can reach devices on the host’s network.

  • Router and Other Network Devices: From within the container, test connectivity to the router at 192.168.178.1 and other devices on the host’s network:
ping 192.168.178.1
  • Host: Try to ping the host (192.168.178.10) from the contiainer. By default, ipvlan isolates containers from the host. So this will most likely fail! To allow containers to reach the host directly, additional routing usually is necessary (see “Optional: Enable host access” below).
  • Test Container-to-Container Communication: Start another container on ipvlan_l2_net with a different IP (e.g., 192.168.178.17), and verify that they can communicate by pinging between the containers.

Optional: Enable Host Access

Again, if you need the containers to communicate directly with the host, you need to add a bridge interface on the host.

Create an macvlan bridge interface on the Host: Add a new macvlan interface on the host. Make sure that the new interface has an IP in the same subnet as the containers.

ip link add macvlan0 link enp0s3 type macvlan mode bridge
ip addr add 192.168.178.16/28 dev macvlan-shim
ip link set macvlan-shim up

ip route add 192.168.178.16/28 dev macvlan-shim

You should now be able to ping the host (192.168.178.10)

Making the Changes Permanent

If you don’t need host access when using the ipvlan driver in L2 mode, you can just skip this part. If you need host access, the only settings that needs to be restored after a reboot is the bridge interface and the routing rules. To make these settings permanent, open /etc/network/interfaces and add these lines to the end:

auto macvlan-shim
iface macvlan-shim inet static
    pre-up ip link add macvlan-shim link enp0s3 type macvlan mode bridge
    address 192.168.178.15
    netmask 255.255.255.240
    post-up ip route add 192.168.178.16/28 dev macvlan-shim
    pre-down ip route del 192.168.178.16/28 dev macvlan-shim
    post-down ip link del macvlan-shim

Setup Tutorial: ipvlan Configuration (L3 Mode)

In ipvlan L3 mode, docker creates a virtual, isolated IP network where containers are assigned IP addresses from the specified subnet. External networks are connected through IP routing. As mentioned earlier, Unlike L2 mode, ipvlan L3 mode doesn’t support broadcast or direct MAC communication.

Because the ipvlan l3 subnet must not overlap with the host’s network, in this setup we’ll configure the 192.168.1.0/24 subnet for containers, which will communicate with the main 192.168.178.0/24 network through IP routing.

Again, make sure you’ve got IP forwarding enabled on the docker host.

Host Network Setup for L3 Mode

In order for devices on the main network (192.168.178.0/24) to reach containers in the 192.168.1.0/24 subnet, you’ll need to add a route on your network’s main router. In Germany these are often AVM FRITZ!Boxes, for which you’ll find easy instructions in their documentation. If you’ve got a different brand router, just search the web for something like “<Manufacturer> <Model> add static ip route“. This will direct traffic intended for the container subnet through the docker host.

On the Router: Add a static route with the following details:

  • Destination: 192.168.177.0/24
  • Gateway: 192.168.178.10 (the docker host’s IP)

Docker ipvlan Network Creation (L3 Mode)

Let’s create an ipvlan network in L3 mode within the specified subnet. This isolates containers on their own IP network, routing traffic through IP addresses rather than relying on MAC addresses.

docker network create -d ipvlan \
   --subnet=192.168.177.0/24 \
   --gateway=192.168.178.10 \
   -o parent=enp0s3 \
   -o ipvlan_mode=l3 \
   ipvlan_l3_nte

Routing Configuration for Containers in L3 Mode

As mentioned earlier, the docker host also acts as router and gateway for the L3 subnet that the containers will be put in. The docker host is already aware of the ipvlan L3 subnet, so no extra setup is needed here.

Container Creation and IP Assignment in ipvlan L3 Mode

Now that we have the ipvlan L3 network set up, let’s launch containers and assign them IP addresses within the 192.168.177.0/24 subnet.

Example: Start a container with a specific IP on the ipvlan_l3_net network.

docker run -it --rm --network ipvlan_l3_net --ip 192.168.177.2 alpine sh

This command launches an Alpine container with IP 192.168.177.2. Again, you can assign other IPs in the 192.168.177.0/24 subnet as needed.

Testing Network Connectivity with ipvlan L3 Mode

With routing configured and a test container in place, we can now verify that containers can communicate with the main network and beyond.

  • Ping the Router and External Devices: From within a container, try pinging the router at 192.168.178.1 and other devices on the main network to confirm outgoing connectivity:
ping 192.168.178.1
  • Test Container-to-Host and Host-to-Container Communication: By default, ipvlan isolates the host from containers, but with the routing setup, you should be able to ping containers from the host and vice versa. From the host:
ping 192.168.177.2
  • Containers and External Devices: From another device on the 192.168.178.0/24 network, try pinging a container’s IP (e.g., 192.168.177.2) to ensure full network reachability.
ping 192.168.177.2

Also try pinging devices on your host’s network from your container to test full network reachability.


Troubleshooting

The different docker vlan drivers prove to be very reliable once in place. But, on your way there, you might get stuck one of the other way. I’ve dockumented some common pitfalls on when configuring docker’s vlan drivers.

All: Is IP Forwarding Enabled?

One system setting that is often overlooked is IP forwarding. Any of docker’s vlan drivers will not function properly, if IP forwarding isn’t enabled. To enable IP forwarding, run the following command as root:

sysctl -w net.ipv4.ip_forward=1

With the steps below you can permanently enable IP forwarding on debian based systems:

  1. Open the file /etc/sysctl.conf and find the following (usually commented) line:
#net.ipv4.ip_forward=1
  1. Uncomment (remove the preceeding #) the line
  2. Save the changes and reload the services
sysctl -p /etc/sysctl.conf1
/etc/init.d/procps restart

All: Are Your Subnet Settings Right?

Most of the errors in this category should be caught by docker itself already when creating the network or the corresponding container. But still, there might be a possibility that your subet settings are not right. For the very simple scenario we’ve looked at here it should be hard to mess up. But with more complicated setups?

Try to verify you subnets with a subnet calculator.

All: Is the Gateway Address Right?

For all drivers you must apply the correct gateway address to the docker network you create. Additionally, routing must be configured properly on this gateway.

macvlan & ipvlan L2: The gateway typically s your network’s router. In our examples this is 192.168.178.1. Double check if this is set as gateway for your docker network. You can inspect an existing network’s configuration using the inspect option (see below).

ipvlan L3: For ipvlan L3, the configured gateway address for an ipvlan L3 network must be the docker host’s IP address, in our examples here 192.168.178.10. Us docker’s network inspection command to verify your ipvlan L3 network’s gateway address.

docker network inspect NETWORK

There are a few options you can use for this command, documented in docker’s docs.

macvlan: Is Promiscuous Mode Enabled?

For the macvlan driver to function properly, the network interface it uses must be in promiscuous mode. Check if promiscuous mode is on with the ip command:

ip -d link

This will output something similar to the image below. In this case the interface enp0s3 has promiscuity 1, which means it already is in promiscious mode.

In case it says promiscuity 0, enable it by calling

ip link set enp0s3 promisc on

To make this permanent, run the following commands on systems based on debian 12 or later:

To permanently enable promiscuous mode for an interface, open the file /etc/network/interfaces and add the last two lines to the settings of the interface.

auto enp0s3
iface enp0s3 inet static
    address 192.168.178.10
    netmask 255.255.255.0
    gateway 192.168.178.1
    post-up ip link set enp0s3 promisc on
    pre-down ip link set enp0s3 promisc off

macvlan/ipvlan L2: Is the Shim Routing Configured Properly?

Wmat I’m calling “Shim” here is the bridge interface that allows host access. If this is incorrectly set up, the communication between the docker host and the containers may be impaired. One thing to double check is if the subnet the bridge interface is routing to is correct:

ip route show dev macvlan-shim

Make sure to replace the device you’re looking at (the dev macvlan-shim part) with your bridge. Details are in the macvlan tutorial section. The device should only be routing traffic for the container subnet, 192.168.178.16/28 in the tutorials in this post. To add the route, use the ip command:

ip route add 192.168.178.16/28 dev macvlan-shim

ipvlan L3: Is the router configured correctly?

For the devices on the docker host’s network to be able to connect to the containers in your ipvlan L3 network, your host network’s router must know how to reach the subnet of your ipvlan. Make sure to configure your docker host as gateway for this subnet, in our case 192.168.178.10. This varies depending on your network’s router, so I can’t give you specific instructions here.

ipvlan L3: Is the subnet correct?

Since the docker ipvlan L3 networks cannot overlap your host’s network, the subnet usually is different. Make sure the two networks do not overlap and check if the ipvlan L3’s subnet is set to the one you intended. In the examples above we used 192.168.177.0/24 as subnet for the ipvlan L3 network. To check the configuration of your docker subnet, use the docker network inspect command.

docker network inspect NETWORK

There are a few options you can use for this command, documented in docker’s docs.

Comparison Summary Table: Key Differences Between Macvlan and Ipvlan

While macvlan and ipvlan drivers both allow Docker containers to connect directly to a network without NAT, they handle communication and network configuration in different ways. Here’s a summary of their key differences:

Featuremacvlanipvlan (L2)ipvlan (L3)
MAC Address HandlingUnique per containerShared with hostShared with host
Broadcast SupportYesYesNo
Host IsolationYes (by default)Yes (by default)Yes (by default)
Routing ComplexityMinimalMinimalHigh
Best Use CaseUnique MAC or legacy networksMAC simplificationIP isolation and segmentation

Conclusion

Choosing between Docker’s macvlan and ipvlan drivers really depends on your specific networking needs. Feel free to use the decision tree from this article. If your containers need to be treated as distinct devices on the network with unique MAC addresses, macvlan is the way to go. It’s simple to configure for most Layer 2 setups and works well in environments that rely on MAC-based network policies or discovery protocols like mDNS and ARP.

On the other hand, ipvlan offers more flexibility, particularly with its support for both L2 and L3 modes. It’s a solid choice for scenarios where you want to avoid managing individual MAC addresses or need to isolate container traffic using IP routing. The L3 mode, in particular, shines in environments that require traffic segmentation or advanced routing between subnets.

Whether you’re managing a home lab, a small office setup, or a production environment, understanding these drivers will help you tailor docker networking to your specific requirements. With the detailed tutorials provided, you should now have the tools to configure macvlan and ipvlan networks effectively and make the most of docker’s advanced networking capabilities.

Here’s all cheat sheets from this article, plus the PDF for you to download:

If you have questions or comments, I’d love to hear them. Use the comments below or the contact form to drop me a line!

Leave a Comment