curl & wget können interne DNS-Namen innerhalb des AKS-Clusters nicht auflösen, aber nslookup, host und dig funktionieren einwandfrei

curl & wget können interne DNS-Namen innerhalb des AKS-Clusters nicht auflösen, aber nslookup, host und dig funktionieren einwandfrei

Ich habe eine verwaltete Kubernetes-Instanz auf Azure. Ich bin sehr sicher, dass der Kern-DNS funktioniert und die DNS-Pods in Ordnung sind.

Ich habe ein paar Dienste

  1. Frontend-Dienst mit einem Pod – Image [nginx-alpine], das die statischen Frontend-Dateien enthält.

  2. Backend-Dienst mit einem Pod – Bild [ubuntu:20.04], das den Node.JS-Code enthält.

Ich kann die internen DNS-Dienstnamen wie frontend-service ODER frontend-service.default.svc.cluster.local nicht aus den Pods des Backends auflösen, aber nslookup, host, dig der internen DNS-Namen werden in die richtige Adresse aufgelöst. Die Backend-Pods können auch die externen DNS-Namen wie google.com auflösen.

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

Beim Versuch, den internen DNS-Namen des Backend-Dienstes aus den Pods des Frontend-Dienstes aufzulösen, funktioniert alles einwandfrei.

Nach einigem Debuggen und einem Blick auf die Protokolle von Coredns und Strace sehe ich, dass während der Ausführung eines Curl kein Aufruf der Coredns-Pods erfolgt, ich kann den Eintrag jedoch bei einem NSlookup sehen.

Ich habe außerdem überprüft, dass /etc/resolv.conf die richtige Konfiguration hat.

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

strace zeigt keinen Eintrag zum Suchen nach /etc/resolv.conf an, daher sucht curl nicht nach /etc/resolv.conf.

Bearbeiten 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

Bearbeiten 2

Ich wollte die Bereitstellung Schritt für Schritt mit demselben Ubuntu:20.04-Image testen und habe daher Folgendes getan.

Ansatz 1

Ich habe im Cluster wie unten einen kurzlebigen Pod erstellt.

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.

Das hat mich verwirrt, also habe ich alle meine Build-Schritte aus der Docker-Datei entfernt und nur die folgenden Befehle verwendet.

Ansatz 2

Docker-Datei

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

Das Image wurde zu ACR gepusht und die Backend-Pods erneut bereitgestellt.

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.

Das ist überraschend, dasselbe Image mit demselben Inhalt – ausgeführt über kubectl run und bereitgestellt über Dockerfile – zeigt ein anderes Verhalten beim Ausführen von curl derselben Version (7.68).

Ich wollte den Ablauf in Strace in beiden Ansätzen sehen. Die Strace-Links finden Sie unter RUN und EXEC

Strace vom laufenden Curl aus der kurzlebigen Schote. https://pastebin.com/NthHQacW

strace vom Ausführen von curl aus dem über Dockerfile bereitgestellten Pod https://pastebin.com/6LCE5NXu

Nach der Analyse der Prüfpfade durch Ausführen von

cat strace-log | grep open

Ich habe festgestellt, dass im Strace-Protokoll von Ansatz 2 die folgenden Zeilen fehlen.


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

Daher sieht sich der Curl-Befehl im Pod weder /etc/resolv.conf noch /etc/nsswitch.conf an.

Ich bin verwirrt, warum das Verhalten von Curl innerhalb von zwei Pods mit demselben Image und derselben Curl-Version im selben Cluster unterschiedlich ist.

Antwort1

Nachdem ich viele Optionen ausprobiert hatte, versuchte ich, meine Bereitstellungskonfigurationsdatei zu debuggen, die ich zum Bereitstellen des Pods im AKS-Cluster verwendete. Ich hatte ein Host-Mount-basiertes Volume, das auf den Pfad „/var/run“ verwies.

Nachdem ich die Host-Einbindung entfernt hatte, funktionierten Curl und Wget wie erwartet.

Nachdem ich dieses Verhalten mit dem MS-Support besprochen hatte, bestätigte dieser, dass curl und wget nicht auf die Datei /etc/resolv.conf zur DNS-Auflösung zurückgreifen, wenn Sie einen Host-Mount haben, der auf den Pfad „/var/run“ zeigt. Dies kann an der Art und Weise liegen, wie die DNS-Prüfung in curl und wget implementiert ist.

verwandte Informationen