dnsdock は、自動的にホスト内のコンテナをディスカバーして名前解決をしてくれるシンプルな DNS サーバーで、自身も一つのコンテナとして起動するだけで簡単に利用することが出来るツールです。
ただし、ダウンロードしてみると 650MB もあって、ホストを disposable に使うには時間がかかってしまって頻繁に利用するにはあまりよろしくない。
Dockerfile を見ると、golang イメージからソースをビルドして、一つのバイナリを実行しているだけというのがわかるので、
こういう場合はバイナリ単体だけリップして scratch
からバイナリだけセットした Dockerfile
を書くのが定石。
$ docker create --name dnsdock tonistiigi/dnsdock
537ae61e7004660a7795bb38ea3ac36c322980959184de04db2785d7ba7c3f39
$ docker cp dnsdock:/go/bin/dnsdock .
$ docker rm dnsdock
$ ls -l
-rwxr-xr-x 1 docker docker 8514840 Aug 19 16:49 dnsdock*
FROM scratch
COPY dnsdock /dnsdock
CMD ["/dnsdock"]
$ docker build -t dnsdock .
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
dnsdock latest d118bb5f300a 3 seconds ago 8.515 MB
tonistiigi/dnsdock latest 8bc6b282823e 9 hours ago 649.5 MB
いきなり 650MB から 8.5MB になりました。
$ docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 0.0.0.0:53:53/udp --name dnsdock dnsdock
b376f942a4744327b153f322c8500c7124368b2c887d1d494cd7cc5f4c8d3d7d
Error response from daemon: Cannot start container b376f942a4744327b153f322c8500c7124368b2c887d1d494cd7cc5f4c8d3d7d: [8] System error: no such file or directory
ところが、実行してみるとエラー。。。
これは、dnsdock
がスタティックにリンクされてなくて共有ライブラリを使っているせいです。
(GO なんだからスタティックなバイナリにしようよ〜)
バイナリをチェックしてみると、
$ LD_TRACE_LOADED_OBJECTS=1 ./dnsdock
linux-vdso.so.1 (0x00007ffd33540000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007f0ab3b71000)
libc.so.6 => /lib/libc.so.6 (0x00007f0ab37ce000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0ab3d8e000)
たしかに、共有ライブラリを引き込んでいます。これでは、scratch
が使えません。
そこで次の候補になるのが、busybox や alpine のような小さなベースイメージなのですが、標準的な公式のイメージは、uClibc
や musl
という libc.so.6
(glibc
) とは異なるライブラリを使っているので、これらも使えません。
次に候補になるのが、alpine-glibc
という alipne
に glibc
を追加したイメージ
Docker Hub で検索するといくつかヒットします。
FROM frolvlad/alpine-glibc
COPY dnsdock /dnsdock
CMD ["/dnsdock"]
$ docker build -t dnsdock:alpine-glibc -f Dockerfile.alpine-glibc .
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
dnsdock alpine-glibc 25c58bf1150d 2 seconds ago 20.03 MB
dnsdock latest d118bb5f300a 22 minutes ago 8.515 MB
tonistiigi/dnsdock latest 8bc6b282823e 9 hours ago 649.5 MB
20MB に増えてしまいましたが、それでも 650MB に比べれば全然いいですね。
$ docker rm -f dnsdock
$ docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 0.0.0.0:53:53/udp --name dnsdock dnsdock:alpine-glibc
9e78b8eac5170d5288e25f343d751e07eb5dd00bc714c37f9e09ccd9f158dc72
ちゃんと動きます。
それでも、やっぱりもっと小さいイメージを使いたいミニマリストの方は
ホスト側のライブラリを使ってしまいましょう。
$ docker rm -f dnsdock
$ docker run -d -v /lib:/lib:ro -v /lib64:/lib64:ro -v /var/run/docker.sock:/var/run/docker.sock -p 0.0.0.0:53:53/udp --name dnsdock dnsdock
4374a344dbfd1f0a198e69e9bdd60f219c67aa656f700671be87f15e78992e4d
動きました。
でも、コンテナ内に docker exec
出来ないとかデバックが厳しいので、やはり何らかのベースイメージから作った方が良いと思います。
最後に、私の作った docker-root イメージをご紹介
bash
も glibc
も標準で入っているコンパクトなディストリビューションです。
FROM ailispaw/docker-root
COPY dnsdock /dnsdock
CMD ["/dnsdock"]
$ docker build -t dnsdock:docker-root -f Dockerfile.docker-root .
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
dnsdock docker-root 3149aae33f0d 3 seconds ago 25.58 MB
dnsdock alpine-glibc 25c58bf1150d 17 minutes ago 20.03 MB
dnsdock latest d118bb5f300a 39 minutes ago 8.515 MB
tonistiigi/dnsdock latest 8bc6b282823e 9 hours ago 649.5 MB
$ docker rm -f dnsdock
$ docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 0.0.0.0:53:53/udp --name dnsdock dnsdock:docker-root
4ad4c2af7740d30180bcee8c01905f6024b65e2fb267324d6f5756f13463ac7e