前回は、IPv4/IPv6 Dualstackを設定したKubernetesの環境構築を行いました。
今回は「IPv6チェック用のイメージを作成する」という内容で、書いてみたいと思います。
内容
- KubernetesクラスターでIPv4/IPv6 Dual-stackサポートを有効にする
- IPv6チェック用のイメージを作成する(←今回の内容)
- IPv4/IPv6でサービスを動かすコンテナイメージを使ってKubernetesで実行
イメージ作成環境の作成
最終的にはクラスターでアプリケーションサーバーを動かして、IPv4とIPv6アドレスでそのアプリケーションコンテナーにアクセスするのが目標です。
最近よく使うRed Hat UBI 9イメージにはPython 3.9がインストール済みになっており、これを使ってSimple HTTPサーバーを動かせばチェックできるなと思いつき、早速テストに使うイメージをDockerで作ってみることにしました。
イメージを作ったあとに簡易的なチェックを行いたいところですが、現時点のDockerはコンテナーにIPv6アドレスを振る機能はLinuxホストで動くDockerが必要とのことです。
手元ではMultipassを利用して、Ubuntu VMでDockerが動くLinux環境を用意しました(もちろん、仮想マシンソフトウェアでVMを作って、その中でDockerを動かす方法でも問題ありません。手間を省力化するためにMultipassを使いました)。
Dockerインストール済みのUbuntuイメージ「docker」を使って、VMを作成するには、次のように実行するだけです。デフォルトのVMスペックでは動作しないので、CPU、メモリ、ストレージを指定しています。
% multipass launch -c2 -m4G -d40G -n docker docker % multipass shell docker $ cat /etc/docker/daemon.json #こんな内容を`daemon.json`に追記 { "ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64" } $ sudo systemctl restart docker
このあと、IPv6でもIPv4のアドレスでもアクセスできるイメージを作る流れで解説していきますが、これはこの作業を始める前に次のブログ記事を拝見したためです。
2年くらい前の記事なのですが、この記事によると当時のNGINXのコンテナイメージはIPv6アドレスでリッスンしてくれなかったようです。
後でわかったのですが、執筆日(2022年9月7日)現在はよく使われるWebサーバーであるNGINXとApache Web Server(httpd)の現在のイメージについては、IPv4,IPv6アドレスともに問題なく利用できるのを手元の環境で確認しています。あえて古いイメージを使わない限りは問題なさそうですが、場合によってはそういうこともありうるので、使うイメージによって事前にチェックが必要かもしれません。
- docker.io/nginx:stable
- docker.io/nginx:stable-alpine
- docker.io/httpd:2.4
- docker.io/httpd:2.4-alpine
イメージ作成
コンテナのカスタムイメージを作るため、まずは次のようなDockerfileを作成します。 ちょっとテストするだけなので、最小限にしてあります。
FROM docker.io/redhat/ubi9:latest ENTRYPOINT ["python3", "-m","http.server","--bind","::"] EXPOSE 8000
このDockerfileを使って、イメージをビルドします。
docker build --compress -t localhost/python-webserver -f Dockerfile .
イメージのテスト
作成したイメージを使って、コンテナを実行してみます。
docker container run -p 58000:8000 -d localhost/python-webserver
curl
を使ってアクセスしてみます。
curl http://127.0.0.1:58000 curl http://[::]:58000
どちらを実行しても同じ結果になるはずです。特にIPv6アドレスでアクセスできない場合は、IPv6オプションの記述に不備があるか環境にIPv6アドレスが設定されていない可能性が考えられます。
$ curl http://[::]:58000 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Directory listing for /</title> </head> <body> <h1>Directory listing for /</h1> <hr> <ul> <li><a href=".dockerenv">.dockerenv</a></li> <li><a href="afs/">afs/</a></li> <li><a href="bin/">bin@</a></li> <li><a href="boot/">boot/</a></li> <li><a href="dev/">dev/</a></li> <li><a href="etc/">etc/</a></li> <li><a href="home/">home/</a></li> <li><a href="lib/">lib@</a></li> <li><a href="lib64/">lib64@</a></li> <li><a href="lost%2Bfound/">lost+found/</a></li> <li><a href="media/">media/</a></li> <li><a href="mnt/">mnt/</a></li> <li><a href="opt/">opt/</a></li> <li><a href="proc/">proc/</a></li> <li><a href="root/">root/</a></li> <li><a href="run/">run/</a></li> <li><a href="sbin/">sbin@</a></li> <li><a href="srv/">srv/</a></li> <li><a href="sys/">sys/</a></li> <li><a href="tmp/">tmp/</a></li> <li><a href="usr/">usr/</a></li> <li><a href="var/">var/</a></li> </ul> <hr> </body> </html>
コンテナの環境にiproute
パッケージを入れて確認すると、2001:
から始まるIPv6アドレスが設定されていることがわかります。
[root@764bb1df55cb /]# ip a s eth0 14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever inet6 2001:db8:1::242:ac11:2/64 scope global nodad valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe11:2/64 scope link valid_lft forever preferred_lft forever
というわけで、DockerコンテナでもIPv6アドレスを使えるようになりました。IPv6アドレスによる外部アクセスは、Dockerホストのブリッジインターフェイスを介してゲートウェイから外に出るので、IPv6接続サービスが提供されていればアクセスできるはずです(おそらく)。