VPN ради, прегледач долази до интерних страница, а контејнер и даље не може да раздреши иста имена. Инсталација пакета пада са грешком раздрешивања имена као што је EAI_AGAIN, или апликација не може да пронађе хост базе података који хост машина раздрешује без икакве жалбе. Контејнер не користи резолвер који је VPN инсталирао. Docker је копирао конфигурацију резолвера хоста када је контејнер створен, и ништа је после тога није поново копирало.

Два погледа на резолвер на истој машини

На Linux-у Docker сваком контејнеру даје копију конфигурације резолвера хоста у тренутку стварања, филтрира loopback адресе и покреће уграђени DNS сервер на 127.0.0.11 који прослеђује упите ка споља. VPN клијент који препише /etc/resolv.conf након што је контејнер покренут не мења ништа унутар њега. Поновно покретање контејнера помаже само ако је резолвер хоста у том тренутку случајно исправан.

Docker Desktop на macOS-у или Windows-у додаје слој, јер демон живи у виртуелној машини. Резолвер VPN-а на хосту можда никада неће бити видљив тој VM, па поновно покретање не мења баш ништа. Упореди два погледа пре него што изабереш решење: docker exec mycontainer cat /etc/resolv.conf поред листе резолвера хоста.

Контејнер који наводи јавни резолвер док хост наводи интерни раздрешаваће јавна имена и падати на интерним. Та подела је потпис овог проблема.

Опција А: пренети резолвер тунела по контејнеру

Docker прихвата DNS поставке по контејнеру, што је најмања промена која функционише. Прво прочитај адресе VPN резолвера: scutil --dns на macOS-у, resolvectl status или сопствени статусни излаз клијента на Linux-у. Затим покрени контејнер са њима, на пример docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage. У Compose-у је иста поставка листа испод сервиса, где живи у контроли верзија уместо у нечијој историји наредби.

Низ dns у /etc/docker/daemon.json примењује се на сваки нови контејнер, што звучи уредније него што јесте. Примењује се и када је тунел пао, а резолвер доступан само кроз VPN тада квари уобичајено повлачење слика. Поставке по контејнеру лакше је образложити и лакше поништити.

Опција Б: нека контејнер дели мрежу хоста

Умрежавање хоста у потпуности заобилази копију, јер контејнер користи резолвер хоста и тунел хоста. Оно уклања и мрежну изолацију коју си вероватно желео, и не понаша се исто под Docker Desktop-ом. На Linux-у је то прагматичан избор за једнократни алат који мора да раздрешује интерна имена.

За build-ове не важи ниједна опција, јер кораци build-а не наслеђују заставице времена извршавања. Гради са умрежавањем хоста где платформа то дозвољава, или држи инсталацију зависности у фази којој тунел није потребан.

Шта ниједна опција не поправља

DNS адреса је бескорисна ако контејнер нема руту до ње. Резолвер VPN-а обично седи унутар адресног простора тунела, па контејнеру треба пут до тог префикса. Docker-ов подразумевани мост обично усмерава напоље кроз хост, што је довољно када хост има руту тунела и када је прослеђивање омогућено. Прилагођене мостовне мреже са сопственим базенима адреса могу се сударити са VPN подмрежом, а тада упити одлазе сасвим негде другде.

Провери подмрежу Docker мреже према VPN подмрежи пре него што отклањаш грешке у самом резолверу. Преклапање производи квар који изгледа тачно као покварен DNS сервер.

Провери унутар контејнера

Тестирај са getent hosts db.internal унутар контејнера, а не прегледачем или језичким runtime-ом, јер они примењују сопствену DNS политику и сопствено кеширање. Ако getent раздреши име а апликација и даље пада, резолвер је сада исправан и преостали проблем је на нивоу апликације. Ако га не раздреши, DNS корак није завршен.

Поново креирај контејнер након промене његових DNS поставки. Уређивање /etc/resolv.conf унутар покренутог контејнера нестаје са њим и скрива проблем конфигурације тачно онолико колико некоме треба да га поново покрене.

Повезани чланци