Kontejneri nuk arrin API-në që ofrohet vetëm përmes VPN? Bëji proxy në host
Tuneli jeton në host, ndaj kontejneri nuk ka rrugë drejt adresës private. Publiko një proxy të kundërt të ngushtë dhe thirre atë si host.docker.internal.
Shërbimi yt Compose skadon kohën kundrejt një API që shfletuesi në të njëjtën makinë e hap pa asnjë ankesë. Ky ndryshim është indicja: kërkesa që funksionon del nga një host me tunel VPN, dhe kërkesa që ngec del nga një kontejner me stivën e vet të rrjetit. Asgjë brenda kontejnerit nuk i njeh rrugët e tunelit, ndaj destinacioni privat mbetet i paarritshëm sido që të shkruhet emri. Zgjidhja është një kërcim i qëllimshëm përmes hostit, jo një tabelë rrugësh më e zgjuar.
Fillò me pse dy rrugët ndryshojnë, pastaj vendos ku duhet të jetojë tuneli.
Pse hosti funksionon dhe kontejneri jo
Ngritja e tunelit i jep hostit një ndërfaqe, një grup rrugësh dhe, zakonisht, një zë resolveri të siguruar nga VPN. Kontejneri nuk trashëgon asgjë nga kjo: nis me një ndërfaqe në urën e motorit dhe një rrugë të parazgjedhur që tregon drejt asaj ure. Rrugët e instaluara në host janë të padukshme për çdo gjë që ekzekutohet brenda atij hapësire emrash.
Për këtë arsye simptomat duken jo konsistente dhe jo thjesht të prishura. Hosti e zgjidh emrin privat dhe lidhet, sepse atje ekzistojnë edhe emri edhe rruga. Kontejneri e dërgon paketën e vet drejt një adrese private ku asgjë në rrugën e urës nuk mund të arrijë, dhe kërkesa skadon. Shtimi i emrit në skedarin hosts të kontejnerit nuk ndryshon asgjë, sepse adresa vetë është e paarritshme nga vendi ku ndodhet kontejneri.
Arrije hostin nga brenda kontejnerit
Një proces në kontejner që thërret localhost po thërret kontejnerin. Docker Desktop publikon host.docker.internal si emër që tregon përsëri drejt makinës që ekzekuton motorin; motorët Linux e lënë të papërcaktuar nëse shërbimi nuk e kërkon, dhe kjo është ajo që bën hartëzimi më poshtë. Me këtë, aplikacioni synon një emër dhe një port në vend të adresës private.
services:
app:
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
INTERNAL_API_HOST: "host.docker.internal:8666"Tuneli mbetet në anën e hostit të kërcimit, dhe porti në atë variabël është ai ku proxy do të dëgjojë. Një kontejner që humbet tunelin tani dështon në një kërcim të njohur, në vend që të provojë një rrugë që nuk e kishte kurrë.
Zgjidh ku jeton tuneli
Për një shërbim Compose që ka nevojë për një API privat janë të mundshme tri forma, dhe ato ndryshojnë në atë se cili proces zotëron tunelin. Një klient VPN mund të ekzekutohet brenda imazhit të kontejnerit, çka kërkon ekspozimin e një pajisjeje tuneli dhe dhënien e aftësisë së administrimit të rrjetit që vjen me të. Aplikacioni mund të ndajë hapësirën e emrave të rrjetit të një kontejneri tuneli të veçantë, kështu që të dy proceset shohin një stivë dhe një tabelë rrugësh. Ose tuneli mund të mbetet në host, me një përcjellës të ngushtë nga hosti në kontejner.
Dy të parat tërheqin skedarë profili, sjelljen e rilidhjes dhe politikën e resolverit brenda projektit, dhe e bëjnë çdo shërbim në skedar të varur nga shëndeti i tunelit. Ky është lidhje e tepërt për një thirrje të vetme API. Për një stivë zhvillimi që lexon një pikë të vetme fundore të brendshme, përcjellësi në anën e hostit është ndryshimi më i vogël që i mban kredencialet aty ku ekipi i platformës i administron.
Publiko një shteg të ngushtë në host
Fillò nga ajo që trashëgon përcjellësi: ekzekutoje me llogarinë që zotëron tunelin dhe soketat e tij dalëse marrin rrugët e hostit dhe resolverin e hostit. Një bllok location i nginx mbulon një shteg.
server {
listen 8666;
location /search/ {
proxy_pass http://10.20.30.40:8090/;
proxy_set_header Host internal-api.example;
proxy_read_timeout 60s;
}
}Trajto adresën dhe portin si zëvendësues dhe vendos çiftin ku API dëgjon vërtet. Çdo upstream shtesë meriton bllokun e vet location, dhe çdo bllok duhet të lejojë vetëm shtigjet që thërret ky shërbim, që proxy të mos bëhet derë e përgjithshme në rrjetin privat. Lidhe dëgjuesin me adresën e urës për klientët që vijnë përmes host-gateway, me loopback vetëm kur klienti ndan hapësirën e emrave të rrjetit të hostit, dhe kurrë me 0.0.0.0. Zgjidh edhe një port që është ende i lirë: një numër i zënë tashmë e lë proxy pa dëgjuar ndërsa kontejneri vazhdon të skadojë, çka nuk dallohet nga defekti i rrjetit me të cilin fillove.
Portet, emrat dhe vendimi për TLS
Zgjidhja e emrave ndahet njësoj si rrugëtimi. Kërkimet publike të kontejnerit kalojnë përmes resolverit të motorit, ndaj një emër privat që zgjidhet në host nuk do të zgjidhet brenda kontejnerit. Proxy është komponenti që zgjidh emrin privat, sepse trashëgon resolverin e hostit.
TLS është vendimi që shtyhet dhe pastaj shpjegon dështimin e radhës. Nëse proxy përcjell bajtët të paprekur, kontejneri sheh certifikatën e vetë API-së dhe ka nevojë për CA-në e brendshme në depon e vet të besimit. Nëse proxy përfundon TLS, ai besim kalon në host dhe aplikacioni fillon të ndërtojë lidhje nga koka host që merr. Zgjidh një rregullim dhe zbatoje atë për çdo burim, sepse një ridrejtim i lëshuar nga tjetri tregon një emër hosti që kontejneri nuk mund ta zgjidhë.
Verifiko nga brenda shërbimit
Dërgo kërkesën nga kontejneri, jo nga hosti: një curl i thjeshtë drejt shtegut të proxy, pastaj kontrolli i shëndetit të vetë aplikacionit. Kur proxy përgjigjet por aplikacioni vazhdon të dështojë, krahaso tri gjëra: URL-në bazë që ndërton, çdo variabël proxy në mjedisin e tij dhe CA-në së cilës i beson. Të gjitha janë në mjedisin dhe regjistrat e kontejnerit, dhe rregullimi i cilësdo prej tyre e lë VPN-në në paqe.
Shkruaje rregullimin e zgjedhur në README të projektit sa kohë është i freskët. Përndryshe personi tjetër që ndeshet me këtë skadim kohe do të kalojë të njëjtën pasdite duke rizbuluar se tuneli jeton në host.