Docker で IPv4 / IPv6 Dual Stack な ipvlan network を設定する
さくらのクラウドのスイッチに接続したサーバ上でDockerを動かし、コンテナを直接スイッチに繋げる。
参考資料
- ipvlan ガイド
https://docs.docker.com/network/drivers/ipvlan/ - IPv6 の有効化 (パターン1) (明らかに公式じゃないけど)
https://matsuand.github.io/docs.docker.jp.onthefly/config/daemon/ipv6/ - IPv6 の有効化 (パターン2) (こっちは公式だけどexperimentalって言ってる)
https://docs.docker.com/config/daemon/ipv6/
設定
# パターン1
root# cat /etc/docker/daemon.json
{
"ipv6": true,
"fixed-cidr-v6": "fd67:debd:c5cb::/64"
# この場合、必ずデフォルトのbridgeにCIDRくれてやる必要がある
# (適当なUnique-Localでも付けておく)
}
# パターン2
root# cat /etc/docker/daemon.json
{
"experimental": true,
"ip6tables": true
# この方法でも動いた なんだかよくわからん
}
root# systemctl restart docker.service
# docker network create で --ipv6 を指定する (Dual stack IPv4 IPv6 IPvlan L2 mode)
root# docker network create -d ipvlan --ipv6 \
--subnet=192.0.2.80/28 --gateway=192.0.2.81 \
--subnet=2001:db8:beef:beef::/64 --gateway=2001:db8:beef:beef::1 \
-o ipvlan_mode=l2 -o parent=eth0 \
hoge_net
c1245dc251bc0592e6f2aeef53188d39456282ecbb28f6a83d28c533cd02a76b
root# docker network inspect hoge_net
[
{
"Name": "hoge_net",
"Id": "c1245dc251bc0592e6f2aeef53188d39456282ecbb28f6a83d28c533cd02a76b",
"Created": "2023-11-22T13:10:03.532223202+09:00",
"Scope": "local",
"Driver": "ipvlan",
"EnableIPv6": true, # <--- '--ipv6' が漏れると true にならない (その場合 docker run --ip6 は通るけどコンテナにIPv6アドレス付かない)
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.0.2.80/28",
"Gateway": "192.0.2.81"
},
{
"Subnet": "2001:db8:beef:beef::/64",
"Gateway": "2001:db8:beef:beef::1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {
"ipvlan_mode": "l2",
"parent": "eth0"
},
"Labels": {}
}
]
root# docker run --net hoge_net \
--ip 192.0.2.86 --ip6 2001:db8:beef:beef::a \
-it ubuntu /bin/bash
root# docker network inspect hoge_net
[
{
"Name": "hoge_net",
"Id": "c1245dc251bc0592e6f2aeef53188d39456282ecbb28f6a83d28c533cd02a76b",
"Created": "2023-11-22T13:10:03.532223202+09:00",
"Scope": "local",
"Driver": "ipvlan",
"EnableIPv6": true,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.0.2.80/28",
"Gateway": "192.0.2.81"
},
{
"Subnet": "2001:db8:beef:beef::/64",
"Gateway": "2001:db8:beef:beef::1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"59eea54661448e2ee0f10717f83928fbccf2118336f9f07d40a67f4ef1d77028": {
"Name": "great_moser",
"EndpointID": "e9563c867e0a5553ace2eaaa8cff9018a0dd5ca1bfeea12cdb3f324a7a26691d",
"MacAddress": "",
"IPv4Address": "192.0.2.86/28",
"IPv6Address": "2001:db8:beef:beef::a/64" # <--- ここにちゃーんとIPv6ついてるのを確認しておきたい
}
},
"Options": {
"ipvlan_mode": "l2",
"parent": "eth0"
},
"Labels": {}
}
]
root@59eea5466144:/# apt update && apt install -y iproute2 wget iputils-ping
:
root@59eea5466144:/# ip ad show dev eth0
31: eth0@if2: mtu 1500 qdisc noqueue state UNKNOWN group default
link/ether 9c:a3:ba:32:1e:3a brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.0.2.86/28 brd 192.0.2.95 scope global eth0
valid_lft forever preferred_lft forever
inet6 2001:db8:beef:beef::a/64 scope global nodad
valid_lft forever preferred_lft forever
inet6 fe80::9ca3:ba00:132:1e3a/64 scope link
valid_lft forever preferred_lft forever
root@59eea5466144:/# ip route
default via 192.0.2.81 dev eth0
192.0.2.80/28 dev eth0 proto kernel scope link src 192.0.2.86
root@59eea5466144:/# ip -6 route
2001:db8:beef:beef::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
default via 2001:db8:beef:beef::1 dev eth0 metric 1024 pref medium
root@59eea5466144:/# wget -q -O- api6.ipify.org
2001:db8:beef:beef::a
root@59eea5466144:/# wget -q -O- api4.ipify.org
192.0.2.86