ubuntu18.04LTS で dockerd の dns を設定する


環境

  • Ubuntu 18.04LTS
    • systemd で resolv.conf 管理したり dockerd 起動したりしてる linux distribution
  • docker-ce 18.09
  • Public network 8.8.8.8 に直につなげない環境下で独自の nameserver を利用している

やりたいこと

systemd で起動する dockerd に対して dns (nameserver) のアドレスを設定したい.

読み飛ばしてもよい背景

何も設定していない状態の dockerd では,ホストの /etc/resolv.conf をマスク(上書き)したファイルがコンテナ内部の /etc/resolv.conf として mount される.

コンテナの DNS を設定 — Docker-docs-ja 1.10.0b ドキュメント

こちらに書かれている通りホストの /etc/resolv.conf が未設定の状態だと 8.8.8.8 へ強制的に飛ばされるのだが,8.8.8.8 へ到達できない環境下だと外部のアドレスが解決できなくなり困る.

16.04LTS だと dns のアドレスを /etc/systemd/system/docker.service.d 配下に ExecStart で書いたり, 或いは何もしなくても resolv.conf の設定がうまいことコンテナ上の /etc/resolv.conf に反映されていた. のだが, 18.04LTS へ新たにインストールしなおしたところ, それらの設定がうまく反映されなくなってしまったので,対処法を調べた.

正攻法(恐らく)

/etc/docker/daemon.json を編集する.

曰く http_proxy など一部の設定を除いては daemon.json に書けとのこと.
(当初 /etc/systemd/system/docker.service.d 配下に ExecStart を記述しようとしたがサービスの起動に失敗した)

編集したら以下のコマンドで再起動する.

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

邪道?

/etc/resolv.conf のリンク先を書き換える.

$ cd /etc
$ sudo rm resolv.conf
$ sudo ln -s resolv.conf ../run/systemd/resolve/resolv.conf

この方法は systemd-resolved で dns 設定が ../run/systemd/resolve/resolv.conf に反映されていることを前提としている. dockerd の再起動は不要.

言い訳

まっさらからインストールした Ubuntu 18 だと /etc/resolv.conf../run/systemd/resolve/stub-resolv.conf のシンボリックリンクとなっている(Ubuntu 16 或いは 16 から移行した環境では ../run/systemd/resolve/resolv.conf となっている).

参考:Systemd 時代のresolv.conf

../run/systemd/resolve/stub-resolv.conf の中身はこうなっている.

nameserver 127.0.0.53

どうも systemd が systemd-resolved サービスを経由して dns 解決するような変更が加わったらしい. (systemd-resolved/etc/systemd/resolved.conf の設定を参照して, 代理のローカル nameserver を 127.0.0.53 に立ち上げる)

この状態で docker run すると 127.0.0.53 がマスクされる. 代わりに 8.8.8.8 で上書きされ, 外部ネットワーク上のアドレス解決ができなくなってしまう.

参考にしたページ