Docker networkのmacvlanとhostについてまとめる

## 目的
dockerネットワークのモードであるmacvlanとhostの違いについて、ドキュメントを読んだだけではよく分からなかった。そこで、実際に手を動かしてみた結果、理解する事が出来たので紹介する。

## macvlanとは
ホストのEthernetのインターフェースに仮想的なポートを作成する。作成したポートを各コンテナに割り当てる。仮想的なポートは固有のMACアドレスを持っているため、ホストのネットワークにIPを持たせて所属させる事が出来る。

### 用途
- コンテナにIPアドレスを振りたい
- コンテナからのトラフィックにtagvlanを付けて通信したい

### 構築

```docker-compose.yml
version: "3.9"
services:

  dhcp4:
    build: ./v4
    image: dhcp4:1.0.0
    container_name: dhcp4
    environment:
      TZ: Asia/Tokyo
      DHCPIF: "enp1s0"

    networks:
      vlan0:
        ipv4_address: 172.24.20.203

networks:
  vlan0:
    name: vlan0
    driver: macvlan
    driver_opts:
      parent: enp1s0
    ipam:
      config:
        - subnet: 172.24.20.0/24
          gateway: 172.24.20.254
```

### 解説

Dockerネットワークの作成
parentで指定するのは、Dockerホストのインターフェース。
```docker-compose.yml
networks:
  vlan0:
    name: vlan0
    driver: macvlan
    driver_opts:
      parent: enp1s0
    ipam:
      config:
        - subnet: 172.24.20.0/24
          gateway: 172.24.20.254

```


コンテナ側のネットワークの設定
Dockerネットワークで作成したvlan0　　　　　　
```docker-compose.yml
    networks:
      vlan0:
        ipv4_address: 172.24.20.203
```

### vlanで通信させる場合は
コンテナから出るトラフィックに直接vlan-tagを付ける事が可能である。

```docker-compose.yml
version: "3.9"
services:

  dhcp4:
    build: ./v4
    image: dhcp4:1.0.0
    container_name: dhcp4
    environment:
      TZ: Asia/Tokyo
      DHCPIF: "enp1s0"
      VLAN: 20

    networks:
      vlan20:
        ipv4_address: 172.24.20.203

networks:
  vlan20:
    name: vlan20
    driver: macvlan
    driver_opts:
      parent: enp1s0.20
    ipam:
      config:
        - subnet: 172.24.20.0/24
          gateway: 172.24.20.254
```

## host
ホストのインターフェースをコンテナが共有する事が出来る。そのため、複数コンテナで同じポートを使用する事が出来ない

### 構築
docker-compose.yml
```docker-compose.yml
version: "3.9"
services:

  dhcp4:
    build: ./v4
    image: dhcp4:1.0.0
    container_name: dhcp4

    network_mode: "host"
```

コンテナのインターフェースを確認
```/bin/ash
/ # ip a
95489: br-155b0d683780: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
    link/ether 02:42:ed:dd:1b:77 brd ff:ff:ff:ff:ff:ff
    inet 192.168.144.1/20 brd 192.168.159.255 scope global br-155b0d683780
       valid_lft forever preferred_lft forever
    inet6 fe80::42:edff:fedd:1b77/64 scope link
       valid_lft forever preferred_lft forever
81409: veth320ac8c@if81408: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master br-69ba31e87ce8 state UP
    link/ether 0e:ae:01:10:89:02 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::cae:1ff:fe10:8902/64 scope link
       valid_lft forever preferred_lft forever
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
    link/ether 52:54:00:6c:04:4b brd ff:ff:ff:ff:ff:ff
    inet 172.24.20.34/24 brd 172.24.20.255 scope global enp1s0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe6c:44b/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
    link/ether 02:42:a9:73:b3:98 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:a9ff:fe73:b398/64 scope link
       valid_lft forever preferred_lft forever
```

ホストのインターフェースを確認
```bash
root@shoma:/home/shoma/dhcp/v4# ip a
95489: br-155b0d683780: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:ed:dd:1b:77 brd ff:ff:ff:ff:ff:ff
    inet 192.168.144.1/20 brd 192.168.159.255 scope global br-155b0d683780
       valid_lft forever preferred_lft forever
    inet6 fe80::42:edff:fedd:1b77/64 scope link
       valid_lft forever preferred_lft forever
81409: veth320ac8c@if81408: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-69ba31e87ce8 state UP group default
    link/ether 0e:ae:01:10:89:02 brd ff:ff:ff:ff:ff:ff link-netnsid 20
    inet6 fe80::cae:1ff:fe10:8902/64 scope link
       valid_lft forever preferred_lft forever
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:6c:04:4b brd ff:ff:ff:ff:ff:ff
    inet 172.24.20.34/24 brd 172.24.20.255 scope global enp1s0
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe6c:44b/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:a9:73:b3:98 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:a9ff:fe73:b398/64 scope link
       valid_lft forever preferred_lft forever
```
全く同じ！

ここで、DockerコンテナでDHCPを構築した場合のポートの状態を確認する
コンテナ起動
```bash
$ docker-compose up
lsof -i:67
COMMAND     PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
dhcpd   1070444 root    7u  IPv4 67869674      0t0  UDP *:bootps
```

コンテナ停止
```
$ docker-compose down
Stopping dhcp4 ... done
Removing dhcp4 ... done
$ lsof -i:67
$
```

コンテナ内で動いているプロセスがホストのプロセスとして認識される

## 参考文献

https://designetwork.daichi703n.com/entry/2018/05/02/docker-compose-network-vlan-tag