Dockerコンテナ内の名前解決への /etc/hosts の影響


結論

  • コンテナ内の /etc/hosts のみがコンテナ内での名前解決に影響する
    • コンテナの外(ホスト)の /etc/hosts は無関係
  • curl や ping は /etc/hosts の設定が反映されるが、 nslookup や dig は /etc/hosts を見ない
  • コンテナ内の /etc/hosts への設定は docker の機能で可能
    • docker-compose の extra_hosts 設定
    • docker の --add-host パラメータ

環境

  • Windows 10 Home
  • docker-machine 0.14.0

docker

$ docker --version
Docker version 18.03.0-ce, build 0520e24302

docker-compose

$ docker-compose --version
docker-compose version 1.20.1, build 5d8c71b2

docker-machine

$ docker-machine --version
docker-machine.exe version 0.14.0, build 89b8332

docker-machine 内の docker

$ docker-machine ssh default docker --version
Docker version 18.09.0, build 4d60db4

コンテナ

centos:7.6

docker-compose.yml

version: '3'

services:
  centos:
    image: centos:7.6.1810
    tty: true

準備

nslookup コマンドを使えるようにするため bind-utils をインストール

yum install -y bind-utils

検証

以下のパターンを確認する

  1. 初期状態
  2. コンテナ内の /etc/hosts を変更する場合
  3. docker-machine 内の /etc/hosts を変更する場合
  4. ホストの /etc/hosts を変更する場合
  5. コンテナ作成時に extra_hosts オプションを指定する場合

初期状態

結果: aaa.example.com は名前解決できない(存在しないため)

nslookup

[root@d327ebe36ed9 /]# nslookup aaa.example.com
Server:         127.0.0.11
Address:        127.0.0.11#53

** server can't find aaa.example.com: NXDOMAIN

ping


[root@d327ebe36ed9 /]# ping aaa.example.com
ping: aaa.example.com: Name or service not known

curl

[root@d327ebe36ed9 /]# curl -v aaa.example.com
* Could not resolve host: aaa.example.com; Unknown error
* Closing connection 0
curl: (6) Could not resolve host: aaa.example.com; Unknown error

コンテナ内の /etc/hosts を変更する場合

結果: nslookup では名前解決できないが、 pingやcurlなどでは名前解決されている

/etc/hosts を変更

aaa.example.com -> 127.2.3.4 に名前解決されるように設定

[root@d327ebe36ed9 /]# echo "127.2.3.4 aaa.example.com" | tee -a /etc/hosts
127.2.3.4 aaa.example.com
[root@d327ebe36ed9 /]# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.19.0.2      d327ebe36ed9

127.2.3.4 aaa.example.com

動作確認

ping: 名前解決されてる

[root@d327ebe36ed9 /]# ping aaa.example.com
PING aaa.example.com (127.2.3.4) 56(84) bytes of data.
64 bytes from aaa.example.com (127.2.3.4): icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from aaa.example.com (127.2.3.4): icmp_seq=2 ttl=64 time=0.040 ms
64 bytes from aaa.example.com (127.2.3.4): icmp_seq=3 ttl=64 time=0.042 ms
64 bytes from aaa.example.com (127.2.3.4): icmp_seq=4 ttl=64 time=0.043 ms
^C
--- aaa.example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3067ms
rtt min/avg/max/mdev = 0.027/0.038/0.043/0.006 ms

curl: 名前解決されてる

ただし、名前解決されたIPでWebサーバーは動いていないのでcurl自体は失敗する

[root@d327ebe36ed9 /]# curl -v aaa.example.com
* About to connect() to aaa.example.com port 80 (#0)
*   Trying 127.2.3.4...
* Connection refused
* Failed connect to aaa.example.com:80; Connection refused
* Closing connection 0
curl: (7) Failed connect to aaa.example.com:80; Connection refused

nslookup: 名前解決されてない

nslookupは そもそも /etc/hosts を見ない

dns - Why is my /etc/hosts file not queried when nslookup tries to resolve an address? - Ask Ubuntu

[root@d327ebe36ed9 /]# nslookup aaa.example.com
Server:         127.0.0.11
Address:        127.0.0.11#53

** server can't find aaa.example.com: NXDOMAIN

docker-machine 内の /etc/hosts を変更する場合

結果: aaa.example.com は名前解決できない(ping, curlでも不可)

/etc/hosts を変更

aaa.example.com -> 127.2.3.4 に名前解決されるように設定

/etc/hosts の変更には root 権限が必要なため、 sudo が必要

docker@default:~$ echo "127.2.3.4 aaa.example.com" | tee -a /etc/hosts
tee: /etc/hosts: Permission denied
127.2.3.4 aaa.example.com
docker@default:~$ echo "127.2.3.4 aaa.example.com" | sudo tee -a /etc/hosts
127.2.3.4 aaa.example.com
docker@default:~$ cat /etc/hosts
127.0.0.1 default localhost localhost.local

# The following lines are desirable for IPv6 capable hosts
# (added automatically by netbase upgrade)

::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

127.2.3.4 aaa.example.com

動作確認(コンテナ内)

ping: 名前解決されてない

[root@d327ebe36ed9 /]# ping aaa.example.com
ping: aaa.example.com: Name or service not known

curl: 名前解決されてない

[root@d327ebe36ed9 /]# curl -v aaa.example.com
* Could not resolve host: aaa.example.com; Unknown error
* Closing connection 0
curl: (6) Could not resolve host: aaa.example.com; Unknown error

nslookup: 名前解決されてない

[root@d327ebe36ed9 /]# nslookup aaa.example.com
Server:         127.0.0.11
Address:        127.0.0.11#53

** server can't find aaa.example.com: NXDOMAIN

ホストの /etc/hosts を変更する場合

結果: aaa.example.com は名前解決できない(ping, curlでも不可)

/etc/hosts を変更

aaa.example.com -> 127.2.3.4 に名前解決されるように設定

Windowsの場合は C:\Windows\System32\drivers\etc\hosts127.2.3.4 aaa.example.com を追記

# localhost name resolution is handled within DNS itself.
# 127.0.0.1       localhost
# ::1             localhost


127.2.3.4 aaa.example.com

動作確認(コンテナ内)

ping: 名前解決されてない

[root@d327ebe36ed9 /]# ping aaa.example.com
ping: aaa.example.com: Name or service not known

curl: 名前解決されてない

[root@d327ebe36ed9 /]# curl -v aaa.example.com
* Could not resolve host: aaa.example.com; Unknown error
* Closing connection 0
curl: (6) Could not resolve host: aaa.example.com; Unknown error

nslookup: 名前解決されてない

[root@d327ebe36ed9 /]# nslookup aaa.example.com
Server:         127.0.0.11
Address:        127.0.0.11#53

** server can't find aaa.example.com: NXDOMAIN

コンテナ作成時に extra_hosts オプションを指定する場合

結果: nslookup では名前解決できないが、 pingやcurlなどでは名前解決されている

extra_hosts オプションとは

Compose ファイル・リファレンス — Docker-docs-ja 17.06.Beta ドキュメント

ホスト名を割り当てます。これは docker クライアントで --add-host パラメータを使うのと同じものです。

extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"

docker-compose.yml を変更

version: '3'

services:
  centos:
    image: centos:7.6.1810
    extra_hosts:
      - "aaa.example.com:127.2.3.4"
    tty: true

コンテナ内 /etc/hosts に自動で追記される

[root@7c139c5eed5b /]# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
127.2.3.4       aaa.example.com
172.20.0.2      7c139c5eed5b

動作確認(コンテナ内)

「コンテナ内の /etc/hosts を変更する場合」 と同じ結果のため省略

nslookup では名前解決できないが、 pingやcurlなどでは名前解決されている

結論

  • コンテナ内の /etc/hosts のみがコンテナ内での名前解決に影響する
    • コンテナの外(ホスト)の /etc/hosts は無関係
  • curl や ping は /etc/hosts の設定が反映されるが、 nslookup や dig は /etc/hosts を見ない
  • コンテナ内の /etc/hosts への設定は docker の機能で可能
    • docker-compose の extra_hosts 設定
    • docker の --add-host パラメータ