Menu Close

Configuring VLANs under Docker

In my use case under Docker, I want to present my containers on several different VLANs.

To do this, my server has two network interfaces:

  • eth0: dedicated to server administration, no container will be presented, is connected on a dedicated VLAN for Docker administration
  • eth1: connected on a switch port with the desired VLANs tagged

Prerequisites

Have an operational Docker. For Docker installation, refer to the official procedure: https://docs.docker.com/engine/install/debian/

Install the vlan package

apt update && apt install vlan

Configure eth1

For the configuration of the eth1 interface, I created a file in /etc/network/interfaces.d/99-vlans as I am on Debian and do not use netplan. Be careful to declare the interface for VLANs only once and only once. In this example, I will use VLANs 10 and 20. Adapt according to your use case.

# Parent Interface
allow-hotplug eth1
iface eth1 inet manual
    up ip link set eth1 up
    down ip link set eth1 down

# Vlan 10 Interface
auto eth1.10
iface eth1.10 inet manual
    vlan-raw-device eth1
    up ip link set eth1.10 up
    down ip link set eth1.10 down
    
# Vlan 20 Interface
auto eth1.20
iface eth1.20 inet manual
    vlan-raw-device eth1
    up ip link set eth1.20 up
    down ip link set eth1.20 down

As you can notice, no IP address is defined in the configuration file. This is because only the containers will be presented on the VLANs. The VLAN interfaces are named <parent>.<vlanid> to give the VLAN ID to use. That is eth1.10 and eth1.20

We then apply the configuration via a restart of the networking service

systemctl restart networking.service

We can then verify that the configuration has been taken into account via the ip link command, the new interfaces must be present and in the LOWER_UP status

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 6e:de:8d:cf:52:f3 brd ff:ff:ff:ff:ff:ff
    altname enp0s18
    altname ens18
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 6d:f3:61:4f:8c:b4 brd ff:ff:ff:ff:ff:ff
    altname enp0s19
    altname ens19
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
    link/ether 74:03:aa:8b:85:7e brd ff:ff:ff:ff:ff:ff
60: eth1.1202@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 6d:f3:61:4f:8c:b4 brd ff:ff:ff:ff:ff:ff
61: eth1.3202@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 6d:f3:61:4f:8c:b4 brd ff:ff:ff:ff:ff:ff

Creating Docker networks

We then move on to creating networks, for this we use the macvlan driver, here you will need to replace the subnets with what will be used on each of the VLANs

docker network create -d macvlan \
  --subnet=192.168.10.0/24 \
  --gateway=192.168.10.1 \
  -o parent=eth1.10 \
  vlan10

docker network create -d macvlan \
  --subnet=192.168.20.0/24 \
  --gateway=192.168.20.1 \
  -o parent=eth1.20 \
  vlan20

We can then list the networks to validate that they are present via the following command:

docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
xxxxxxxxxxxx   bridge     bridge    local
xxxxxxxxxxxx   host       host      local
xxxxxxxxxxxx   none       null      local
xxxxxxxxxxxx   vlan10     macvlan   local
xxxxxxxxxxxx   vlan20     macvlan   local

Configuring a container via compose.yaml

For my container deployment, I chose to go through a compose.yaml file
Below is a generic configuration example to present the container on IP address 192.168.20.15 on VLAN 20

services:
  bind9:
    image: myimage
    container_name: mycontainer
    restart: unless-stopped
    networks:
      vlan20:
        ipv4_address: 192.168.20.15
networks:
  vlan20:
    external: true

Note that here no port is declared, indeed in the case of configuring an IP address all the container’s ports are presented on the destination network.

The external: true allows to indicate that the network already configured on the Docker server should be used, this avoids redeclaring it in each configuration file.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.