docker.io DNSが機能せず、8.8.8.8を使用しようとしています


33

Ubuntu 14.04を新しくインストールし、Dockerを使用して12.04が必要な古いものを実行したい。Docker内のDNSは機能しません。

私のラップトップのresolv.confは次のようになります。

nameserver 127.0.0.1

どうやら、Dockerでは機能しません。したがって、ネームサーバーを8.8.8.8および8.8.4.4に設定しようとします。私がする時

$ sudo docker run -i -t ubuntu /bin/bash

それは言います:

WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [8.8.8.8 8.8.4.4]

確かに、Dockerインスタンス内では、resolv.confは次のようになります。

nameserver 8.8.8.8
nameserver 8.8.4.4

Dockerインスタンス内からこれらの両方に正常にpingできます。ただし、DNSはありません(たとえば、ping google.com失敗します)。

Docker内のifconfig出力:

eth0      Link encap:Ethernet  HWaddr aa:e9:9f:83:9d:92  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::a8e9:9fff:fe83:9d92/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:648 (648.0 B)  TX bytes:738 (738.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

それで?

回答:


23

Ubuntu Dockerパッケージがsystemdを使用するように更新されると、/etc/default/dockerconfigファイルのサポートが削除されたため、rocketman10404によって提案された初期ソリューションは機能しなくなります(無効化dnsmasqは引き続き機能しますが、UbuntuがDNSサーバーを自動的に更新できないという欠点があります) 。

新しいdaemon.json設定ファイルの修正

ネットワークのDNSサーバーを見つけます。

$ nmcli dev show | grep 'IP4.DNS'
IP4.DNS[1]:                             10.0.0.2

存在しない場合は開くか作成し、/etc/docker/daemon.jsonDNS設定をExecStart行に追加します。

# /etc/docker/daemon.json
{
    "dns": ["10.0.0.2", "8.8.8.8"]
}

dockerデーモンを再起動します。

$ sudo service docker restart

私が書いた、詳細なブログ記事をしても、バグを提出し、あなたがより多くの細部をたい場合は、この問題について。

(もともと/lib/systemd/system/docker.serviceを開いてDNS設定をExecStart行追加することで解決しましたが、それは悪いことです。systemd ファイルを直接編集しないください。)


あなたのソリューションに感謝します-私のソリューションに向かう道で役立ちました-私自身の状況とUbuntu(またはNetworkManager + dnsmasqを使用する他のデスクトップディストリビューション)でDockerを実行する特性に少し優雅な一致だと思います
エイドリアン

16

私は自分でdockerを使用していないので、通常はdockerの質問についてはここでは触れませんが、たまたまそれについて読んでいて、この正確な問題対処しているように見えるdockerのドキュメントを見つけました。総括する...

ドキュメントでは、いくつかの回避策が提案されています。最初の方法は、次の行をに追加して、コンテナのdockerデーモンが使用するDNSサーバーを指定すること/etc/default/dockerです。

docker_OPTS="--dns 8.8.8.8"

ここで提供されるDNSは、192.168.1.1(ゲートウェイ)などのローカルDNSサーバーです。次に、で再起動します

sudo restart docker

別の解決策は、次の/etc/NetworkManager/NetworkManager.confように設定をコメントアウトすることにより、NetworkManagerでdnsmasqを無効にします。

#dns=dnsmasq

その後、両方を再起動します

sudo restart network-manager
sudo restart docker

3
dnsmasqを無効にすることは私のために働いた。
ベニル

2
この後者のアプローチは、もちろん、ネットワークマネージャーがdnsmasqを制御できないことを意味します。たとえば、VPNへの切り替えなど、ネットワークを変更してもdnsサーバーを変更できないことを意味します。前者のアプローチのほうが良いように思えますが、dnsmasqがdocker IP(172.17.0.1)でもリッスンできるようにしたいので、そのためにdockerホストをポイントできます。
mc0e

1
Ubuntuはsytemdを使用したDockerのセットアップに切り替えたため/etc/default/docker、効果はなくなりました。これをpost-init.d / upstartの世界で解決する方法については、私のソリューションをご覧ください。
ロビンウィンスロー

/etc/NetworkManager/NetworkManager.confUbuntu 18.04 LTSには存在しません。:/
XtraSimplicity

一部のUbuntu 18.04セットアップ(例:Amazonの最小イメージ)systemd-resolvedでは、デフォルトでキャッシュDNSサーバーとして機能し、WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it.問題を引き起こします(Ubuntu 16.04セットアップではデフォルトで有効になっていないようです)。回避策は、メインの回答で述べたように、コンテナを起動するときsystemd-resolved--dnsオプションを無効にするか使用することです。
アノン

9

具体的には私の状況でこれに遭遇しました

  • ローカル開発マシンでDockerコンテナーを実行する
  • VPNに接続されているもの
  • コンテナ構築スクリプトのいくつかは、コンテナ内のVPNのnpm installカスタムリポジトリから実行するようなことを行います
    • これはCIパイプラインからは機能しますが、開発者のマシンからnpmは機能しません。DNSルックアップを正常に実行できないためです
    • また、外部REST APIを呼び出すためにルックアップを行う必要のあるコンテナにも問題がありました

UbuntuはデフォルトでdnsmasqNetworkManagerによって起動されたDNS要求をキャッシュに使用し、/etc/resolv.confこのインスタンスを指すように設定します127.0.1.1

  • 私たちが使用しているVPNクライアントはNetworkManagerと互換性がなく/etc/resolv.conf、NetworkManagerの設定を上書きする独自のVPNクライアントです
  • これにより、VPNのDNSサーバーが構成されます
  • Dockerは/etc/resolv.confデフォルトでコンテナをシャドウします
    • 通常、Ubuntuでは、Google DNSサーバーをコンテナに渡します(dnsmasq状況を知っているため)。
    • しかし、VPN DNSサーバーの設定をコンテナに渡すことは幸せです
    • docker0ネットワークブリッジのコンテナーから、VPN tap0アダプターを介したDNSサーバーへのルートはありません。
  • エルゴ、コンテナ内のすべてのDNSルックアップは失敗します。これは、提供されている唯一のDNSサーバーに到達できないためです
  • また、一部のネットワークは、すべてのDNSルックアップをスヌーピングできるようにするため、Google DNSサーバーへのリクエストをブロックします

ソリューション :

NetworkManagerを使用する方がよりエレガントdnsmasqで、設計された方法でのキャプティブインスタンスです。

  1. dnsmasqインスタンスをDNS に使用するようにDockerに指示します

    • ファイル/etc/docker/daemon.jsonを追加または編集してdocker0、DNSにブリッジアダプターを使用するようにdockerに指示します

      {
        "dns": ["172.17.0.1"]
      }
      
  2. dnsmasqデフォルトでは127.0.1.1のみをリッスンするため、NM インスタンスもDockerブリッジをリッスンするように構成します-ファイルを作成します/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
  3. 私はそのVPNクライアントの失礼な振る舞いが好きではなく、VPNルックアップにVPNエンドでDNSを使用するだけです(正しく設定されたNetworkManagerを使用するポライトVPNクライアントがある場合、これを行う必要はありません)

    • VPNクライアントのDNS機能をオフにします(resolv.conf接続時に上書きが停止し、すべてのDNSがdnsmasq再び通過します)
    • dnsmasqドメインへのDNSリクエストを適切に指示するように設定ファイルを追加します-ファイル `/etc/NetworkManager/dnsmasq.d/vpn-dns.confを追加します

      server=/myprivatedomain.net/10.0.0.1  
      # or whatever your private DNS server is
      
    • オプションで、ドメインの検索ドメインを追加して、短い名前を使用できるようにします

      • デフォルトのネットワーク接続の検索リストにローカルドメインを追加しました
  4. NetworkManagerとDockerを再起動します

    sudo service network-manager restart
    sudo service docker restart
    

この時点nslookupで、VPNの内側と外側の両方のドメインで、VPNを使用している場合、Dockerコンテナは問題なく実行できるはずです。


1
docker0ブリッジIPのハードコーディングを伴わない小さな調整は、listen-addressディレクティブの代わりにinterfaceを使用することです:interface = docker0
siwyd

素晴らしい説明と指示。+1に値する。
ereOn

乾杯@simonwydooghe-あなたの提案を取り入れました-そのフィールドでワイルドカードを使用することもできますので、デフォルト以外のネットワークで使用されるすべてのブリッジ名のパターンを追加しました(少なくとも、docker-composeで使用)。
エイドリアン

1
daemon.jsonのdns値は配列でなければならないようです。そうしないと、docker cannot unmarshal string into Go value of type []stringサービスを再起動するときにエラーが発生します。
スラベンRezic

Bionicの更新:18.04は、NetworkManager for DNSによって管理されるdnsmasqのキャプティブインスタンスを使用せず、代わりにsystemd-resolvedを使用します。docker0ブリッジをリッスンするように構成できないため、独自の問題が発生します。私はそれを無効にし、NetworkManager dnsmasqを再インストールして正しく設定することに頼りました。
エイドリアン

2

これは、ヘッドレスで実行しているUbuntu 14.04サーバーでdockerをセットアップする方法です。

次のdockerバージョンがインストールされたUbuntuサーバー14.04を実行しています。

#docker version
Client version: 0.9.1
Go version (client): go1.2.1
Git commit (client): 3600720
Server version: 0.9.1
Git commit (server): 3600720
Go version (server): go1.2.1

ファイル/etc/init/docker.io.confおよびスクリプトには、次の行が含まれています。

# modify these in /etc/default/$UPSTART_JOB (/etc/default/docker)
    DOCKER=/usr/bin/$UPSTART_JOB
    DOCKER_OPTS=

上記の答えは、上記のファイルを見つけるのに役立ちました。

/etc/default/docker.ioで次のコメントを外し、ローカルDNSサーバーを追加しました。

# Use DOCKER_OPTS to modify the daemon startup options.  
DOCKER_OPTS="--dns 192.168.X.X"

次を使用してサービスを再起動しました。

sudo service docker.io restart

docker run <image> /bin/bash

コンテナの起動時にDNSメッセージはありません。

新しいコンテナを開始し、dnsutilsをインストールしました。

Ran digとサーバーメッセージは正しいローカルDNSサーバーです。


0

同様の問題があり、StackOverflow報告しました8.8.8.8DockerのデフォルトのUbuntuインストールで指定されているネームサーバーを照会できなかったようです。ただし、pingを実行できました。この場合、実際に照会できるDNSサーバーを使用します。でテスト

nslookup - dns.server.name

コンテナを起動します

docker run --dns=ip.addr.of.dns

私はまだhttps://askubuntu.com/q/607172/30266で自動マジックソリューションを導き出す方法を見つけていません。


私の答えはあなたのために十分に自動化されているかもしれません...-
エイドリアン

0

ユーザー定義のネットワークdnsmasq上にある場合、DockerコンテナーからホストのローカルDNSリゾルバーを使用できます(例)。その場合、コンテナにはネームサーバー(別名Dockerの組み込みDNSサーバー)があり、ホストのループバックアドレスにDNS要求を適切に転送できます。/etc/resolv.conf127.0.0.11

$ cat /etc/resolv.conf
nameserver 127.0.0.1
$ docker run --rm alpine cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
$ docker network create demo
557079c79ddf6be7d6def935fa0c1c3c8290a0db4649c4679b84f6363e3dd9a0
$ docker run --rm --net demo alpine cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0    

を使用するとdocker-compose、コンテナのカスタムネットワークが自動的にセットアップされます(ファイル形式v2 +を使用)。ただし、docker-composeユーザー定義のネットワークでコンテナを実行している間、デフォルトのネットワークでコンテナを構築することに注意してください。ビルドにカスタムネットワークを使用するにnetworkは、ビルド構成でパラメーターを指定できます(ファイル形式v3.4 +が必要です)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.