Ĉu la ujo ne atingas la nur-VPNan API-on? Starigu proksilon sur la gastiganto
La tunelo loĝas sur la gastiganto, do la ujo havas neniun itineron al la privata adreso. Publikigu mallarĝan inversan proksilon kaj voku ĝin kiel host.docker.internal.
Via Compose-servo tempolimas kontraŭ API, kiun la retumilo sur la sama maŝino malfermas sen plendo. Tiu diferenco estas la indico: la peto, kiu funkcias, forlasas gastiganton kun VPN-tunelo, kaj la peto, kiu pendas, forlasas ujon kun propra reta stako. Nenio ene de la ujo konas la itinerojn de la tunelo, do la privata celo restas neatingebla, kiel ajn la nomo estas literumita. La solvo estas intenca salto tra la gastiganto, ne pli lerta itinertabelo.
Komencu per kial la du vojoj diferencas, poste decidu, kie la tunelo devus loĝi.
Kial la gastiganto funkcias kaj la ujo ne
Levado de la tunelo donas al la gastiganto interfacon, aron da itineroj kaj kutime rizolvan entenon provizitan de la VPN. Ujo heredas neniom el tio: ĝi startas kun unu interfaco sur la ponto de la motoro kaj defaŭlta itinero, kiu montras al tiu ponto. Itineroj instalitaj sur la gastiganto estas nevideblaj por ĉio, kio ruliĝas ene de tiu nomspaco.
Tial la simptomoj aspektas malkonsistaj, ne simple rompitaj. La gastiganto solvas la privatan nomon kaj konektiĝas, ĉar kaj la nomo kaj la itinero ekzistas tie. La ujo sendas sian paketon al privata adreso, kiun nenio sur la pontovojo povas atingi, kaj la peto tempolimas. Aldoni la nomon al la hosts-dosiero de la ujo ŝanĝas nenion, ĉar la adreso mem estas neatingebla de tie, kie la ujo sidas.
Atingu la gastiganton el la interno de la ujo
Procezo en la ujo, kiu telefonalas localhost, telefonalas la ujon. Docker Desktop publikigas host.docker.internal kiel nomon, kiu montras reen al la maŝino, kiu rulas la motoron; Linux-motoroj lasas ĝin nedifinita, se la servo ne petas ĝin, kaj tion faras la mapeado sube. Kun tio la aplikaĵo celas nomon kaj pordon anstataŭ la privatan adreson.
services:
app:
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
INTERNAL_API_HOST: "host.docker.internal:8666"La tunelo restas sur la gastiganta flanko de la salto, kaj la pordo en tiu variablo estas tiu, sur kiu la proksilo aŭskultos. Ujo, kiu perdas la tunelon, nun malsukcesas ĉe unu konata salto anstataŭ provi itineron, kiun ĝi neniam havis.
Elektu, kie la tunelo loĝas
Tri formoj eblas por Compose-servo, kiu bezonas privatan API, kaj ili diferencas laŭ tio, kiu procezo posedas la tunelon. VPN-kliento povas ruliĝi ene de la uja bildo, kio postulas elmeti tunelan aparaton kaj doni la retadministran kapablon, kiu akompanas ĝin. La aplikaĵo povas kunhavigi la retan nomspacon de aparta tunela ujo, do ambaŭ procezoj vidas unu stakon kaj unu itinertabelon. Aŭ la tunelo povas resti sur la gastiganto, kun mallarĝa plusendilo de la gastiganto en la ujon.
La du unuaj trenas profil-dosierojn, rekonektan konduton kaj rizolvan politikon en la projekton, kaj ili igas ĉiun servon en la dosiero dependa de la sano de la tunelo. Tio estas multe da kuplado por unu API-alvoko. Por evoluiga stako, kiu legas unu solan internan finpunkton, la plusendilo sur la gastiganta flanko estas la plej malgranda ŝanĝo, kiu tamen konservas la akreditaĵojn tie, kie la platforma teamo administras ilin.
Publikigu unu mallarĝan vojon sur la gastiganto
Komencu de tio, kion la plusendilo heredas: rulu ĝin sub la konto, kiu posedas la tunelon, kaj ĝiaj eliraj ingoj prenos la itinerojn de la gastiganto kaj la rizolvilon de la gastiganto. Unu nginx location-bloko kovras unu vojon.
server {
listen 8666;
location /search/ {
proxy_pass http://10.20.30.40:8090/;
proxy_set_header Host internal-api.example;
proxy_read_timeout 60s;
}
}Traktu la adreson kaj la pordon kiel anstataŭaĵojn kaj enmetu la paron, sur kiu la API efektive aŭskultas. Ĉiu plua upstream gajnas sian propran location-blokon, kaj ĉiu bloko devus enlasi nur la vojojn, kiujn ĉi tiu servo vokas, por ke la proksilo ne fariĝu ĝenerala pordo en la privatan reton. Ligu la aŭskultanton al la ponta adreso por klientoj, kiuj alvenas per host-gateway, al loopback nur kiam la kliento kunhavigas la retan nomspacon de la gastiganto, kaj neniam al 0.0.0.0. Elektu ankaŭ pordon, kiu ankoraŭ estas libera: numero jam okupita lasas la proksilon ne aŭskulti, dum la ujo daŭre tempolimas, kio ne estas distingebla de la reta fuŝo, kun kiu vi komencis.
Pordoj, nomoj kaj la TLS-decifro
Nomosolvado dividiĝas same kiel enitinero. La publikaj serĉoj de la ujo iras tra la rizolvilo de la motoro, do privata nomo, kiu solviĝas sur la gastiganto, ne solviĝos ene de la ujo. La proksilo estas la komponanto, kiu solvas la privatan nomon, ĉar ĝi heredas la rizolvilon de la gastiganto.
TLS estas la decido, kiu prokrastiĝas kaj poste klarigas la sekvan malsukceson. Se la proksilo plusendas bajtojn sentuŝe, la ujo vidas la propran atestilon de la API kaj bezonas la internan CA en sia fido-stokejo. Se la proksilo finas TLS, tiu fido translokiĝas al la gastiganto kaj la aplikaĵo komencas konstrui ligilojn el la host-kapo, kiun ĝi ricevas. Elektu unu aranĝon kaj aplikigu ĝin al ĉiu rimedo, ĉar alidirekto eldonita de la alia montras al gastignomo, kiun la ujo neniel povas solvi.
Kontrolu el la interno de la servo
Sendu la peton el la ujo, ne de la gastiganto: ordinaran curl al la proksila vojo, poste la propran san-kontrolon de la aplikaĵo. Kiam la proksilo respondas sed la aplikaĵo ankoraŭ malsukcesas, komparu tri aferojn: la bazan URL-on, kiun ĝi konstruas, ajnan proksilan variablon en sia medio, kaj la CA-on, kiun ĝi fidas. Ĉiuj ili troviĝas en la medio kaj protokoloj de la ujo, kaj ripari ajnan el ili lasas la VPN-on trankvila.
Skribu la elektitan aranĝon en la README de la projekto dum ĝi estas freŝa. Alie la sekva persono, kiu trafos ĉi tiun tempolimon, pasigos la saman posttagmezon retrovante, ke la tunelo loĝas sur la gastiganto.