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, цяпер пытаецца ў кантэйнера тунеля, а не ў нагрузкі.
Запішыце схему, уключна з тым, які кантэйнер валодае прасторай імёнаў і якія парты ёй належаць. Наступны чалавек дадасць службу, скапіюе не той блок і ўзнавіць першы збой у гэтым артыкуле.