dnsdock の Docker イメージを小さくする

[dnsdock](https://github.com/tonistiigi/dnsdock) は、自動的にホスト内のコンテナをディスカバーして名前解決をしてくれるシンプルな DNS サーバーで、自身も一つのコンテナとして起動するだけで簡単に利用することが出来るツールです。

ただし、ダウンロードしてみると 650MB もあって、ホストを disposable に使うには時間がかかってしまって頻繁に利用するにはあまりよろしくない。
[Dockerfile](https://github.com/tonistiigi/dnsdock/blob/master/Dockerfile) を見ると、golang イメージからソースをビルドして、一つのバイナリを実行しているだけというのがわかるので、

### こういう場合はバイナリ単体だけリップして `scratch` からバイナリだけセットした `Dockerfile` を書くのが定石。

```bash
$ 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*
```

```Dockerfile
FROM scratch
COPY dnsdock /dnsdock
CMD ["/dnsdock"]
```

```bash
$ 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 になりました。

```bash
$ 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 なんだからスタティックなバイナリにしようよ〜）

バイナリをチェックしてみると、

```bash
$ 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](https://hub.docker.com/_/busybox/) や [alpine](https://hub.docker.com/_/alpine/) のような小さなベースイメージなのですが、標準的な公式のイメージは、`uClibc` や `musl` という `libc.so.6` (`glibc`) とは異なるライブラリを使っているので、これらも使えません。

### 次に候補になるのが、`alpine-glibc` という `alipne` に `glibc` を追加したイメージ

Docker Hub で検索するといくつかヒットします。

```Dockerfile
FROM frolvlad/alpine-glibc
COPY dnsdock /dnsdock
CMD ["/dnsdock"]
```

```bash
$ 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 に比べれば全然いいですね。

```bash
$ 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
```

ちゃんと動きます。

### それでも、やっぱりもっと小さいイメージを使いたいミニマリストの方は

ホスト側のライブラリを使ってしまいましょう。

```bash
$ 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](https://hub.docker.com/r/ailispaw/docker-root/) イメージをご紹介

`bash` も `glibc` も標準で入っているコンパクトなディストリビューションです。

```Dockerfile
FROM ailispaw/docker-root
COPY dnsdock /dnsdock
CMD ["/dnsdock"]
```

```bash
$ 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
```

```bash
$ 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
```