はじめに
しっかりとDockerのipv6周りについては理解していないです。ドキュメントも読んでみたのですが、私の知識不足がたたってか、あまり呑み込めていないです。
Dockerを使用する前から、自宅のネットワーク環境にIPv6を整備しつつあったのですが、機能の一部をDockerに移していたところ、IPv6での疎通がうまくいっていないことをTwitterで呟いていたりしました。
で、改めてチャレンジした次第。
参考にした情報
最も参考になったのは以下のWebページ。
Dockerとipv6で調べてみるとよく出てくる情報は、Unique Local AddressとNAT66を併用したパターンになるかと思います。
ただ、こちらでも書かれているように、Unique Local Addressの場合は、RFC6724で定義されているpolicy tableに従って、IPv4/IPv6 dual stackのインスタンスとの通信ではIPv4が優先される、とのことで、通常とは逆の動作になるかと思います。
あと、ip6tablesの設定を投入するのが案外面倒な面もあるかもしれません。
もう一つとしてはGlobal unicast Addressを使用するパターンになるかと思います。
個人的には、こちらの方が、ホスト側に設定されたIPv6アドレスの拡張の範囲で設定できるので、あまり違うネットワークといえばいいのか、理解のずれ?みたいなものが少ないような気がします。
今回自分の場合は、後者で設定し、疎通できることを確認しました。
DockerでIPv6通信を行うようにするには
Dockerでipv6なネットワーク設定を行う場合は以下の方法があると思います。
Docker network
コマンドから、ipv6オプションを付与したうえで作成する。daemon.json
にipv6向け設定を追加する。- docker-composeファイルに、都度ipv6を付与するネットワーク設定を追加する。
というわけで、今回は一番よく使うパターンになる3番目のDocker-composeファイルを使用した形をメモしておこうと思います。
設定方法
docker-composeの場合
ちなみにDocker-composeファイルに記述するときは、versionは”3″だとダメなようで、私は”2.1″を使用しています。containerの設定で”3″固有の記述があるのであれば、見直すか、別の設定方法に変更する必要があるはずです。
version: "2.1"
services:
networks:
default-net:
driver: bridge
enable_ipv6: true
ipam:
driver: default
config:
- subnet: 172.32.0.0/24
gateway: 172.32.0.1
- subnet: 240x:zzzz:xxxx:yyyy:1000::/80
gateway: 240x:zzzz:xxxx:yyyy:1000::1
ここで設定するsubnet
はDocker containerが所属するネットワークアドレス、gateway
はcontainerホストに設定されるipv6アドレスであり、各containerのデフォルトゲートウェイに設定されるアドレスになるはずです。
これでDockerゲスト?からDockerホスト側へはping6
が飛ぶようになると思います。が、グローバルへ確認しても、返答をDockerホストからDockerゲストへ戻してあげることができないため、疎通不能になるはずです。
NDP Proxyを設定する
これを解消するために、Dockerホスト側にNDP Proxy
を有効にします。
net.ipv6.conf.eth0.proxy_ndp=1
隣接するシステムとして、neighbor addを各containerで設定する必要があるのですが、さすがにこれは現実的ではないので、ndppd – NDP Proxy Daemonを導入する方が早いはずです。
$ sudo apt update
$ sudo apt install ndppd
$ cat /etc/ndppd.conf
proxy eth0 {
rule 240x:zzzz:xxxx:yyyy:1000::/80 {
static
}
}
ndppd
については以下を参照してください。
これを設定することで、DockerゲストがDockerホストのneighbor table
に登録されることになるので、グローバルを含めた形で疎通ができるようになるはずです。
確認してみる
$ docker network inspect docker-env_default-net
"Containers": {
"0c3c9bda23a7768031525ee92ed4b91af4fc42fc8be8ed3533795e6722bc4ee6": {
"Name": "bind-9",
"EndpointID": "4609709ec8c06d2f89eb5ecdce8a749134ffdb31ba96027b48a6fb302e6ed531",
"MacAddress": "02:42:ac:20:00:08",
"IPv4Address": "172.32.0.8/24",
"IPv6Address": "240x:zzzz:xxxx:yyyy:1000::8/80"
$ docker exec -it bind-9 ip -6 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
219: eth0@if220: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 state UP
inet6 240x:zzzz:xxxx:yyyy:1000::8/80 scope global flags 02
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe20:8/64 scope link
valid_lft forever preferred_lft forever
$ docker exec -it bind-9 ip -6 r
240x:zzzz:xxxx:yyyy:1000::/80 dev eth0 metric 256
fe80::/64 dev eth0 metric 256
ff00::/8 dev eth0 metric 256
default via 240x:zzzz:xxxx:yyyy:1000::1 dev eth0 metric 1024
$ docker exec -it bind-9 ping6 -c 3 www.google.com
PING www.google.com (2404:6800:4004:80b::2004): 56 data bytes
64 bytes from 2404:6800:4004:80b::2004: seq=0 ttl=51 time=5.824 ms
64 bytes from 2404:6800:4004:80b::2004: seq=1 ttl=51 time=6.240 ms
64 bytes from 2404:6800:4004:80b::2004: seq=2 ttl=51 time=6.378 ms
--- www.google.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 5.824/6.147/6.378 ms
理解そのものの間違い等はあると思いますので、気が付いた方はご指摘いただければと思います。