Jūsu Compose pakalpojums saskaras ar taimautu pret API, ko pārlūks tajā pašā mašīnā atver bez sūdzībām. Šī atšķirība ir pavediens: pieprasījums, kas strādā, iziet no resursdatora ar VPN tuneli, un pieprasījums, kas karājas, iziet no konteinera ar savu tīkla steku. Nekas konteinera iekšienē nezina tuneļa maršrutus, tāpēc privātais galamērķis paliek nesasniedzams, lai kā arī rakstītu nosaukumu. Risinājums ir apzināts lēciens caur resursdatoru, nevis gudrāka maršrutēšanas tabula.

Sāciet ar to, kāpēc abi ceļi atšķiras, pēc tam izlemiet, kur tunelim jādzīvo.

Kāpēc resursdators strādā, bet konteiners ne

Tuneļa pacelšana dod resursdatoram saskarni, maršrutu kopu un parasti VPN nodrošinātu resolvera ierakstu. Konteiners neko no tā nemanto: tas sākas ar vienu saskarni uz dzinēja tilta un noklusējuma maršrutu, kas norāda uz šo tiltu. Resursdatorā instalētie maršruti nav redzami nekam, kas darbojas šajā vārdu telpā.

Tāpēc simptomi šķiet nekonsekventi, nevis vienkārši salūzuši. Resursdators atrisina privāto nosaukumu un savienojas, jo tur pastāv gan nosaukums, gan maršruts. Konteiners sūta savu paketi uz privātu adresi, ko nekas uz tilta ceļa nevar sasniegt, un pieprasījums sasniedz taimautu. Nosaukuma pievienošana konteinera hosts failam neko nemaina, jo pati adrese ir nesasniedzama no vietas, kur atrodas konteiners.

Sasniedziet resursdatoru no konteinera iekšpuses

Process konteinerā, kas zvana localhost, zvana konteineram. Docker Desktop publicē host.docker.internal kā nosaukumu, kas norāda atpakaļ uz mašīnu, kura darbina dzinēju; Linux dzinēji to atstāj nedefinētu, ja vien pakalpojums to nepieprasa, un tieši to dara zemāk esošā kartēšana. Ar to lietojumprogramma mērķē uz nosaukumu un portu, nevis uz privāto adresi.

services:
  app:
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      INTERNAL_API_HOST: "host.docker.internal:8666"

Tunelis paliek resursdatora pusē šim lēcienam, un ports šajā mainīgajā ir tas, kurā starpnieks klausīsies. Konteiners, kas zaudē tuneli, tagad neizdodas vienā zināmā lēcienā, nevis mēģina maršrutu, kāds tam nekad nav bijis.

Izvēlieties, kur dzīvo tunelis

Compose pakalpojumam, kuram nepieciešams privāts API, ir iespējami trīs veidi, un tie atšķiras ar to, kurš process pārvalda tuneli. VPN klients var darboties konteinera attēlā, kas prasa atklāt tuneļa ierīci un piešķirt ar to saistīto tīkla administrēšanas iespēju. Lietojumprogramma var kopīgot atsevišķa tuneļa konteinera tīkla vārdu telpu, tāpēc abi procesi redz vienu steku un vienu maršrutēšanas tabulu. Vai arī tunelis var palikt resursdatorā, ar šauru pāradresētāju no resursdatora konteinerā.

Pirmie divi ievelk profila failus, atkārtotas savienošanas uzvedību un resolvera politiku projektā un padara katru faila pakalpojumu atkarīgu no tuneļa veselības. Tas ir pārāk daudz sasaistes vienam API izsaukumam. Izstrādes stekam, kas lasa vienu iekšēju galapunktu, resursdatora puses pāradresētājs ir mazākā izmaiņa, kas tomēr patur akreditācijas datus tur, kur tos pārvalda platformas komanda.

Publicējiet vienu šauru ceļu resursdatorā

Sāciet ar to, ko pāradresētājs manto: palaidiet to ar kontu, kuram pieder tunelis, un tā izejošās ligzdas pārņems resursdatora maršrutus un resursdatora resolveri. Viens nginx location bloks aptver vienu ceļu.

server {
    listen 8666;
    location /search/ {
        proxy_pass http://10.20.30.40:8090/;
        proxy_set_header Host internal-api.example;
        proxy_read_timeout 60s;
    }
}

Uztveriet adresi un portu kā aizstājējus un ievietojiet pāri, kurā API patiešām klausās. Katrs papildu upstream ir pelnījis savu location bloku, un katram blokam vajadzētu ielaist tikai tos ceļus, kurus izsauc šis pakalpojums, lai starpnieks nekļūtu par vispārīgām durvīm privātajā tīklā. Piesaistiet klausītāju tilta adresei klientiem, kas nāk caur host-gateway, loopback tikai tad, kad klients kopīgo resursdatora tīkla vārdu telpu, un nekad 0.0.0.0. Izvēlieties arī portu, kas vēl ir brīvs: jau aizņemts numurs atstāj starpnieku neklausāmies, kamēr konteiners turpina sasniegt taimautu, ko nevar atšķirt no tīkla kļūmes, ar kuru sākāt.

Porti, nosaukumi un TLS lēmums

Nosaukumu izšķiršana sadalās tāpat kā maršrutēšana. Konteinera publiskie vaicājumi iet caur dzinēja resolveri, tāpēc privāts nosaukums, kas tiek atrisināts resursdatorā, netiks atrisināts konteinera iekšienē. Starpnieks ir komponents, kas atrisina privāto nosaukumu, jo tas manto resursdatora resolveri.

TLS ir lēmums, kas tiek atlikts un pēc tam izskaidro nākamo kļūmi. Ja starpnieks pārsūta baitus neskartus, konteiners redz paša API sertifikātu un tam vajag iekšējo CA savā uzticības krātuvē. Ja starpnieks pabeidz TLS, šī uzticība pāriet uz resursdatoru un lietojumprogramma sāk veidot saites no saņemtās host galvenes. Izvēlieties vienu izkārtojumu un piemērojiet to katram resursam, jo otras izdotais pāradresējums norāda uz resursdatora nosaukumu, ko konteiners nevar atrisināt.

Pārbaudiet no pakalpojuma iekšpuses

Sūtiet pieprasījumu no konteinera, nevis no resursdatora: vienkāršu curl uz starpnieka ceļu, pēc tam pašas lietojumprogrammas veselības pārbaudi. Kad starpnieks atbild, bet lietojumprogramma joprojām neizdodas, salīdziniet trīs lietas: bāzes URL, ko tā veido, jebkuru starpnieka mainīgo tās vidē un CA, kam tā uzticas. Visi tie ir konteinera vidē un žurnālos, un jebkura no tiem izlabošana atstāj VPN mierā.

Ierakstiet izvēlēto izkārtojumu projekta README, kamēr tas vēl ir svaigs. Citādi nākamais cilvēks, kas saskarsies ar šo taimautu, pavadīs to pašu pēcpusdienu no jauna atklājot, ka tunelis dzīvo resursdatorā.

Saistītie raksti