Docker konteineris nepasiekiamas per VPN? Palyginkite potinklius
Dockeras išduoda potinklį, į kurį pretenduoja ir VPN. Palyginkite abu adresų planus ir pasirinkite taisymą, kuris išliks po pakartotinio prisijungimo.
Konteineriai atsako biuro vietiniame tinkle, o tada nustoja atsakinėti tą akimirką, kai prisijungia įmonės VPN. Konteineryje niekas nepasikeitė: jokio perkrovimo, jokio atvaizdžio atnaujinimo, jokio konfigūracijos pakeitimo. Pasikeitė pagrindinio kompiuterio maršrutų lentelė, kurioje tunelio pridėtas maršrutas dabar apima adresą, kurį išdavė Docker. Prieš taisydami potinklį ar prašydami VPN išimties, sudėkite abu adresų planus greta, nes taisymai kainuoja labai skirtingai laiko atžvilgiu.
Perskaitykite maršrutą prieš keisdami konfigūraciją
Pradėkite nuo tinklo, kurį Docker iš tikrųjų sukūrė. IPAM blokas yra adresų planas, o potinklis – ta eilutė, kuri svarbi:
docker network inspect project_default --format '{{json .IPAM.Config}}'
# [{"Subnet":"172.18.0.0/16","Gateway":"172.18.0.1"}]Pagal numatytuosius nustatymus Compose kiekvienam naujam projektui skiria /16, todėl dvi paslaugos gali tilpti 65,536 adresų diapazone. Būtent dėl šio platumo persidengimai tokie dažni: atsitiktinai parinktas /16 yra pakankamai didelis, kad prarytų svetainę, kurią pasiekiate per tunelį, ir niekas to nepastebi, kol tunelis neįsijungia.
Tada palyginkite maršruto parinkimą vienam konteinerio adresui: vieną kartą, kai tunelis išjungtas, ir vieną kartą, kai jis įjungtas:
ip route get 172.18.0.7
# 172.18.0.7 dev br-3f2a9c src 172.18.0.1Du atsakymo variantai veda į skirtingas vietas. Jei išvestyje nurodytas tun0, wg0 ar kitas tunelio įrenginys, VPN priešdėlis yra bent tiek pat konkretus kaip tilto maršrutas, ir paketas niekada nepasiekia konteinerio. Jei vis dar nurodytas tiltas, pagrindinis kompiuteris pasiekia konteinerį, o jūsų problema yra filtravimas, DNS arba grįžtamasis kelias, kuris sugenda tik viena kryptimi.
Kodėl /16 susidūrimą lengva sukelti
Docker ima tilto tinklus iš privačių telkinių, o numatytasis telkinys sudaromas iš 172.16.0.0/12 bloko /16 gabalais. Įmonių tinklai dažnai naudoja tą pačią privačią erdvę, o nuotolinės prieigos VPN stumia tuos priešdėlius kiekvienam prisijungiančiam klientui. Kai abi pusės tiki, kad joms priklauso 172.18.0.0/16, vienoje maršrutų lentelėje atsiduria du prieštaraujantys teiginiai.
Laimi ne maršrutų eilės tvarka, o priešdėlio ilgis. Tunelis, stumiantis 10.0.0.0/8, nenugali tilto maršruto 172.18.0.0/16, nes /8 yra mažiau konkretus. Tunelis, stumiantis 172.18.0.0/16 arba 172.18.5.0/24 jo viduje, nugali. Štai kodėl vienas nešiojamasis kompiuteris veikia biuro tinkle, o to paties VPN atveju nepavyksta viešbučio Wi-Fi tinkle: klientas gauna skirtingus priešdėlius.
Ta pati lentelė valdo ir priešingą kryptį. Konteineris, kuriam reikia vidinio kompiuterio adresu 10.8.4.20, siunčia paketą savo tilto tinklų vartams, o pagrindinis kompiuteris tada nukreipia jį į tunelį. Šis kelias paprastai veikia, nes NAT atlieka pagrindinis kompiuteris, bet nepavyksta, kai įmonės pusė priima tik nešiojamojo kompiuterio VPN adresą arba kai atvirkštinio kelio filtravimas atmeta asimetrišką atsakymą.
Palyginkite tris taisymo būdus
Yra tik trys išeitys, ir jos skiriasi tuo, kas turi jas patvirtinti ir kas lūžta jas taikant.
| Repair | Who owns it | What it costs |
|---|---|---|
| Renumber the container network | You | Recreates the network, restarts services, invalidates literal addresses in configs and scripts |
| Exclude your range from the tunnel | Network team | Changes what every laptop sees, needs a change request and a client profile update |
| Reach the service through a published port | You and the client | One port only, no direct container-to-container routing across the tunnel |
Pernumeravimas – vienintelis taisymas, kurį galima atlikti be prašymo, todėl dauguma aprašų tuo ir baigiasi. Jauname projekte tai pigu, o pabrangsta, kai migracijos įrankis ar išsaugota prisijungimo eilutė nurodo tiesioginį adresą. Suskaičiuokite tas nuorodas prieš redaguodami YAML, o ne po to.
Išimtis iš tunelio yra švariausias sprendimas, kai persidengimas yra diapazone, kuris tikrai priklauso jūsų įmonei. Tai ir lėčiausias variantas, be to, jis nenaudingas rangovui, kuris negali pakeisti kliento profilio. Paskelbtas prievadas ar nedidelis atvirkštinis tarpinis serveris išvengia ginčo: klientas kreipiasi į adresą, kurį tunelis jau nukreipia teisingai, ir pasiekiamas turi būti tik tas prievadas.
Priskirkite diapazoną sąmoningai
Vienam projektui deklaruokite potinklį compose faile, kad projektas nustotų imti iš bendro telkinio:
networks:
default:
ipam:
config:
- subnet: 10.201.7.0/24Imkite tą diapazoną iš registro, kurį tvarko jūsų komanda, o ne iš pavyzdžio, kurį radote paieškoje. Patikrinkite jį pagal priešdėlius, kuriuos stumia VPN, namų tinklus, iš kurių žmonės dirba, ir kitus konteinerių tinklus tame pačiame pagrindiniame kompiuteryje. Tada suplanuokite atkūrimą, nes esamas tinklas išsaugo savo senąjį potinklį: docker compose down, tada up -d. docker network rm atsisako, kol prijungti galiniai taškai, o bet koks ipv4_address įrašas faile turi patekti į naują diapazoną.
Tinklams, kuriuos Docker kuria savarankiškai, nustatykite tarnybos telkinį faile /etc/docker/daemon.json:
{
"default-address-pools": [
{ "base": "10.201.0.0/16", "size": 24 },
{ "base": "10.202.0.0/16", "size": 24 }
]
}Telkinys taikomas tinklams, sukurtiems po tarnybos perkrovimo, o jau esami tiltai išsaugo savo adresus. Tai patogu ir lengva pamiršti, todėl seną projektą laikykite vis dar persidengiančiu, kol kas nors atkurs jo tinklą. Docker variklio tinklų dokumentacija aprašo paskirstymo taisykles, jei peržiūroje reikia apginti telkinį.
Linux tiltas ir Docker Desktop genda skirtingai
Linux pagrindiniame kompiuteryje konteineriai yra ant tiltų pagrindinėje vardų erdvėje. Viską sprendžia viena lentelė, todėl aukščiau pateiktas palyginimas yra visa istorija: perskaitykite tilto maršrutą, perskaitykite tunelio maršrutą ir pažiūrėkite, kuris laimi tikram konteinerio adresui.
Docker Desktop pastato konteinerius už virtualiosios mašinos, turinčios savo NAT. Pagrindinis kompiuteris apskritai neturi maršruto į konteinerio adresą; paslaugą jis pasiekia per paskelbtą prievadą, paprastai susietą su 127.0.0.1. Todėl VPN klientas gali sugadinti paslaugą be jokio potinklių persidengimo: arba įdiegdamas maršrutą virtualiosios mašinos vidiniam diapazonui, arba blokuodamas loopback srautą, kol tunelis prijungtas. Jei ip route get pagrindiniame kompiuteryje praneša, kad konteinerio adresui maršruto nėra, tai tikėtina, o ne klaida.
Praktinė pasekmė – nuo ko pradėti. Linux atveju pradėkite nuo maršrutų lentelės. Desktop atveju pradėkite nuo paskelbto prievado ir VPN kliento užkardos taisyklių, tada patikrinkite, ar virtualiosios mašinos vidinis potinklis nesidengia su tuo, ką stumia tunelis.
Patikrinkite įjungus tunelį
Prieš sakydami, kad sutvarkyta, du kartus prisijunkite prie VPN iš naujo, nes profilis, kuris prisijungus prideda maršrutus, o atsijungus juos atšaukia, po pirmo bandymo gali atrodyti taisyklingas. Tada atlikite patikras, kurias iš tikrųjų atlieka klientas:
ip route getiš pagrindinio kompiuterio, naudojant tikrąjį konteinerio adresą.- Užklausa iš kito konteinerio, įrodanti, kad pati paslauga sveika.
curl -sv http://127.0.0.1:8080/iš kliento, kai tunelis įjungtas, tadatraceroute -nį konteinerio adresą iš kompiuterio vietiniame tinkle.sysctl net.ipv4.conf.all.rp_filter, jei užklausa pasiekia pagrindinį kompiuterį, bet atsakymas dingsta.
Galiausiai įrašykite pasirinktą diapazoną į tą patį registrą, iš kurio jį rinkotės, nurodydami datą ir jį valdantį projektą. Kitas persidengimas ateis iš projekto, kurio niekas nedokumentavo, o vienintelė gynyba – diapazonas buvo rezervuotas sąmoningai, o ne parinktas atsitiktinai.