designetwork(EN)

IT technical memo of networking

Create MACVLAN (802.1Q VLAN Tag) network with Docker-Compose

In this article I connected the Docker container with an external network 802.1Q VLAN Tag.

en-designetwork.hatenablog.com

This time with define as Docker-Compose file to make it easier to operate. If I make it further, I think that network test automation can be realized.

Reference information

Docker-Compose How to write the file is official reference. Attention is necessary because the file format (Key name) has changed or it can not be used depending on the version.

docs.docker.com

Here is an example of using MACVLAN.

Docker Compose File for MacVLAN Network Driver ( Single Node) · GitHub

Create a VLAN Tag network with Docker-Compose

The network to build is as follows. (Same as the previous article)

The docker-compose.yml looks like this. Use Alpine and simply start up the container as tail -f /dev/null.

* There may be errors if version specifications differ. Please refer to Docker Docs and rewrite it when using another version.

$ cat ./docker-compose.yml
version: '2.1'

services:
  vlan20:
    image: alpine
    container_name: container-vlan20
    command: ['tail', '-f', '/dev/null']
    networks:
      vlan20:
        ipv4_address: 192.168.20.201
    environment:
      VLAN: 20
  vlan30:
    image: alpine
    container_name: container-vlan30
    command: ['tail', '-f', '/dev/null']
    networks:
      vlan30:
        ipv4_address: 192.168.30.201
    environment:
      VLAN: 30

networks:
  vlan20:
    name: vlan20
    driver: macvlan
    driver_opts:
      parent: ens192.20
    ipam:
      config:
        - subnet: 192.168.20.0/24
          gateway: 192.168.20.1
  vlan30:
    name: vlan30
    driver: macvlan
    driver_opts:
      parent: ens192.30
    ipam:
      config:
        - subnet: 192.168.30.0/24
          gateway: 192.168.30.1

Create and start a network container using the above docker-compose.yml file.

$ docker-compose up -d
Creating network "vlan20" with driver "macvlan"
Creating network "vlan30" with driver "macvlan"
Creating container-vlan20 ... done
Creating container-vlan30 ... done

Docker Network & Container Status Confirmation

Check the created Docker network. It was created as 802.1Q VLAN tag network using MACVLAN driver.

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
61b2b0b3706c        bridge              bridge              local
e14ebf55d626        host                host                local
112dc8a40c20        none                null                local
e44db3a06622        vlan20              macvlan             local
44e22d10ce22        vlan30              macvlan             local

$ docker network inspect vlan20
[
    {
        "Name": "vlan20",
        "Id": "e44db3a06622aa890d0af9851782e398ad938c552b3aad3636b364f9fd45186c",
        "Created": "2018-05-02T05:10:57.097052723-04:00",
        "Scope": "local",
        "Driver": "macvlan",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "192.168.20.0/24",
                    "Gateway": "192.168.20.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Containers": {
            "894e66f1395a1771737a0c9dbb1812781a8f2d17ec60d27b57b46c12e776de10": {
                "Name": "container-vlan20",
                "EndpointID": "a424fe4eb6bff57c8aa04a116acffcc41bcc9f0c3f8edd3afa782f63484935d6",
                "MacAddress": "02:42:c0:a8:14:c9",
                "IPv4Address": "192.168.20.201/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "parent": "ens192.20"
        },
        "Labels": {
            "com.docker.compose.network": "vlan20",
            "com.docker.compose.project": "vlan-tag"
        }
    }
]

$ docker network inspect vlan30
[
    {
        "Name": "vlan30",
        "Id": "44e22d10ce2269ed8204244430dcea4249b931d2be00b459db4bd731cf5cdca3",
        "Created": "2018-05-02T05:10:57.123608227-04:00",
        "Scope": "local",
        "Driver": "macvlan",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "192.168.30.0/24",
                    "Gateway": "192.168.30.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Containers": {
            "bea9276ab6df772e5af985bc7e761765d562caf3d682850f5669e516c02de374": {
                "Name": "container-vlan30",
                "EndpointID": "e6f134af82f057c0ed7259ec8bc9932e23e594f9211663563b776736e884537b",
                "MacAddress": "02:42:c0:a8:1e:c9",
                "IPv4Address": "192.168.30.201/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "parent": "ens192.30"
        },
        "Labels": {
            "com.docker.compose.network": "vlan30",
            "com.docker.compose.project": "vlan-tag"
        }
    }
]

$ docker ps
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS               NAMES
894e66f1395a        alpine              "tail -f /dev/null"   26 seconds ago      Up 26 seconds                           container-vlan20
bea9276ab6df        alpine              "tail -f /dev/null"   26 seconds ago      Up 26 seconds                           container-vlan30

Communication between two containers & Route confirmation

Ping and Traceroute mutually communicate with each other in the activated container and check the route.

$ docker exec -it container-vlan20 /bin/sh
/ # ip a
84: eth0@if82: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 02:42:c0:a8:14:c9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.20.201/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:c0ff:fea8:14c9/64 scope link
       valid_lft forever preferred_lft forever

/ # ping 192.168.20.1
PING 192.168.20.1 (192.168.20.1): 56 data bytes
64 bytes from 192.168.20.1: seq=0 ttl=64 time=1.164 ms
64 bytes from 192.168.20.1: seq=1 ttl=64 time=0.332 ms

/ # ping 192.168.30.201
PING 192.168.30.201 (192.168.30.201): 56 data bytes
64 bytes from 192.168.30.201: seq=0 ttl=63 time=1.160 ms
64 bytes from 192.168.30.201: seq=1 ttl=63 time=0.317 ms

/ # traceroute 192.168.30.201
traceroute to 192.168.30.201 (192.168.30.201), 30 hops max, 46 byte packets
 1  192.168.20.1 (192.168.20.1)  0.366 ms  0.141 ms  0.452 ms
 2  192.168.30.201 (192.168.30.201)  0.200 ms  0.283 ms  0.268 ms

/ # exit

$ docker exec -it container-vlan30 /bin/sh
/ # ip a
85: eth0@if83: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 02:42:c0:a8:1e:c9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.30.201/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:c0ff:fea8:1ec9/64 scope link
       valid_lft forever preferred_lft forever

/ # ping 192.168.30.1
PING 192.168.30.1 (192.168.30.1): 56 data bytes
64 bytes from 192.168.30.1: seq=0 ttl=64 time=0.298 ms
64 bytes from 192.168.30.1: seq=1 ttl=64 time=0.300 ms

/ # ping 192.168.20.201
PING 192.168.20.201 (192.168.20.201): 56 data bytes
64 bytes from 192.168.20.201: seq=0 ttl=63 time=0.511 ms
64 bytes from 192.168.20.201: seq=1 ttl=63 time=0.405 ms

/ # traceroute 192.168.20.201
traceroute to 192.168.20.201 (192.168.20.201), 30 hops max, 46 byte packets
 1  192.168.30.1 (192.168.30.1)  0.217 ms  0.215 ms  0.197 ms
 2  192.168.20.201 (192.168.20.201)  0.306 ms  0.458 ms  0.443 ms
/ # exit

SUCCEEDED !! Mutual communication confirmation and route confirmation are done as expected. As can be seen from the result of Traceroute, the host NIC is transparent to the VLAN tag and is routed between VLANs in the external router.

Conclusion - Create MACVLAN (802.1Q VLAN Tag) network with Docker-Compose

MACVLAN (802.1Q VLAN Tag) network was created by Docker-Compose, and containers were placed in each network (VLAN / segment), and mutual communication and route confirmation was carried out.

I think that it is possible to automate the network test by devising the method of generating docker-compose.yml and the shell script for the start container.


This Blog is English Version of my JP's.

Sorry if my English sentences are incorrect.

designetwork