LINUX.ORG.RU

Проблема с DNS в docker-контейнере

 


0

1

Всем здравствуйте!

Ситуация следующая: есть хост-система (CentOS 7.6), в которой установлен докер. И (среди прочего) есть контейнер, в котором установлен CentOS из вот этого образа https://hub.docker.com/_/centos/ Причём немного «допилен» для поддержки systemd (на той же странице в hub.docker.com есть инструкция под заголовком «Dockerfile for systemd base image»).

Контейнер запускается в приватной сети с примерно вот такими параметрами:

docker run -dit --name="env4" --restart always --privileged --net mynetwork -p 22004:22 --expose 80 --expose 443 local/centos-systemd:my_tag

В «чистом» контейнере в плане DNS всё хорошо работает, можно пропинговать любой сайт по доменному имени.

Дальше я произвожу запуск определённого bash-скрипта (в контейнере), который написан не мной и который устанавливает веб-окружение и кучу-кучу всего (nginx, httpd, mysql, nodejs и мн.мн.др.) Так вот после его установки перестают ресолвиться доменные имена. При этом пинг по IP-адресам проходит:

root# ping ya.ru
ping: ya.ru: Name or service not known
root# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=4.62 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=4.67 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=46 time=4.65 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=46 time=4.68 ms

Содержимое файла /etc/resolv.conf до и после установки скрипта одинаковое:

root# cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0

Если прописать в этот файл ручками гугловские DNS-серверы (8.8.8.8 и 8.8.4.4), то всё начинает работать (имена ресолвятся), но вариант не подходит из-за того, что тогда теряются алиасы локальных IP-адресов, которые есть в приватной сети docker. Ну и плюс при каждом рестарте контейнера этот файл переписывается на то содержимое, которое я привёл.

Такое ощущение, что этот скрипт ставит какую-то свою службу разрешения доменных имён, которая работает криво. Посмотрел лог установки, по слову «DNS» нашёл следующее:

---> Package perl-Net-DNS.x86_64 0:0.72-6.el7 will be installed
Может, это как-то влияет.

Есть ли идеи, куда копать, чтобы в контейнере доменные имена начали ресолвиться?

В «чистом» контейнере в плане DNS всё хорошо работает

Куда уходят запросы?

тогда теряются алиасы локальных IP-адресов

А когда не теряются? Где эти алиасы прописаны?

Такое ощущение, что этот скрипт ставит какую-то свою службу разрешения доменных имён, которая работает криво

Посмотри, какие процессы запущены после работы скрипта, может среди них найдётся что-нибудь интересное. Возможно, наоборот, что-то убивает резолвер, который отрабатывает в «чистом» контейнере (ведь до работы скрипта, по твоим словам, в плане DNS всё хорошо).

perl-Net-DNS.x86_64

Перловые модули для работы с DNS — их использует либо что-то из стандартного набора софта, либо что-то, подтягиваемое твоим скриптом.

mathcrosp ★★ ()
Ответ на: комментарий от mathcrosp

Куда уходят запросы?

# traceroute ya.ru
traceroute to ya.ru (87.250.250.242), 30 hops max, 60 byte packets
 1  gateway (172.18.0.1)  0.034 ms  0.014 ms  0.013 ms
 2  10.112.119.1 (10.112.119.1)  0.487 ms  0.589 ms  0.658 ms
 3  119.spb.net.selectel.ru (188.93.17.119)  1.086 ms  1.072 ms  1.073 ms
 4  diana-spb-ix.yandex.net (194.226.100.90)  1.424 ms  1.627 ms  1.612 ms
 5  ya.ru (87.250.250.242)  13.861 ms  11.238 ms  11.199 ms

здесь 172.18.0.1 - это какой-то шлюз приватное докеровской сети. Как понимаю, он и делает все преобразования.

Ну то есть если выполнить в хост системе «docker inspect network mynetwork», то увидим нечто такое:

# docker inspect network webformat
<...>
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
<...>

А когда не теряются? Где эти алиасы прописаны?

Я точно не знаю, как работает DNS в актуальном докере (у меня его версия 18.09.6, build 481bc77156). Раньше, вроде, все алиасы прописывались в /etc/hosts. А сейчас, видимо, за преобразование имён ответствен вот этот gateway, который указан в настройках приватной сети. Как он работает - фиг знает.

Но работать-то перестаёт именно после того, как я устанавливаю это веб-окружение bash-скриптом внутри контейнера. Из этого делаю вывод, что причина именно внутри контейнера. Запросы на преобразование имени перестают улетать на этот IP (причём если прописать этот gateway в resolv.conf - всё равно не работает).

Посмотри, какие процессы запущены после работы скрипта

Ну вот из «плохого» контейнера (с проблемой DNS). Я предварительно поубивал в нём все процессы вроде nginx и httpd. Вроде ничего бросающегося в глаза не осталось:

[root@docker /]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0 190880  3720 ?        Ss   07:44   0:04 /usr/sbin/init
root        23  0.0  0.0  39084  8412 ?        Ss   07:44   0:00 /usr/lib/systemd/systemd-journald
root        27  0.0  0.0  43112  2148 ?        Ss   07:44   0:00 /usr/lib/systemd/systemd-udevd
root       537  0.0  0.0  26376  1740 ?        Ss   07:44   0:01 /usr/lib/systemd/systemd-logind
dbus       555  0.0  0.0  58120  2432 ?        Ss   07:44   0:03 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root       765  0.0  0.0   8084   872 console  Ss+  07:44   0:00 /sbin/agetty --noclear --keep-baud console 115200,38400,9600 linux
root     11112  0.0  0.0  13420  2036 pts/1    Ss   08:42   0:00 bash
root     11262  0.0  0.0  86228  5728 pts/1    S+   09:02   0:00 /usr/bin/mc -P /tmp/mc-root/mc.pwd.11112
root     11264  0.0  0.0  13420  2028 pts/2    Ss+  09:02   0:00 bash -rcfile .bashrc
root     14236  0.0  0.0  13420  2028 pts/3    Ss   11:21   0:00 bash

А вот для сравнения из «хорошего»:

root         1  0.0  0.0  43084  3212 ?        Ss   06:05   0:00 /usr/sbin/init
root        20  0.0  0.0  39084  6308 ?        Ss   06:05   0:00 /usr/lib/systemd/systemd-journald
root        28  0.0  0.0  41628  1840 ?        Ss   06:05   0:00 /usr/lib/systemd/systemd-udevd
dbus       756  0.0  0.0  57988  2104 ?        Ss   06:05   0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root       841  0.0  0.0  24252  1556 ?        Ss   06:05   0:00 /usr/lib/systemd/systemd-logind
root       883  0.0  0.0   8084   872 console  Ss+  06:05   0:00 /sbin/agetty --noclear --keep-baud console 115200,38400,9600 linux
root      2353  0.3  0.0  11820  1888 pts/1    Ss   06:19   0:00 bash

Novascriptum ()
Ответ на: комментарий от Novascriptum

И вот тоже из «плохого», но по IP-адресу:

[root@docker]# traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  gateway (172.18.0.1)  0.109 ms  0.017 ms  0.014 ms
 2  10.112.119.1 (10.112.119.1)  0.588 ms  0.671 ms  0.757 ms
 3  188.93.17.119 (188.93.17.119)  1.064 ms  1.043 ms  0.921 ms
 4  188.93.16.145 (188.93.16.145)  0.857 ms  0.832 ms  0.853 ms
 5  74.125.244.132 (74.125.244.132)  1.101 ms  1.230 ms 74.125.244.133 (74.125.244.133)  1.752 ms
 6  216.239.42.53 (216.239.42.53)  5.302 ms 216.239.42.85 (216.239.42.85)  5.071 ms 216.239.42.53 (216.239.42.53)  5.028 ms
 7  209.85.249.79 (209.85.249.79)  7.048 ms  4.798 ms 209.85.249.175 (209.85.249.175)  4.748 ms
 8  108.170.235.204 (108.170.235.204)  5.114 ms 216.239.57.222 (216.239.57.222)  5.207 ms 216.239.54.46 (216.239.54.46)  4.692 ms
 9  209.85.251.41 (209.85.251.41)  6.269 ms * 216.239.47.167 (216.239.47.167)  6.801 ms

Novascriptum ()
Ответ на: комментарий от Novascriptum

шлюз приватное докеровской сети
Как понимаю, он и делает все преобразования

traceroute шлёт ICMP-пакеты, преобразования DNS тут ни при чём. Чтобы понять, куда идут DNS-запросы, можешь потрейсить дигом или на худой конец подампить трафик.

Запросы на преобразование имени перестают улетать

Может при установке окружения какие-нибудь маршруты ломаются. Понаблюдай.

mathcrosp ★★ ()
Ответ на: комментарий от Novascriptum

Потому что ya.ru из-за нерабочего DNS не может разрезолвиться. Ну а комментом ниже всё работает, потому что у тебя уже есть конкретный айпишник и резолвить ничего не надо.

mathcrosp ★★ ()
Ответ на: комментарий от Novascriptum

перестают улетать на этот IP (причём если прописать этот gateway в resolv.conf - всё равно не работает)

На всякий случай ещё раз обращу внимание, что шлюз — это про маршрутизацию, и скорее всего DNS-запросы на этот IP в качестве DNS-сервера не идут никогда.

mathcrosp ★★ ()
Ответ на: комментарий от deadNightTiger

Там, вроде, ничего примечательного:

[root@docker etc]# 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.18.0.5      6446a43b9573

Novascriptum ()
Ответ на: комментарий от mathcrosp

Если я правильно понял, то вот dig из «плохого» контейнера:

[root@docker etc]# dig ya.ru

; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> ya.ru
;; global options: +cmd
;; connection timed out; no servers could be reached

И вот он же, если прописать в resolv.conf google-dns 8.8.8.8:

[root@docker etc]# dig ya.ru

; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> ya.ru
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19723
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;ya.ru.                         IN      A

;; ANSWER SECTION:
ya.ru.                  23      IN      A       87.250.250.242

;; Query time: 5 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Jun 11 07:19:00 +05 2019
;; MSG SIZE  rcvd: 50
Novascriptum ()
Ответ на: комментарий от Novascriptum

Не, надо понять, какой DNS-сервер используется, когда в контейнере ещё всё хорошо. Потом понять, почему он отваливается.

mathcrosp ★★ ()
Ответ на: комментарий от mathcrosp

Ну вот их «хорошего» контейнера:

[root@3e9a75147f38 /]# dig ya.ru

; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.1 <<>> ya.ru
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24992
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;ya.ru.                         IN      A

;; ANSWER SECTION:
ya.ru.                  426     IN      A       87.250.250.242

;; AUTHORITY SECTION:
ya.ru.                  91      IN      NS      ns1.yandex.ru.
ya.ru.                  91      IN      NS      ns2.yandex.ru.

;; Query time: 2 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Tue Jun 11 05:30:03 UTC 2019
;; MSG SIZE  rcvd: 93

Как я понимаю, доменные имена преобразует сервер 127.0.0.11. Именно он и указан в «плохом» в /etc/resolv.conf. И он как бы не поменялся. И я бы решил, что проблема именно в нём (127.0.0.11), но ошибка-то возникает как раз после «тёмных делишек» bash-скрипта в рассматриваемом контейнере. И, соответственно, в нём и возникает какая-то проблема.

Novascriptum ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.