Prečo kontajnery Dockeru ignorujú DNS resolver VPN
Kontajner pri spustení skopíruje resolver hostiteľa, takže VPN, ktorá neskôr prepíše DNS, zostáva vnútri neviditeľná. Odovzdajte resolver explicitne.
VPN beží, prehliadač sa dostane na interné stránky, a kontajner napriek tomu nedokáže preložiť rovnaké mená. Inštalácia balíka umiera na chybu prekladu mien, ako je EAI_AGAIN, alebo aplikácia nenájde hostiteľa databázy, ktorého hostiteľský stroj preloží bez jedinej sťažnosti. Kontajner nepoužíva resolver, ktorý VPN nainštalovala. Docker skopíroval konfiguráciu resolvera hostiteľa pri vytvorení kontajnera a potom ju už nič znova neskopírovalo.
Dva pohľady na resolver na jednom stroji
V Linuxe dá Docker každému kontajneru kópiu konfigurácie resolvera hostiteľa v okamihu vytvorenia, odfiltruje adresy loopback a spúšťa vstavaný server DNS na 127.0.0.11, ktorý preposiela dopyty von. Klient VPN, ktorý prepíše /etc/resolv.conf po spustení kontajnera, vnútri nič nezmení. Reštart kontajnera pomôže len vtedy, keď je resolver hostiteľa v tej chvíli náhodou správny.
Docker Desktop na macOS alebo Windows pridáva vrstvu, pretože démon žije vo virtuálnom stroji. Resolver VPN hostiteľa nemusí byť pre tento VM nikdy viditeľný, takže reštart nezmení vôbec nič. Porovnajte oba pohľady, kým zvolíte opravu: docker exec mycontainer cat /etc/resolv.conf vedľa zoznamu resolverov hostiteľa.
Kontajner, ktorý uvádza verejný resolver, zatiaľ čo hostiteľ uvádza interný, preloží verejné mená a zlyhá na interných. Toto rozdelenie je podpisom tohto problému.
Možnosť A: odovzdať resolver tunela pre každý kontajner
Docker prijíma nastavenia DNS pre každý kontajner, a to je najmenšia zmena, ktorá funguje. Najprv si prečítajte adresy resolvera VPN: scutil --dns na macOS, resolvectl status alebo vlastný stavový výstup klienta v Linuxe. Potom kontajner s nimi spustite, napríklad docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage. V Compose je rovnaké nastavenie zoznam pod službou, kde žije v správe verzií namiesto v niekoho histórii shellu.
Pole dns v /etc/docker/daemon.json platí pre každý nový kontajner, čo znie upravenejšie, než je. Platí aj vtedy, keď je tunel mimo prevádzky, a resolver dostupný len cez VPN potom pokazí bežné sťahovanie obrazov. Nastavenia pre jednotlivý kontajner sa ľahšie odôvodňujú a ľahšie vracajú.
Možnosť B: nechajte kontajner zdieľať sieť hostiteľa
Sieť hostiteľa kópiu úplne obchádza, pretože kontajner používa resolver hostiteľa a tunel hostiteľa. Odstraňuje však aj sieťovú izoláciu, ktorú ste pravdepodobne chceli, a pod Docker Desktop sa nespráva rovnako. V Linuxe je to pragmatická voľba pre jednorazový nástroj, ktorý musí prekladať interné mená.
Pre buildy neplatí ani jedna možnosť, keďže kroky buildu nededí prepínače času behu. Buildte so sieťou hostiteľa tam, kde to platforma dovolí, alebo držte inštaláciu závislostí vo fáze, ktorá tunel nepotrebuje.
Čo ani jedna možnosť neopraví
Adresa DNS je nanič, ak k nej kontajner nemá trasu. Resolver VPN zvyčajne sedí v adresnom priestore tunela, takže kontajner potrebuje cestu k tomuto prefixu. Predvolený most Dockeru zvyčajne smeruje von cez hostiteľa, a to stačí, keď má hostiteľ trasu tunela a preposielanie je zapnuté. Vlastné mostové siete s vlastnými fondmi adries sa môžu zraziť s podsieti VPN, a potom dopyty idú úplne inam.
Pred ladením samotného resolvera porovnajte podsiet siete Dockeru s podsieti VPN. Prekrytie vytvára zlyhanie, ktoré vyzerá presne ako pokazený server DNS.
Overte vnútri kontajnera
Testujte pomocou getent hosts db.internal vnútri kontajnera, nie prehliadačom alebo jazykovým runtime, pretože tie uplatňujú vlastnú politiku DNS a vlastnú vyrovnávaciu pamäť. Ak getent preloží meno a aplikácia stále zlyháva, resolver je teraz správny a zostávajúci problém je na úrovni aplikácie. Ak ho nepreloží, krok DNS nie je dokončený.
Po zmene nastavení DNS kontajner znova vytvorte. Úprava /etc/resolv.conf v bežiacom kontajneri zmizne spolu s ním a skryje problém konfigurácie presne na tak dlho, ako niekomu trvá ho reštartovať.