Dev Container nepasiekia tik per VPN prieinamo hosto: kur žiūrėti
Naršyklė ir konteineris turi skirtingus resolver, proxy ir maršrutų kontekstus. Išsiaiškinkite, kurį naudoja nepavykstantis procesas, prieš keisdami bet kurį VPN nustatymą.
Privatus API atsidaro darbalaukio naršyklėje ir nepavyksta kūrimo konteineryje. Tai ne prieštaravimas, ir retai kalta pati VPN. Naršyklės užklausą ir nepavykusią užklausą pateikė skirtingi procesai, su skirtingais resolveriais, proxy ir maršrutais, o dažnai ir iš visiškai skirtingų tinklo vardų erdvių. „Mano nešiojamajame“ gali reikšti Windows hostą, WSL distribuciją, Docker Desktop virtualią mašiną ir konteinerį toje VM — keturi kontekstai, kurių kiekvienas tą patį hosto vardą gali atsakyti skirtingai. Išsiaiškinkite, kurį naudoja nepavykstantis procesas, prieš liesdami bent vieną nustatymą.
Raskite procesą prieš keisdami nustatymą
Pradėkite nuo konteinerių variklio, o ne nuo VPN kliento. Paklauskite, su kokiu kontekstu kalba komandinė eilutė ir kokioje operacinėje sistemoje tas variklis veikia, nes Linux konteineris, valdomas darbalaukio VM, eina kitu keliu nei valdomas vietinio demono:
docker context ls
docker info --format '{{.OperatingSystem}} / {{.Name}}'
docker run --rm alpine ip route
Windows aplinkoje wsl -l -v pasako, ar distribucija veikia pagal WSL 2, o tai pastato ją už savo virtualaus komutatoriaus. Ši detalė nulemia, ar konteineris dalijasi hosto maršrutų lentele, ar yra už NAT, kuriam reikia persiųsto prievado ar hosto vardo, kad pasiektų hostą.
Laikykite vieną užklausą pastovią ir palyginkite
Pasirinkite vieną nekenksmingą galinį tašką privačiame hoste ir naudokite jį kiekvienam palyginimui: iš naršyklės, iš hosto terminalo, iš WSL distribucijos ir iš konteinerio vidaus. Užrašykite keturis dalykus kiekvienam bandymui: išspręstą adresą, ar buvo naudotas proxy, gedimo klasę ir praėjusį laiką. Vardo paieška, ryšio užmezgimas, TLS patikra ir HTTP būsena yra keturios skirtingos problemos, o jų suliejimas į „neveikia“ pražudo visą rytą.
Palyginimą atlikite nepavykstančiame konteineryje, su skirtuoju laiku, kad tyli užkarda nelaikytų terminalo minutėmis. Naujas konteineris atkuria variklio tinklo kontekstą, bet ne programos konteinerio vardų erdvę, proxy kintamuosius ar resolverį, todėl docker exec į tikrąjį konteinerį yra autoritetingas testas, o šalutinis konteineris tėra būdas atskirti, ar skirtumas variklyje, ar konteineryje:
docker exec -it app /bin/sh -c "getent hosts api.internal; curl -v --max-time 8 https://api.internal/ 2>&1 | tail -20"
docker run --rm --network container:app curlimages/curl:latest -sv --max-time 8 https://api.internal/ 2>&1 | tail -20
alpine bazinis atvaizdis turi busybox ir neturi curl, ir būtent tokia detalė sužlugdo nukopijuotą diagnostikos bloką: pasirinkite atvaizdį su klientu arba pridėkite jį tame pačiame paleidime. Palyginimas su nesusijusiomis viešomis svetainėmis nieko neatskiria. Jei https://example.com veikia iš konteinerio, sužinojote, kad konteineris turi prieigą prie interneto, ir nieko apie tai, ar jis pasiekia privatų adresą per tunelį. Taip pat naujo terminalo atidarymas įrodo tik tai, kad naujas terminalas veikia, o ne kad jis dalijasi vykdymo aplinka su nepavykusia programa.
Docker Desktop gali veikti su VPN
Pačios Docker dokumentacija apie VPN ir hosto ryšį aprašo tai kaip palaikomą sąranką, o sąžininga santrauka yra ta, kad ji veikia, o ne būna automatiškai sulaužyta. Nepamanykite, kad darbalaukio VM pagal projektą apeina hosto tunelį; daugelyje sąrankų srautas teisingai eina per hosto tunelį, ir todėl legenda „Docker ignoruoja VPN“ duoda užtikrintus ir neteisingus patarimus.
Tai, kas vis dar svarbu, yra naudojamas backend, kliento split-tunnel politika ir VM gauta resolver konfigūracija. VPN klientas, kuris įdiegia maršrutus, bet ne DNS, arba stumia DNS serverį, kurio VM negali pasiekti, sukelia vardo paieškos gedimą konteineryje, o hostas veikia, nes turi papildomą resolverį ar talpykloje esantį atsakymą. Tai resolverio problema konteinerio kostiumu. Ji išgyvena kiekvieną VPN prisijungimą iš naujo, kurį bandote, nes tunelis jau neša srautą, kurio paprašėte.
Adresų persidengimas ir MTU yra skirtingi gedimai
Du gedimai nusipelno atskiros diagnostikos, nes jie dažnai painiojami su prieigos politika. Pirmasis yra adresų persidengimas: jei VPN stumia diapazoną, kuris susiduria su konteinerių tinklo numatytuoju tilto potinkliu, konteinerio maršrutas tam diapazonui rodo į vietinį tiltą ir niekada nepasiekia tunelio. Tikrinkite tikruosius potinklius, o ne spėliokite:
docker network inspect bridge --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
ip route get 10.20.30.40
Antrasis yra MTU problema. Jei ryšys užmezgamas ir TLS baigiasi, bet didesni atsakymai stringa, turite paketo dydžio problemą, o ne autorizacijos, ir DNS įrašų keitimas to niekada nepataisys. Išbandykite su maža ir didele užklausa prieš ką nors keisdami ir užrašykite abu rezultatus.
Persidengimo sprendimas yra kitas konteinerių potinklis arba apribotas maršrutas, kurį parenka adresų plano savininkas. MTU strigimo sprendimas yra suspausti arba sumažinti tunelio ar sąsajos MTU iki vertės, kuri išlieka kelyje, taikant tame sluoksnyje, kurį kontroliuojate.
Proxy konfigūracija yra kiekvienam procesui, o ne mašinai
Konteinerio viduje localhost įvardija to konteinerio tinklo kontekstą, todėl hoste veikiantis proxy ten nepasiekiamas tuo vardu. Docker Desktop suteikia host.docker.internal prieigai prie hosto, o Linux aplinkoje jį aiškiai pridedate su --add-host=host.docker.internal:host-gateway. Bet kokiu atveju tas vardas duoda jums maršrutą į hostą; jis nesukuria proxy paslaugos ir nesuteikia teisės ja naudotis.
Naudokite proxy adresą ir prievadą, kurie skirti faktinei aplinkai, ir patikrinkite, kas juos skaito. Kintamieji, eksportuoti interaktyvioje shell, automatiškai nesukonfigūruoja kiekvieno redaktoriaus plėtinio, kalbų serverio, build įrankio ir fono demono. Svarbiausias yra procesas, pateikęs nepavykusią užklausą, todėl tikrinkite jo aplinką, o ne savo terminalo.
Galiausiai, leiskite pataisymui paaiškinti save. Naudingas sprendimas įvardija klaidingą ribą, nustatymą, kuris ją pakeitė, ir procesų rinkinį, kuriam jis dabar daro įtaką. VPN, redaktoriaus ir variklio paleidimas iš naujo iš eilės gali pakeisti simptomą, bet nepalieka nieko, ką kitas žmogus galėtų panaudoti.