Docker環境で以下のような「名前解決のズレ」に悩まされたことはないでしょうか。
- ホストでは引けるが、コンテナ内では引けない
- dig は成功するが、アプリは失敗する
- VPN接続時だけ名前解決がおかしくなる
- 再起動すると直るが再発する
これらはDocker特有の名前解決設計を理解していないと、 原因特定に時間がかかりがちです。
本記事では、
- Dockerの名前解決フロー
- ホストとの違い
- ズレが発生する典型パターン
- 実務的な切り分け・対策
を体系的に解説します。
目次
結論:Dockerはホストの名前解決を「そのまま」使っていない
まず結論です。
- Dockerコンテナは 独立した名前解決空間 を持つ
- ホストの /etc/resolv.conf を単純コピーしているだけではない
- systemd-resolved / VPN / NetworkManager の影響を受けやすい
この前提を理解していないと、調査が迷走します。
Dockerコンテナの名前解決の仕組み
Dockerコンテナ内では、基本的に以下が使用されます。
- /etc/resolv.conf(Dockerが生成)
- /etc/hosts(Dockerが管理)
- glibc(通常のLinuxアプリと同じ)
重要なのは、/etc/resolv.conf はホストのコピーではない点です。
コンテナ内 /etc/resolv.conf の実態
docker exec -it <container> cat /etc/resolv.conf
よくある内容は以下です。
nameserver 127.0.0.11
options ndots:0
この 127.0.0.11 は、
- ホストのDNSではない
- systemd-resolved でもない
Docker内蔵DNSです。
Docker内蔵DNS(127.0.0.11)の役割
Dockerは以下の役割を持つDNSを内部に持っています。
- コンテナ名解決(docker-compose / bridge)
- ホストDNSへのフォワード
つまり、
- アプリ → glibc
- glibc → 127.0.0.11
- 127.0.0.11 → ホストDNS
という1段階多い構造になっています。
ズレが発生する典型パターン① systemd-resolved 使用時
ホストで systemd-resolved が有効な場合、
- ホスト:127.0.0.53
- コンテナ:127.0.0.11
という二重スタブ構成になります。
結果として、
- ホストでは解決できる
- コンテナからはフォワード失敗
が発生します。
ズレが発生する典型パターン② VPN接続
VPN接続時、ホストのDNSが動的に変わるケースがあります。
しかし Docker は、
- 起動時のDNS情報を保持
- VPN接続後に自動追従しない
ため、
- ホスト:新DNS
- コンテナ:古いDNS
というズレが発生します。
ズレが発生する典型パターン③ ndots 設定
Dockerでは以下が設定されがちです。
options ndots:0
これにより、
- searchドメインが使われない
- FQDN前提の挙動になる
社内DNSなどでは名前解決失敗につながります。
切り分け手順(実務)
① コンテナ内 glibc 経路確認
docker exec -it <container> getent hosts example.com
- 成功 → DNSフォワードOK
- 失敗 → Docker DNS or ホストDNS疑い
② Docker DNS動作確認
docker exec -it <container> dig example.com
dig が成功してもアプリNGなら glibc設定を疑います。
③ ホストDNS確認
resolvectl status
VPN・NIC別DNSの影響を確認します。
対策① 明示的にDNSを指定する
docker run
docker run --dns 8.8.8.8 nginx
docker-compose
services:
app:
dns:
- 8.8.8.8
期待される結果
- VPNやsystemd-resolvedの影響を受けない
- 名前解決が安定
対策② systemd-resolved を使わない設計
ホスト側で以下を選択するのも有効です。
- systemd-resolved 無効化
- 静的 /etc/resolv.conf
Dockerとの相性が良くなります。
対策③ Docker再起動
VPN接続後は必須です。
systemctl restart docker
期待される結果
- 最新のDNS設定が反映
- ズレが解消
やってはいけない対策
- コンテナ内で resolv.conf を手動編集
- 毎回 dig だけで判断
- 原因不明のまま再起動で逃げる
再発します。
まとめ
- Dockerは独立した名前解決構造を持つ
- 127.0.0.11 はDocker内蔵DNS
- systemd-resolved / VPNと相性問題あり
- getent が最重要切り分け手段
Dockerの名前解決トラブルは、 構造を理解すれば再現性を持って解決できます。
あわせて読みたい


Docker ホストとコンテナ間でファイル共有できないときの対処
はじめに Docker ではホストとコンテナの間でファイルを共有するために ボリュームマウント や バインドマウント を利用します。しかし、設定や権限の問題で「ファイル…
あわせて読みたい


Docker コンテナ内でのファイル I/O エラーの原因と対処
はじめに Docker コンテナ内でファイルを読み書きしようとしたときに、以下のような I/O エラーが発生することがあります。 Permission denied Read-only file system N…
