Kodėl Docker konteineriai nepaiso VPN DNS rezolverio
Konteineris paleidimo metu nukopijuoja pagrindinio kompiuterio rezolverį, todėl vėliau DNS perrašantis VPN lieka jo viduje nematomas. Perduokite rezolverį aiškiai.
VPN veikia, naršyklė pasiekia vidinius puslapius, o konteineris vis dar negali išspręsti tų pačių vardų. Paketo diegimas miršta su vardo sprendimo klaida, pvz., EAI_AGAIN, arba programa neranda duomenų bazės pagrindinio kompiuterio, kurį pagrindinis kompiuteris išsprendžia be jokio nusiskundimo. Konteineris nenaudoja rezolverio, kurį įdiegė VPN. Docker nukopijavo pagrindinio kompiuterio rezolverio konfigūraciją, kai konteineris buvo sukurtas, ir po to niekas jos nebepakartojo.
Du rezolverio vaizdai viename kompiuteryje
Linux sistemoje Docker sukūrimo metu duoda kiekvienam konteineriui pagrindinio kompiuterio rezolverio konfigūracijos kopiją, išfiltruoja loopback adresus ir paleidžia įtaisytą DNS serverį adresu 127.0.0.11, kuris persiunčia užklausas į išorę. VPN klientas, kuris perrašo /etc/resolv.conf po to, kai konteineris paleistas, jo viduje nieko nekeičia. Konteinerio paleidimas iš naujo padeda tik tada, kai tuo metu pagrindinio kompiuterio rezolveris atsitiktinai yra teisingas.
Docker Desktop macOS arba Windows sistemoje prideda sluoksnį, nes demonas gyvena virtualioje mašinoje. Pagrindinio kompiuterio VPN rezolveris gali niekada nebus matomas tai VM, todėl paleidimas iš naujo nieko nekeičia. Palyginkite abu vaizdus prieš rinkdamiesi sprendimą: docker exec mycontainer cat /etc/resolv.conf šalia pagrindinio kompiuterio rezolverių sąrašo.
Konteineris, kuris išvardija viešą rezolverį, o pagrindinis kompiuteris – vidinį, išspręs viešus vardus ir nepavyks su vidiniais. Šis skilimas yra šios problemos parašas.
A variantas: perduoti tunelio rezolverį kiekvienam konteineriui
Docker priima DNS nustatymus kiekvienam konteineriui, ir tai yra mažiausias veikiantis pakeitimas. Pirmiausia perskaitykite VPN rezolverio adresus: scutil --dns macOS, resolvectl status arba paties kliento būsenos išvestis Linux. Tada paleiskite konteinerį su jais, pavyzdžiui, docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage. Compose atveju tas pats nustatymas yra sąrašas po paslauga, kur jis gyvena versijų kontrolėje, o ne kažkieno shell istorijoje.
dns masyvas /etc/docker/daemon.json faile taikomas kiekvienam naujam konteineriui, kas skamba tvarkingiau, nei yra. Jis taikomas ir tada, kai tunelis neveikia, ir tada rezolveris, pasiekiamas tik per VPN, sugadina įprastą atvaizdų atsisiuntimą. Nustatymus kiekvienam konteineriui lengviau pagrįsti ir lengviau atšaukti.
B variantas: leisti konteineriui dalytis pagrindinio kompiuterio tinklu
Pagrindinio kompiuterio tinklas visiškai apeina kopiją, nes konteineris naudoja pagrindinio kompiuterio rezolverį ir pagrindinio kompiuterio tunelį. Jis taip pat pašalina tinklo izoliaciją, kurios tikriausiai norėjote, ir Docker Desktop aplinkoje elgiasi ne taip pat. Linux sistemoje tai pragmatiškas pasirinkimas vienkartiniam įrankiui, kuris turi išspręsti vidinius vardus.
Kūrimui nė vienas variantas netinka, nes kūrimo žingsniai nepaveldi vykdymo vėliavėlių. Kurkite su pagrindinio kompiuterio tinklu ten, kur platforma leidžia, arba laikykite priklausomybių diegimą etape, kuriam tunelio nereikia.
Ko neištaiso nė vienas variantas
DNS adresas nenaudingas, jei konteineris neturi maršruto į jį. VPN rezolveris paprastai yra tunelio adresų erdvėje, todėl konteineriui reikia kelio į tą prefiksą. Docker numatytasis tiltas paprastai maršrutuoja į išorę per pagrindinį kompiuterį, ir to pakanka, kai pagrindinis kompiuteris turi tunelio maršrutą ir persiuntimas įjungtas. Pasirinktiniai tilto tinklai su savo adresų telkiniais gali susidurti su VPN potinkliu, ir tada užklausos nueina visai kitur.
Prieš derindami patį rezolverį, patikrinkite Docker tinklo potinklį su VPN potinkliu. Persidengimas sukuria gedimą, kuris atrodo lygiai kaip sugedęs DNS serveris.
Patikrinkite konteinerio viduje
Išbandykite su getent hosts db.internal konteinerio viduje, o ne su naršykle ar kalbos vykdymo aplinka, nes jos taiko savo DNS politiką ir savo podėlį. Jei getent išsprendžia vardą, o programa vis tiek nepavyksta, rezolveris dabar teisingas, o likusi problema yra programos lygmenyje. Jei neišsprendžia, DNS žingsnis nebaigtas.
Pakeitę DNS nustatymus, sukurkite konteinerį iš naujo. /etc/resolv.conf redagavimas veikiančiame konteineryje išnyksta kartu su juo ir paslepia konfigūracijos problemą lygiai tiek laiko, kiek kažkam reikia jį paleisti iš naujo.