Konteineris, kuris nepasiekia nieko už įmonės VPN, paprastai gyvena kitoje tinklo vardų srityje nei tunelis. Mazgo kliento maršrutai, DNS serveriai ir ugniasienės žymos priklauso mazgo krūvai; tilto tinklo konteineris turi savą. Šis vienas faktas paaiškina daugumą pranešimų, kurie pasiekia platformos komandą, ir jis taip pat paaiškina, kodėl „VPN sugedęs“ ir „Docker apeina VPN“ gali būti neteisingi vienu metu. Už vieno simptomo slypi dvi labai skirtingos konfigūracijos, todėl nustatykite, kurią turite, prieš keisdami bet kokį nustatymą.

Išsiaiškinkite, kam priklauso tunelio vardų sritis

„Docker Desktop“, skirtoje „macOS“ arba „Windows“, konteineriai veikia Linux virtualioje mašinoje. Darbalaukyje įdiegtas VPN klientas sukuria tunelį darbalaukio operacinėje sistemoje, o virtualioji mašina jo niekada nemato. Jokia konteinerio konfigūracija to nepataiso, nes sąsaja, kurios konteineriui reikėtų, jo tinklo vardų srityje apskritai neegzistuoja.

Linux mazge tunelis gyvena mazgo vardų srityje, o tilto konteineriai paprastai jį pasiekia per mazgo maršrutizavimo lentelę, išeinant taikant šaltinio NAT. Kai šis kelias nepavyksta, priežastis paprastai būna persiuntimo politika, atvirkštinio kelio filtravimas arba persidengiantis potinklis, o ne trūkstamas maršrutas. Patvirtinkite, kuriame iš dviejų pasaulių esate, prieš skaitydami toliau:

docker info --format '{{.OperatingSystem}}'
docker run --rm --net=host alpine ip route | head -5
docker run --rm alpine ip route | head -5

Skirtumas tarp šių dviejų maršrutizavimo lentelių yra visa problema viename ekrane. Jei mazgo rodinyje yra tunelio sąsaja, o tilto rodinyje ne, matote vardų sričių izoliaciją, o visa kita yra pasirinkimas, kaip ją pereiti.

Mazgo tinklas yra bandymas, o ne projektas

Konteinerio paleidimas su mazgo tinklu, kurį „Docker“ dokumentuoja kaip mazgo tinklo vardų srities bendrinimą, leidžia jam tiesiogiai paveldėti tunelio sąsają ir jos maršrutus. Jei ta pati užklausa tada pavyksta, maršrutų teorija patvirtinama, o gedimas yra vardų sričių izoliacija, o ne kredencialai, DNS ar prieigos taisyklė.

docker run --rm --net=host curl -sS -o /dev/null -w '%{http_code}\n' https://api.internal/health

Laikykite tai diagnostika. Mazgo tinklas atsisako prievadų publikavimo ir didžiosios dalies izoliacijos, kurios norėjote iš konteinerio, o „Docker Desktop“ atveju „host“ reiškia virtualiąją mašiną, o ne darbalaukį, todėl sėkmė ar nesėkmė ten gali suklaidinti, jei pamiršite, kurį mazgą kreipėtės.

tun įrenginys ir su juo ateinančios privilegijos

VPN klientui konteineryje reikia tunelio įrenginio ir leidimo jį sukonfigūruoti. Įprastas sprendimas yra --privileged, kuris suteikia visus įrenginius ir sušvelnina saugumo politiką visame konteineryje. Tai daug daugiau, nei reikalauja šis darbas, ir tai sunku pateisinti peržiūroje.

sudo modprobe tun
docker run --rm -it --device /dev/net/tun --cap-add NET_ADMIN myvpn-client

Siauresnė forma susieja vieną įrenginio mazgą ir prideda tik tinklo administravimo galimybę. Pirmiausia įkelkite modulį mazge, kad mazgas egzistuotų. Jei konteineris paleidžiamas ir klientas praneša, kad negali atidaryti tunelio įrenginio, patikrinkite susiejimą prieš įtardami profilį, nes ši klaida paprastai yra pažodinė.

Šis projektas taip pat reiškia, kad klientas veikia kiekviename konteineryje. Tai teisingas atsakymas, kai kiekvienam darbo krūviui reikia savo tunelio, ir neteisingas, kai tik norėjote, kad mazgo tunelis būtų matomas, ką platformos komanda tikriausiai manė, kad darote.

Tilto NAT keičia šaltinį, kurį mato VPN

Naudojant numatytąjį tiltą, išeinantis konteinerio srautas verčiamas mazgo adresu. Todėl už VPN įmonės pusė mato mazgo tunelio adresą, o ne konteinerio, prieigos taisyklės pagal šaltinį elgiasi taip, tarsi užklausą būtų išsiuntęs mazgas, ir du konteineriai tampa neatskiriami VPN serveriui.

macvlan arba ipvlan vietoj to suteikia konteineriui LAN adresą, kuris padeda aptikti LAN ir leidžia konteineriui atrodyti kaip lygiaverčiui segmente. Jis taip pat visiškai apeina mazgo tunelį, todėl toks konteineris nepasieks tik VPN skirtų priešdėlių, nebent VPN būtų pasiekiamas ir iš to LAN.

Abi formos yra teisėtos; jos atsako į skirtingus reikalavimus. Jei reikalavimas yra „šis konteineris turi pasiekti tik VPN skirtą paslaugą“, renkatės tarp maršrutizavimo per mazgą ir tunelio užbaigimo konteineryje. Užrašykite šį pasirinkimą prieš diegimą, o ne po pirmos nesėkmingos užklausos. Kad ir ką pasirinktumėte, užsirašykite šaltinio adresą, kurį matys tolimasis galas, nes būtent jį parodys jo prieigos taisyklės ir žurnalai. Projektas, kuris negali nurodyti šio adreso, nėra baigtas.

DNS seka daemoną, o ne tunelį

Konteineris gauna savo sprendėjo konfigūraciją paleidimo metu, nukopijuotą iš daemono arba atvaizdo. Adresai, kuriuos VPN stumia po prisijungimo, ateina per vėlai šiai kopijai, ir jie stumiami į mazgo sprendėją, o ne į konteinerį.

Nustatykite sprendėją aiškiai paslaugai arba nukreipkite jį į vidinį sprendėją, pasiekiamą per tunelį. Konteineris, kuris privatų vardą išsprendžia į viešą adresą, paprastai naudoja viešą sprendėją, o ne kenčia nuo sugedusio maršruto, o taisymas priklauso compose failui arba daemono konfigūracijai.

Tas pats samprotavimas galioja išėjimo adreso klausimui. Jei kiekvienas konteineris turi pasirodyti iš skirtingo VPN adreso, vienas mazgo tunelis to negali užtikrinti, nes NAT juos sujungia į vieną šaltinį. Veikiančios formos yra klientas kiekvieno konteinerio vardų srityje arba sidecar, kuris valdo tunelį ir bendrina savo krūvą, ir abi keičia tai, kaip programėlė adresuojama.

Kontrolinis sąrašas prieš uždarant bilietą: nustatykite vardų sritį, kuriai priklauso tunelis, įrodykite kelią mazgo tinklu, susiekite tik reikiamą tun įrenginį, atsiminkite šaltinio adresą po NAT, aiškiai nustatykite sprendėją ir traktuokite kiekvieno konteinerio išėjimo adresus kaip architektūrinį sprendimą, o ne vėliavėlę.

Susiję straipsniai