Docker Networking 101: macvlan Network

Photo by Lars Kienle on Unsplash

Docker Networking 101: macvlan Network

macvlan networks in Docker provide a way to assign a MAC address to each container's virtual network interface, making it appear as a physical device on your network, just like a traditional virtual machine. It also allows you to assign an IP address from the same subnet in which the Docker host resides. This avoids the use of the host network, there is no NAT overhead, and you won't run into network performance issues. This type of network configuration is particularly useful when dealing with legacy applications or systems that expect to communicate with physical network devices.

The macvlan networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, or Docker EE for Windows Server. You need at least version 3.9 of the Linux kernel, and version 4.0 or higher is recommended. The macvlan driver is not supported in rootless mode. Find out more here.

How does it work?

Each macvlan network interface is given a unique MAC address, enabling the container to have its own identity on the network.

Containers attached to a macvlan network are directly connected to the physical network, bypassing the Docker host's network stack. This means that the container can communicate with other devices on the network as if it were a physical device. This allows for network segmentation. This is useful in scenarios where you want to divide a larger network into smaller, isolated segments without using multiple physical interfaces.

Since macvlan provides direct access to the physical network, it's important to consider security implications. Network policies and firewall rules should be carefully managed.

Setting up a macvlan network involves creating a new network of type macvlan and specifying the parent interface (e.g., eth0, enp0s3) on the Docker host.

For example, let's consider a local lab setup where you have a home router with 192.168.0.110/24 subnet range.

To establish macvlan network you need to follow these steps:

  1. Identify the parent interface: First, determine the name of the network interface on your Docker host that you want to use as the parent interface for the macvlan network. This is typically something like eth0 or enp0s3. You can find this by running ip addr or ifconfig on the Docker host.

  2. Choose a subnet range and gateway: Since our router's subnet is 192.168.0.110/24, we'll need to choose a range within this subnet for our macvlan network. We need to ensure that the range we select does not conflict with the DHCP range of our router to avoid IP address conflicts.

  3. Create the macvlan network: Use the docker network create command to create a new macvlan network. Specify the parent interface and the subnet details. Here's an example command:

     docker network create -d macvlan \
       --subnet=192.168.0.110/24 \
       --gateway=192.168.0.1 \
       -o parent=enp0s3 \
       my_macvlan_net
    

    In this example:

    • -d macvlan specifies the network driver as macvlan.

    • --subnet=192.168.0.110/24 defines the subnet for the macvlan network. Adjust this according to your network setup.

    • --gateway=192.168.0.1 is the default gateway for the network, which is usually the IP address of your router.

    • -o parent=enp0s3 specifies the parent interface (replace enp0s3 with the actual interface name on your host).

    • my_macvlan_net is the name of the new network.

  4. Run Containers on the macvlan Network: Once the network is created, you can start containers and connect them to this network. For example:

     docker run --net=my_macvlan_net --ip=192.168.0.112 -it ubuntu bash
    

    This command starts an Ubuntu container and assigns it a static IP of 192.168.0.112 within the macvlan network. Ensure that the IP you assign is within the subnet range and not in use by another device.

  5. Verify Network Connectivity: Inside the container, you should be able to ping external IPs, other devices on your local network, and access the internet, assuming your network and firewall settings allow this.

Remember:

  • The subnet and IP addresses used in the commands must be adjusted according to your specific network setup.

  • Ensure the chosen IP range does not conflict with the DHCP server on your router.

  • Be aware of the security and network implications of using macvlan networks, as containers will be directly accessible on the network.

Configuration Modes available in mcvlan network:

  • Bridge mode: The most common mode, where the macvlan interface is bridged to a physical network interface on the Docker host. Containers can communicate with each other and with external networks.

  • 802.1q Trunk Bridge mode: This mode allows the Docker host to connect to a VLAN (Virtual LAN) trunk. In this mode, traffic goes through an 802.1Q sub-interface which Docker creates on the fly. This allows you to control routing and filtering at a more granular level. It’s useful in complex network setups involving VLANs.

Limitations

Here's a breakdown of some limitations of macvlan networks you need to keep in mind:

  • Network complexity increases with macvlan.

  • Containers connected to a macvlan network can't communicate with the host network by default.

  • Some cloud providers do not support macvlan.

  • You may unintentionally degrade your network due to IP address exhaustion or to "VLAN spread", a situation that occurs when you have an inappropriately large number of unique MAC addresses in your network.

  • Your networking equipment needs to be able to handle "promiscuous mode", where one physical interface can be assigned multiple MAC addresses.

  • If your application can work using a bridge (on a single Docker host) or overlay (to communicate across multiple Docker hosts), these solutions may be better in the long term.

Use cases

macvlan networks in Docker are particularly useful in several scenarios where traditional bridged networking falls short. Here are some key use cases for macvlan networks:

  1. Legacy Application Integration: When you have legacy applications that expect to be on a physical network or require specific IP addresses that can't be NATed (Network Address Translation), macvlan allows these applications to run in containers without modifying network expectations.

  2. Simplifying Network Complexity: In environments where overlay networks or complex networking configurations are overkill or too cumbersome, macvlan offers a simpler alternative by directly mapping containers to physical network infrastructure.

  3. Non-Overlay Network Requirements: For applications that don't perform well over overlay networks due to latency or complexity, macvlan provides a more direct network path, reducing latency and simplifying the network path.

  4. Avoiding Double NAT Issues: In scenarios where double NATing is problematic (like certain types of media servers, VPN servers, or peer-to-peer applications), macvlan allows containers to have their own unique IP in the local network, bypassing the need for double NAT.

  5. Multi-tenancy Environments: macvlancan be used to isolate tenants in a shared environment by assigning containers to different VLANs, providing network isolation at the container level.

  6. Network Performance Monitoring and Security: When running network monitoring tools or intrusion detection systems in containers, having a macvlan network allows these tools to have direct access to the physical network for monitoring and analyzing traffic.

  7. High-Performance Computing and Real-Time Applications: In environments where network performance is critical, such as high-performance computing or real-time data processing applications, macvlan provides a high-throughput, low-latency network interface.

  8. Integration with Physical Network Infrastructure: For scenarios where containerized applications need to be part of VLANs or need to comply with existing network policies that are tied to physical networks, macvlan makes this integration seamless.

  9. Direct Access to Network Services: Applications that need direct access to network services (like DHCP servers) without NAT interference can benefit from macvlan as it allows containers to appear as physical hosts on the network.

  10. Testing Network Configurations: macvlan can be useful for testing network configurations and applications in a network that closely mimics a production environment.

It's important to note that while macvlan provides several advantages in specific scenarios, it also introduces complexities in network management and might not be suitable for all environments. Careful consideration and planning are advised when implementing macvlan in a Docker environment.

Workshop: Networking using a macvlan network

Go through the workshop exercise provided by Docker Docs to understand the key features of using the macvlan network within Docker.

💡
For the testing purposes you can boot up local Ubuntu 20.04 VM with already installed Docker daemon. To boot up the machine use Vagrant. Code files can be found here.

The goal of this tutorial is to set up a bridged macvlan network and attach a container to it.

Bridge example

In the simple bridge example, your traffic flows through enp0s3 and Docker routes traffic to your container using its MAC address. To network devices on your network, your container appears to be physically attached to the network.

  1. Check your existing network interfaces with ifconfig or ip addr show commands.

  2. Create a macvlan network called my-macvlan-net. Modify the subnet, gateway, and parent values to values that make sense in your environment.

     docker network create -d macvlan \
       --subnet=10.0.2.0/24 \
       --gateway=10.0.2.1 \
       -o parent=enp0s3 \
       my-macvlan-net
    

    You can use docker network ls and docker network inspect my-macvlan-net commands to verify that the network exists and is a macvlan network.

  3. Start an alpine container and attach it to the my-macvlan-net network. The -dit flags start the container in the background but allow you to attach to it. The --rm flag means the container is removed when it is stopped.

     docker run --rm -dit \
       --network my-macvlan-net \
       --name my-macvlan-alpine \
       alpine:latest \
       ash
    

  4. Inspect the my-macvlan-alpine container and notice the MacAddress key within the Networks key:

     docker container inspect my-macvlan-alpine
    

  5. Check out how the container sees its own network interfaces by running a couple of docker exec commands.

     docker exec my-macvlan-alpine ip addr show eth0
    

     docker exec my-macvlan-alpine ip route
    

  6. Stop the container (Docker removes it because of the --rm flag), and remove the network.

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

    or you can destroy VM machine with:

     vagrant destroy
    

References:

  1. Macvlan network driver

  2. Networking using a macvlan network

  3. Macvlan network driver: Assign MAC address to Docker containers

  4. Macvlan Network Driver Getting Started

  5. Macvlan and IPvlan basics

  6. Docker Networking: macvlans with VLANs

  7. Docker Networking YouTube