DockerのLinuxコンテナ内で名前解決エラーに困っていたら、もくもく会参加者に助けられた話


株式会社 SQUEEZE主催のPythonもくもく会参加時にDocker作業環境内からpipやapt-getが使えなくなるという事態に見舞われましたが、周りの参加者さんのおかげで無事解決できました。

本稿ではその時の状況と解決策を記事にしました。

環境

ホストマシン:Windows10 Home Edition
Docker : Docker ToolBox(バージョン情報未確認)
Docker内環境:Ubuntu 18.04.1 LTS

症状

apt-get, pip, git等、外部とのインターネット接続が必要なコマンドが機能しない。

実行例

# pip install update
>> Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f851e229518>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')':

ググったらproxyがどうのという記事が多く、最初はその線を疑っていました。
例)https://qiita.com/sch923/items/44ac748389dd68388467

しかし、参加者の方からは特別な設定なしで外部に接続できるからその線はなさそう、むしろDNS設定が怪しいとの指摘をいただきました。

確かに上記にTemporary failure in name resolutionとあり、名前解決がうまくいっていないように見えます。

原因

アドバイスに従って、以下のコマンドを実行してみました。

# python -c "import socket; print(socket.gethostbyname('security.ubuntu.com'))"
>> Traceback (most recent call last):
>  File "<string>", line 1, in <module>
> socket.gaierror: [Errno -3] Temporary failure in name resolution

これにより、原因は名前解決がうまくいっていないことが明らかになりました。

なんでも、Docker ToolBoxが使っているVirtualBoxが指定するDNSキャッシュサーバー10.0.2.3には欠陥が存在するそうです。
https://qiita.com/matsuzan/items/aa0c8e2f52e191434e4f
https://fumiyas.github.io/vagrant/network.html

解決方法

Dockerの中から/etc/resolv.confを書き換えました:

before
nameserver 10.0.2.3
after
#nameserver 10.0.2.3
nameserver 8.8.8.8
nameserver 8.8.4.4

これにより、再起動等することなく接続が回復し、apt-get, pipともに今まで通り使えるようになりました!

おわりに

Slackで丁寧にアドバイスしていただいた二人の参加者の方に感謝申し上げます。