Rootless DockerでIPv6を使いたい
はじめに
Rootless Dockerのコンテナ内からIPv6でホスト外にアクセスするための設定方法について紹介します。
デフォルトで使われるネットワークドライバであるslirp4netns
やvpnkit
はIPv6に対応していないため、代わりにpasta
を使います。
環境
説明で利用するOSはUbuntu 24.04 LTSです。それ以外のOSでも動くと思いますが、pasta
を手動インストールする必要があるかもしれません。
もちろんホストがIPv6ネットワークで外にアクセスできる状態になっていることが前提です。ping6 www.google.com
等で確認しておきましょう。
セットアップ
必要なパッケージのインストール
必要なパッケージをインストールします。pasta
はpasst
パッケージに含まれています。動作確認にDocker Composeを使うため、そのパッケージもインストールします。
$ sudo apt install docker.io docker-compose-v2 passt
Rootless Dockerのインストール
公式サイトのインストーラを用います。古いバージョンだとpasta
をうまく利用できないため、再インストールした方が良いかもしれません。
この時Rootless Dockerでpasta
を利用するための設定ファイルを用意しておきます。
$ curl -fsSL https://get.docker.com/rootless | sh
$ mkdir -p ~/.config/systemd/user/docker.service.d
$ cat > ~/.config/systemd/user/docker.service.d/pasta.conf <<EOF
[Service]
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_NET=pasta"
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=--ipv6"
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=implicit"
EOF
$ systemctl --user daemon-reload
$ systemctl --user restart docker
動作確認
コンテナの起動
Docker ComposeでUbuntuコンテナを起動します。
$ cat > compose.yaml <<EOF
services:
ubuntu:
image: "ubuntu:24.04"
command: sleep infinity
networks:
- ip6net
networks:
ip6net:
enable_ipv6: true
ipam:
config:
- subnet: 2001:db8::/64
EOF
$ docker compose up -d
動作確認
docker compose exec
でコンテナに入り、必要なパッケージをインストールし動作確認をします。
$ docker compose exec ubuntu bash
root@ab3c11f44d40:/# apt update && apt install -y iproute2 iputils-ping curl
アドレスや経路が設定されており、外のサーバにping6
やcurl -6
が通ると思います。
root@ab3c11f44d40:/# ip a
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
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 2001:db8::2/64 scope global nodad
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe12:2/64 scope link
valid_lft forever preferred_lft forever
root@ab3c11f44d40:/# ip -6 route
2001:db8::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
default via 2001:db8::1 dev eth0 metric 1024 pref medium
余談:Rootless Dockerのネットワークネームスペース
ここからは余談です。
インターンレポート: RootlessコンテナのTCP/IP高速化 | by 松本直樹 | nttlabs | Mediumの記事にあるように、Rootless Dockerはネットワークネームスペースが入れ子になっています。ホストとから隔離されたネットワークネームスペースでrootlesskit
が動作し、さらにその中の別のネットワークネームスペースでコンテナが動いています。(なおpasta
はホストのネットワークネームスペースで動作しています。)
ここではrootlesskit
が動作するネットワークネームスペースに入る方法を紹介します。IPv6でうまく通信できずデバッグしたい時に必要になるかもしれません。
lsns
コマンドでネットワークネームスペース一覧を表示し、入りたいネームスペースで動くプロセスのPIDを指定してnsenter
コマンドでネットワークネームスペースに入ります。
$ lsns -t net
NS TYPE NPROCS PID USER NETNSID NSFS COMMAND
4026531840 net 25 1869 ozaki-r unassigned /usr/bin/pipewire
4026533035 net 5 1159554 ozaki-r unassigned /proc/self/exe --state-dir=/run/user/1000/dockerd-rootless --net=pasta --mtu=1500 --slirp4netn
4026533105 net 24 860887 ozaki-r unassigned /usr/libexec/polkitd --no-debug
4026533181 net 1 1667631 ozaki-r unassigned -/usr/bin/fish
4026533252 net 1 3043978 ozaki-r unassigned sleep infinity
$ sudo nsenter --target 1159554 --net
わかりにくいですが/proc/self/exe
がrootlesskit
なので、nsenter
には1159554
を指定しています。
ip a
やip -6 route
コマンドでIPアドレスや経路を表示し、ホストのものと比較してみると面白いと思います。
おわりに
Rootless Dockerのコンテナ内からIPv6で外に出るための設定方法について紹介しました。
今回利用したpasta
を始め、Rootless Dockerでコンテナ外と通信するためのソフトウェアはとても面白い処理をしているので、興味がある人はその構造や動きを調べてみると良いかもしれません。
Discussion