Bakit binabalewala ng mga container ng Docker ang DNS resolver ng VPN
Kinokopya ng container ang resolver ng host kapag nagsimula, kaya ang VPN na nagre-rewrite ng DNS mamaya ay nananatiling hindi nakikita sa loob nito. Ipasok ang resolver nang tahasan.
Naka-on ang VPN, naaabot ng browser ang mga panloob na site, ngunit hindi pa rin maresolba ng container ang parehong mga pangalan. Namamatay ang pag-install ng pakete sa isang error sa pagresolba ng pangalan tulad ng EAI_AGAIN, o hindi mahanap ng application ang isang host ng database na nireresolba ng host machine nang walang anumang reklamo. Hindi ginagamit ng container ang resolver na in-install ng VPN. Kinopya ng Docker ang configuration ng resolver ng host noong ginawa ang container, at walang muling kumopya nito pagkatapos.
Dalawang pananaw ng resolver sa isang makina
Sa Linux, binibigyan ng Docker ang bawat container ng kopya ng configuration ng resolver ng host sa oras ng paggawa, sinasala ang mga address ng loopback, at nagpapatakbo ng embedded na DNS server sa 127.0.0.11 na nagpapasa ng mga query palabas. Ang kliyente ng VPN na nagre-rewrite ng /etc/resolv.conf pagkatapos magsimula ang container ay walang binabago sa loob nito. Ang muling pag-restart ng container ay nakakatulong lamang kung ang resolver ng host ay nagkataong tama sa sandaling iyon.
Ang Docker Desktop sa macOS o Windows ay nagdadagdag ng isang antas, dahil ang daemon ay naninirahan sa isang virtual machine. Maaaring hindi kailanman makita ng VM na iyon ang resolver ng VPN ng host, kaya walang binabago ang pag-restart. Ihambing ang dalawang pananaw bago pumili ng pag-aayos: docker exec mycontainer cat /etc/resolv.conf sa tabi ng listahan ng resolver ng host.
Ang container na naglilista ng pampublikong resolver habang ang host ay naglilista ng panloob ay maresolba ang mga pampublikong pangalan at mabibigo sa mga panloob. Ang paghahating iyon ang pirma ng problemang ito.
Opsyon A: ipasa ang resolver ng tunnel bawat container
Tumatanggap ang Docker ng mga setting ng DNS bawat container, at iyon ang pinakamaliit na pagbabagong gumagana. Basahin muna ang mga address ng resolver ng VPN: scutil --dns sa macOS, resolvectl status o ang output ng status ng kliyente mismo sa Linux. Pagkatapos ay simulan ang container kasama nila, halimbawa docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage. Sa Compose ang parehong setting ay isang listahan sa ilalim ng serbisyo, kung saan ito naninirahan sa version control sa halip na sa kasaysayan ng shell ng isang tao.
Ang array na dns sa /etc/docker/daemon.json ay nalalapat sa bawat bagong container, na mas mukhang maayos at hindi naman. Nalalapat din ito kapag patay ang tunnel, at pagkatapos ay sinisira ng resolver na maabot lamang sa pamamagitan ng VPN ang mga ordinaryong paghila ng image. Ang mga setting bawat container ay mas madaling bigyang-katwiran at mas madaling bawiin.
Opsyon B: hayaang ibahagi ng container ang network ng host
Nilalampasan ng host networking ang kopya nang lubusan, dahil ginagamit ng container ang resolver ng host at ang tunnel ng host. Tinatanggal din nito ang paghihiwalay ng network na marahil ay gusto mo, at hindi ito kumikilos nang pareho sa ilalim ng Docker Desktop. Sa Linux ito ang pragmatikong pagpipilian para sa isahang gamit na tool na kailangang maresolba ang mga panloob na pangalan.
Para sa mga build wala sa dalawang opsyon ang nalalapat, dahil hindi namamana ng mga hakbang ng build ang mga flag ng run time. Mag-build gamit ang network ng host kung saan pinapayagan ng platform, o panatilihin ang pag-install ng mga dependency sa isang yugto na hindi kailangan ang tunnel.
Ang hindi naaayos ng dalawang opsyon
Walang silbi ang address ng DNS kung walang ruta ang container papunta rito. Karaniwang nakaupo ang resolver ng VPN sa loob ng address space ng tunnel, kaya kailangan ng container ng daan patungo sa prefix na iyon. Karaniwang nagruruta palabas ang default bridge ng Docker sa pamamagitan ng host, at sapat iyon kapag may ruta ng tunnel ang host at nakabukas ang forwarding. Ang mga custom na bridge network na may sariling pool ng address ay maaaring bumangga sa subnet ng VPN, at pagkatapos ay napupunta ang mga query sa ibang lugar nang lubusan.
Suriin ang subnet ng network ng Docker laban sa subnet ng VPN bago i-debug ang resolver mismo. Ang magkapatong ay gumagawa ng pagkabigo na eksaktong mukhang sirang DNS server.
I-verify sa loob ng container
Subukan gamit ang getent hosts db.internal sa loob ng container sa halip na browser o runtime ng wika, dahil inilalapat ng mga iyon ang sarili nilang patakaran sa DNS at sarili nilang cache. Kung maresolba ng getent ang pangalan at nabibigo pa rin ang application, tama na ngayon ang resolver at ang natitirang problema ay nasa antas ng application. Kung hindi nito ito maresolba, hindi pa tapos ang hakbang ng DNS.
Muling likhain ang container pagkatapos baguhin ang mga setting ng DNS nito. Ang pag-edit ng /etc/resolv.conf sa loob ng tumatakbong container ay nawawala kasama nito at itinatago ang problema sa configuration sa eksaktong tagal na kailangan ng isang tao upang i-restart ito.