Hvorfor Docker-containere ignorerer VPN’ens DNS-resolver
En container kopierer værtens resolver, når den starter, så en VPN, der senere omskriver DNS, forbliver usynlig indeni. Giv resolveren eksplicit videre.
VPN’en er oppe, browseren når interne sider, og containeren kan stadig ikke slå de samme navne op. En pakkeinstallation dør med en navneopløsningsfejl som EAI_AGAIN, eller et program kan ikke finde en database-vært, som værtsmaskinen slår op uden klager. Containeren bruger ikke den resolver, VPN’en installerede. Docker kopierede værtens resolverkonfiguration, da containeren blev oprettet, og intet kopierede den igen bagefter.
To resolver-visninger på én maskine
På Linux giver Docker hver container en kopi af værtens resolverkonfiguration ved oprettelsen, filtrerer loopback-adresser fra og kører en indbygget DNS-server på 127.0.0.11, som videresender forespørgsler ud. En VPN-klient, der omskriver /etc/resolv.conf, efter at containeren er startet, ændrer intet indeni. Genstart af containeren hjælper kun, hvis værtens resolver tilfældigvis er korrekt i det øjeblik.
Docker Desktop på macOS eller Windows tilføjer et lag, fordi daemonen bor i en virtuel maskine. Værtens VPN-resolver er måske aldrig synlig for den VM, så genstart ændrer slet intet. Sammenlign de to visninger, før du vælger en løsning: docker exec mycontainer cat /etc/resolv.conf ved siden af værtens resolverliste.
En container, der lister en offentlig resolver, mens værten lister en intern, vil slå offentlige navne op og fejle på interne. Den opdeling er signaturen på dette problem.
Mulighed A: giv tunnel-resolveren videre per container
Docker accepterer DNS-indstillinger per container, og det er den mindste ændring, der virker. Læs først VPN’ens resolveradresser: scutil --dns på macOS, resolvectl status eller klientens egen statusudskrift på Linux. Start derefter containeren med dem, for eksempel docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage. I Compose er den samme indstilling en liste under tjenesten, hvor den bor i versionskontrol i stedet for i nogens shell-historik.
Et dns-array i /etc/docker/daemon.json gælder for hver ny container, hvilket lyder pænere, end det er. Det gælder også, når tunnelen er nede, og en resolver, der kun kan nås via VPN’en, ødelægger så almindelige image-hentninger. Indstillinger per container er lettere at begrunde og lettere at fortryde.
Mulighed B: lad containeren dele værtens netværk
Værtsnetværk omgår kopien helt, fordi containeren bruger værtens resolver og værtens tunnel. Det fjerner også den netværksisolering, du sandsynligvis ønskede, og det opfører sig ikke ens under Docker Desktop. På Linux er det det pragmatiske valg til et engangsværktøj, der skal slå interne navne op.
Til builds gælder ingen af mulighederne, da build-trin ikke arver køretidsflag. Byg med værtsnetværk, hvor platformen tillader det, eller hold installationsafhængigheder i et trin, der ikke har brug for tunnelen.
Hvad ingen af mulighederne løser
En DNS-adresse er ubrugelig, hvis containeren ikke har nogen rute til den. VPN’ens resolver sidder normalt inde i tunnelens adresserum, så containeren skal have en vej til det præfiks. Dockers standardbro router normalt ud gennem værten, og det er nok, når værten har tunnelruten, og videresendelse er aktiveret. Brugerdefinerede bro-netværk med egne adressepuljer kan støde sammen med VPN’ens undernet, og så går forespørgslerne et helt andet sted hen.
Tjek Docker-netværkets undernet mod VPN’ens undernet, før du fejlfinder selve resolveren. Overlap giver en fejl, der ser nøjagtigt ud som en ødelagt DNS-server.
Verificér inde i containeren
Test med getent hosts db.internal inde i containeren i stedet for med en browser eller en sprogruntime, fordi de anvender deres egen DNS-politik og deres egen caching. Hvis getent slår navnet op, og programmet stadig fejler, er resolveren nu korrekt, og det resterende problem er på programniveau. Hvis den ikke slår det op, er DNS-trinet ikke færdigt.
Genskab containeren, efter at du har ændret dens DNS-indstillinger. Redigering af /etc/resolv.conf inde i en kørende container forsvinder med den og skjuler konfigurationsproblemet i præcis så lang tid, som det tager nogen at genstarte den.