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 до списокот на резолвери на домаќинот.

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

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

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

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

Опција B: контејнерот да ја дели мрежата на домаќинот

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

За изградби не важи ниту една од двете опции, бидејќи чекорите на изградба не наследуваат знаменца за време на извршување. Изградете со мрежа на домаќинот каде платформата дозволува, или држете ја инсталацијата на зависности во фаза на која не ѝ е потребен тунелот.

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

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

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

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

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

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

Поврзани статии