curl и wget не могут разрешить внутренние имена DNS в кластере aks, но nslookup, host, dig работают нормально

curl и wget не могут разрешить внутренние имена DNS в кластере aks, но nslookup, host, dig работают нормально

У меня есть управляемый экземпляр kubernetes на azure. Я полностью уверен, что основной dns работает и dns pods здоровы.

У меня есть пара услуг

  1. frontend-service с одним модулем — образ [nginx-alpine], содержащий статические файлы frontend.

  2. backend-service с одним модулем - Образ [ubuntu:20.04], содержащий код nodejs.

Я не могу разрешить внутренние имена служб DNS, такие как frontend-service ИЛИ frontend-service.default.svc.cluster.local из pod'ов бэкенда, но nslookup, host, dig внутренних имен DNS разрешаются в правильный адрес. Поды бэкенда также могут разрешать внешние имена DNS, такие как google.com.

curl http://frontend-service
curl: (6) Could not resolve host: frontend-service

curl http://frontend-service.default.svc.cluster.local
curl: (6) Could not resolve host: frontend-service.default.svc.cluster.local
wget frontend-service
--2020-08-31 23:36:43--  http://frontend-service
Resolving frontend-service (frontend-service)... failed: Name or service not known.
wget: unable to resolve host address 'frontend-service'
/etc/nsswitch.conf shows the below :

passwd:         files
group:          files
shadow:         files
gshadow:        files

hosts:          files dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

Все работает нормально при попытке разрешить внутреннее DNS-имя бэкэнд-службы из модулей фронтэнд-службы.

После некоторой отладки и просмотра журналов coredns и strace я вижу, что при выполнении curl не происходит никаких вызовов модулей coredns, но я вижу запись при выполнении nslook up.

Я также проверил, что /etc/resolv.conf имеет правильную конфигурацию.

nameserver 10.3.0.10
search default.svc.cluster.local svc.cluster.local cluster.local tdghymxumodutbxfnz5m2elcog.bx.internal.cloudapp.net
options ndots:5

strace не показывает ни одной записи для поиска /etc/resolv.conf, поэтому curl не проверяет /etc/resolv.conf.

Редактировать 1

From the backend service pod :
dig frontend-service [It is able to resolve to the correct name server.]


; <<>> DiG 9.16.1-Ubuntu <<>> frontend-service
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 13441
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; OPT=65436: 87 a1 ee 81 04 d8 5a 49 be 0e c4 ed 1d d8 27 41 ("......ZI......'A")
;; QUESTION SECTION:
;frontend-service.            IN      A

;; AUTHORITY SECTION:
.                       30      IN      SOA     a.root-servers.net. nstld.verisign-grs.com. 2020083101 1800 900 604800 86400

;; Query time: 20 msec
;; SERVER: 10.3.0.10#53(10.3.0.10)
;; WHEN: Tue Sep 01 10:48:00 IST 2020
;; MSG SIZE  rcvd: 142

nslookup frontend-service

Server:         10.3.0.10
Address:        10.3.0.10#53

Name:   frontend-service.default.svc.cluster.local
Address: 10.3.0.30
host frontend-service     
frontend-service.default.svc.cluster.local has address 10.3.0.30

Редактировать 2

Я хотел протестировать развертывание шаг за шагом с тем же образом ubuntu:20.04, поэтому я сделал следующее.

Подход 1

Я создал временный модуль в кластере, как показано ниже.

kubectl run -it --rm test-ubuntu --image=ubuntu:20.04 --restart=Never

Installed curl (7.68) and ran the curl http://frontend-service – This is successful.

Это меня озадачило, поэтому я удалил все шаги сборки из Dockerfile и использовал только приведенные ниже команды.

Подход 2

Dockerfile

FROM ubuntu:20.04
 
EXPOSE 3688
CMD [ "sleep", "infinity" ]

Отправил образ в acr и снова развернул внутренние модули.

kubectl exec -it <pod-name> /bin/bash

I installed curl (7.68) and ran the curl http://frontend-service – Same error – unable to resolve host.

Это удивительно, один и тот же образ с одинаковым содержимым — запуск через kubectl run и развертывание через Dockerfile — ведет себя по-разному при запуске curl той же версии (7.68).

Я хотел увидеть поток в strace в обоих подходах. Пожалуйста, найдите ссылки strace из RUN и EXEC

след от бегущего завитка из эфемерного стручка. https://pastebin.com/NthHQacW

strace из запущенного curl из модуля, развернутого через Dockerfile https://pastebin.com/6LCE5NXu

После анализа зондирующих путей путем запуска

cat strace-log | grep open

Я обнаружил, что в журнале strace из подхода 2 отсутствуют следующие строки.


2844  openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/etc/host.conf", O_RDONLY|O_CLOEXEC <unfinished...>
2844  <... openat resumed>)             = 7
2844  openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC <unfinished ...>
2844  <... openat resumed>)             = 7
2844  openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 7

Таким образом, команда curl внутри модуля не просматривает ни /etc/resolv.conf, ни /etc/nsswitch.conf.

Я озадачен, почему поведение curl в двух модулях с одинаковым изображением и одинаковой версией curl в одном кластере отличается.

решение1

Перепробовав множество вариантов, я попытался отладить свой файл конфигурации развертывания, который я использовал для развертывания pod в кластере AKS. У меня был том на основе монтирования хоста, который указывал на путь "/var/run".

После того, как я удалил монтирование хоста, curl и wget заработали как и ожидалось.

После обсуждения этого поведения со службой поддержки MS они подтвердили, что curl и wget не возвращаются к файлу /etc/resolv.conf для разрешения DNS, если ваш хост смонтирован по пути "/var/run". Это может быть связано со способом реализации проверки DNS в curl и wget.

Связанный контент