Konteiner ei jõua VPN-i taga oleva API-ni? Tee hostile pöördproksi
Tunnel elab hostil, seega konteineril pole privaatse aadressi jaoks marsruuti. Avalda kitsas pöördproksi ja kutsu seda nimega host.docker.internal.
Sinu Compose-teenus jookseb ajapiirini API vastu, mille sama masina brauser avab ilma ühegi kaebuseta. Just see vahe on vihje: töötav päring väljub hostilt, kus on VPN-tunnel, ja takerduv päring väljub konteinerist, millel on oma võrgupino. Miski konteineri sees ei tea tunneli marsruute, seega jääb privaatne sihtkoht kättesaamatuks ükskõik kuidas nime kirjutada. Lahendus on teadlik hüpe läbi hosti, mitte nutikam marsruutimistabel.
Alusta sellest, miks kaks teed erinevad, ja otsusta siis, kus tunnel peaks elama.
Miks host töötab ja konteiner mitte
Tunneli ülespanek annab hostile liidese, hulga marsruute ja tavaliselt VPN-i antud resolveri kirje. Konteiner ei päri sellest midagi: see algab ühe liidesega mootori sillal ja vaikemarsruudiga, mis osutab sellele sillale. Hostile paigaldatud marsruudid on nähtamatud kõigele, mis jookseb selle nimeruumi sees.
Seepärast näivad sümptomid ebajärjekindlad, mitte lihtsalt katki. Host lahendab privaatse nime ja ühendub, sest seal on olemas nii nimi kui ka marsruut. Konteiner saadab oma paketi privaatsele aadressile, milleni miski sillateel ei jõua, ja päring jookseb ajapiirini. Nime lisamine konteineri hosts-faili ei muuda midagi, sest aadress ise on kättesaamatu sealt, kus konteiner asub.
Jõua hostini konteineri seest
Protsess konteineris, mis helistab localhost-ile, helistab konteinerile. Docker Desktop avaldab host.docker.internal nime, mis osutab tagasi masinale, mis mootorit käitab; Linuxi mootorid jätavad selle määratlemata, kui teenus seda ei küsi, ja täpselt seda teeb allolev vastendus. Sellega sihib rakendus nime ja porti privaatse aadressi asemel.
services:
app:
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
INTERNAL_API_HOST: "host.docker.internal:8666"Tunnel jääb hüppe hostipoolele ja selle muutuja port on see, millel proksi hakkab kuulama. Tunneli kaotanud konteiner ebaõnnestub nüüd ühel teadaoleval hüppel, selle asemel et proovida marsruuti, mida tal kunagi polnud.
Vali, kus tunnel elab
Privaatset API-t vajava Compose-teenuse jaoks on võimalikud kolm kuju ja need erinevad selle poolest, milline protsess tunneli omanik on. VPN-klient võib joosta konteineri image’i sees, mis nõuab tunnelseadme avamist ja sellega kaasneva võrguadministreerimise võime andmist. Rakendus võib jagada eraldi tunnelikonteineri võrgu nimeruumi, nii et mõlemad protsessid näevad üht pino ja üht marsruutimistabelit. Või võib tunnel jääda hostile, kitsa edasisaatjaga hostist konteinerisse.
Kaks esimest tõmbavad profiilifailid, taasühendumise käitumise ja resolveri poliitika projekti ning teevad iga failis oleva teenuse sõltuvaks tunneli tervisest. See on ühe API-kutse jaoks liiga palju sidumist. Arenduspino jaoks, mis loeb üht sisemist lõpp-punkti, on hostipoolne edasisaatja väikseim muudatus, mis hoiab siiski volitusi seal, kus platvormimeeskond neid haldab.
Avalda hostil üks kitsas tee
Alusta sellest, mida edasisaatja pärib: käivita see kontoga, mis tunnelit omab, ja selle väljuvad soklid võtavad üle hosti marsruudid ja hosti resolveri. Üks nginx location-plokk katab ühe tee.
server {
listen 8666;
location /search/ {
proxy_pass http://10.20.30.40:8090/;
proxy_set_header Host internal-api.example;
proxy_read_timeout 60s;
}
}Käsitle aadressi ja porti asendajatena ning pane sisse paar, millel API tegelikult kuulab. Iga täiendav upstream väärib oma location-plokki ja iga plokk peaks lubama ainult teid, mida see teenus kutsub, et proksi ei muutuks üldiseks ukseks privaatvõrku. Seo kuulaja silla aadressiga klientidele, kes saabuvad host-gateway kaudu, loopbackiga ainult siis, kui klient jagab hosti võrgu nimeruumi, ja mitte kunagi aadressiga 0.0.0.0. Vali ka port, mis on veel vaba: juba hõivatud number jätab proksi mitte kuulama, samal ajal kui konteiner jätkab ajapiirini jooksmist, mida ei saa eristada võrguveast, millega alustasid.
Pordid, nimed ja TLS-i otsus
Nimelahendus jaguneb samamoodi nagu marsruutimine. Konteineri avalikud päringud käivad läbi mootori resolveri, seega privaatne nimi, mis laheneb hostil, ei lahene konteineri sees. Proksi on komponent, mis lahendab privaatse nime, sest see pärib hosti resolveri.
TLS on otsus, mis lükatakse edasi ja mis seejärel selgitab järgmist tõrget. Kui proksi edastab baidid puutumata, näeb konteiner API enda sertifikaati ja vajab oma usaldushoidlas sisemist CA-d. Kui proksi lõpetab TLS-i, liigub see usaldus hostile ja rakendus hakkab linke ehitama saadud host-päise põhjal. Vali üks lahendus ja rakenda seda igale ressursile, sest teise poolt väljastatud ümbersuunamine osutab hostinimele, mida konteiner ei suuda lahendada.
Kontrolli teenuse seest
Saada päring konteinerist, mitte hostilt: tavaline curl proksi teele ja seejärel rakenduse enda tervisekontroll. Kui proksi vastab, aga rakendus ikka ebaõnnestub, võrdle kolme asja: baas-URL, mille see ehitab, mis tahes proksimuutuja selle keskkonnas ja CA, mida see usaldab. Kõik need on konteineri keskkonnas ja logides ning ükskõik millise parandamine jätab VPN-i puutumata.
Kirjuta valitud lahendus projekti README-sse, kuni see on veel värske. Muidu veedab järgmine inimene, kes selle ajapiirini jookseb, sama pärastlõuna avastades uuesti, et tunnel elab hostil.