Using docker macvlan network with docker compose

Apart from simple tests in my lab, all containers I have running are started via docker-compose and thereby all configuration is kept in docker-compose YAML files.

To use the docker macvlan network created in the previous post, the following is needed:

In the global definition, define the network and set it to type external (as it is not defined in the docker compose file)

version: '3'

networks:
  prod_net:
   external: true

In the service definitions, in the specific container sections, specify the network to use just like any other network

services:
  my-container-service-name:
    image: "myhandle/mycontainer"
    networks:
     - prod_net

Alternatively, if you do not want docker IPAM to assign an IP from the configured range and instead assign an IP statically (which can be outside of the configured range for IPAM:

 services:
   my-container-service-name:
     image: "myhandle/mycontainer" 
     networks:
       prod_net:
         ipv4_address: 192.168.1.202

All exposed ports on the container are exposed directly on the IP configured (by IPAM or statically) so there is no need to define ports to expose through the macvlan network. Should you want to expose services/ports through another network you will of course need to configure that accordingly.

Docker macvlan network configuration

As some of my “internal service” have conflicts in port usage and some require direct L2 (non-IP) capbabilities another type of network connectivity than NAT of ports through the docker host is needed.

For this purpose I use the docker macvlan driver which makes the containers connected to a macvlan network appear like they are directly connected to the physical network (or VLAN).

Configuration

Create a docker network using the macvlan driver:

docker network create -d macvlan \
--subnet 192.168.1.0/24 \
--gateway 192.168.1.1 \
--ip-range=192.168.1.208/28 \
-o parent=ens192 prod_net
  • Subnet/GW are both self-explanatory.
  • IP-range is the range docker’s IPAM module will use to assign an IP in this network (if you do not set a specific IP manually)
  • ens192 is the “physical interface” of the docker host.
  • prod_net is the network name.

The above will create the network called prod_net, which is a bridged network allowing containers to participate in the physical network directly.

Do note that the docker host will not be able to reach any container using the macvlan networking (and vice versa)