Docker: насочете еден контејнер низ VPN и оставете друг директен
Дајте му на тунелот сопствен контејнер, дозволете само на услугите на кои им е потребен да го делат тој простор од имиња, потоа земете го предвид она што го следи сопственикот: порти, localhost, DNS.
Еден домаќин, две работни оптоварувања и барање што ги разделува: клиент за преземање што мора да излезе низ комерцијален VPN и интерфејс за управување што мора да продолжи да ја користи врската на домаќинот. Инсталирањето на VPN клиентот на домаќинот веднаш го прекршува барањето, бидејќи тогаш двете оптоварувања делат еден излез. Моделот што навистина функционира е да го преместите тунелот во негов сопствен контејнер и да дозволите само на оптоварувањата на кои им е потребен да се приклучат на мрежниот простор од имиња на тој контејнер. Сè друго го задржува вообичаениот Docker пат, а деталите што следат се последици од тоа кој го поседува просторот од имиња.
Зошто заедничкиот простор од имиња ги менува правилата
Контејнер што се приклучува на просторот од имиња на друг не добива сопствен мрежен стек. Ги гледа истите интерфејси, истата табела за рутирање и истиот loopback како контејнерот кон кој се приклучил, и токму затоа моделот е корисен: оптоварувањето нормално разрешува и се поврзува, а тунелот под него го фаќа сообраќајот без апликацијата да знае. Цената е што секое мрежно поставување сега има еден сопственик, а контејнерот што се приклучува не е тој.
Ова правило за сопственост одговара на повеќето конфигурациски прашања пред воопшто да бидат поставени. Ако поставувањето живее во мрежниот стек, му припаѓа на страничниот контејнер. Ако го опишува процесот, останува со оптоварувањето.
Loopback е делот што ги изненадува луѓето. Внатре во контејнерот што се приклучува, localhost се разрешува на loopback на страничниот контејнер, а не на сопствен приватен, така што услугата што се врзува на 127.0.0.1 очекувајќи изолација сега ја дели таа адреса со контејнерот на тунелот.
Објавете порти на контејнерот што го поседува просторот од имиња
Мапирањето на порти му припаѓа на сопственикот на просторот од имиња, дури и кога процесот што слуша работи во другиот контејнер. Објавете го мапирањето на страничниот контејнер, а оптоварувањето нека ја задржи сопствената конфигурација на процесот недопрена. Мапирање на услугата што се приклучува не може да стапи на сила, без разлика дали двигателот го одбива или тивко го игнорира зависно од тоа како контејнерот се стартува, и затоа интерфејсот што беше достапен пред момент исчезнува штом моделот се примени.
services:
gluetun:
image: qmcgaw/gluetun
cap_add: [NET_ADMIN]
ports: ["8080:8080"]
client-vpn:
image: example/client
network_mode: "service:gluetun"
client-direct:
image: example/client
ports: ["8081:8080"]Читајте го овој блок како три одлуки, а не три услуги. Страничниот контејнер го поседува тунелот и објавената порта; клиентот што се приклучува воопшто не објавува мрежа; директниот клиент го задржува сопственото мапирање на стандардната мрежа. Способноста NET_ADMIN е она што му овозможува на страничниот контејнер да создава интерфејси и да менува рути, и тоа е причината зошто овој контејнер бара повеќе привилегии од оптоварувањата што ги опслужува.
Услугата што останува директна ја задржува сопствената мрежа
Оптоварувањето што не смее да помине низ тунелот го задржува стандардниот мост или сопствена мрежа дефинирана од корисникот, со сопствена објавена порта и сопствен излез. Примамливо е да го прикачите на мрежата на страничниот контејнер за двете контејнери да можат да зборуваат по име, но тој еден чекор тивко го преместува неговиот сообраќај во тунелот. Ако треба да се достигнат, изградете посебна мрежа дефинирана од корисникот, прикачете ги двата на неа и оставете го страничниот контејнер како единствен пат кон надвор.
Држете ги двете прашања одделно: кои контејнери можат да се достигнат и кој од каде излегува. Нивното спојување е најчестиот начин на кој овој дизајн повторно станува VPN за целиот домаќин.
Матрица на откази за првиот час
Повеќето први обиди не успеваат на еден од четири начини и секој има различен причинител. Проверете ги по овој редослед, бидејќи првите два објаснуваат речиси секој извештај.
| Symptom | Likely cause |
|---|---|
| Web UI unreachable after the change | Port mapping declared on the joining container instead of the sidecar |
| Both containers show the provider's exit address | The direct service was attached to the sidecar network |
| Internal names stop resolving | Resolver settings live on the host, not in the shared namespace |
| Health check fails but the app works | The check probes localhost, which now means the sidecar |
Четвртиот ред е оној што луѓето погрешно го дијагностицираат како грешка во апликацијата. Проверката напишана против сопствениот loopback на оптоварувањето сега го тестира контејнерот на тунелот, па или не успева или пријавува сосема погрешна услуга.
Кога едно име на домаќин има потреба од тунелот
Понекогаш целосниот тунел е премногу: едно внатрешно име мора да помине низ корпоративен VPN, додека локален сокет или врска за екран продолжува да работи. Целосниот тунел внатре во контејнерот го крши тој пат и сè што е адресирано до домаќинот, затоа рутирајте само го префиксот на кој му е потребно. Обвивка за поделено рутирање околу клиентот го прави тоа, го испраќа именуваниот домаќин низ тунелот и ја остава претходната рута недопрена за сè друго.
Изберете го ова кога треба да достигнете само една услуга и не се обидувате да го преместите целиот сообраќај на контејнерот. Тоа е различен алат од страничниот контејнер и одговара на различно прашање.
Проверете, потоа направете го отпорно на рестартирање
Прашајте го секој контејнер од која адреса изгледа дека доаѓа. Оној во тунелот треба да ја испечати адресата на провајдерот, а директниот излезот на домаќинот. Идентичните одговори значат дека директната услуга наследила погрешен простор од имиња или дека VPN на ниво на домаќин сè уште го фаќа сè, и тие две поправки се различни. Пуштете ја проверката повторно по секое уредување на compose, бидејќи еден копиран блок на услуга е доволен за да се врати проблемот.
Три работи имаат тенденција да се расипат подоцна. DNS го следи сопственикот на просторот од имиња, затоа поставувањата на резолверот и доменот за пребарување му припаѓаат на страничниот контејнер, а не на домаќинот. VPN со препраќање на порти го менува својот порта за слушање при повторно поврзување, затоа препратената порта на провајдерот и портата за слушање на страната на контејнерот мора да се запишат назад во конфигурацијата на клиентот или во мапирањето на порти, обично со мал ажурирач што го чита API на провајдерот. И секоја проверка напишана против localhost сега го прашува контејнерот на тунелот, а не оптоварувањето.
Запишете го моделот, вклучително кој контејнер го поседува просторот од имиња и кои порти му припаѓаат. Следниот човек ќе додаде услуга, ќе го копира погрешниот блок и ќе го репродуцира првиот отказ во оваа статија.