Beveik kiekvienas šios problemos aprašymas kaltina tomą, ir būtent todėl pataisymas užima tiek laiko. Turėjote veikiantį bind mount, įmonės VPN prisijungė, ir docker compose up dabar nepavyksta dėl trūkstamo šaltinio kelio, tuščio katalogo arba prijungimo, kurio variklis atsisako sukurti. Aplinkose, kurias sutvarkiau, Compose failas nebuvo pakeistas, o kelias buvo teisingas. Pasikeitė tai, kuris demonas gavo užklausą, o prijungimo klaida buvo tik pirmoji vieta, kur šis skirtumas tapo matomas.

Tomas niekada nejudėjo; judėjo užklausa

Vėliavėlė -v /srv/app:/app nėra katalogo kopija, kurią atlieka jūsų shell. Klientas paverčia ją API užklausa, o atsakantis demonas išsprendžia /srv/app savo paties failų sistemoje. Kai abi pusės veikia tame pačiame branduolyje, tas kelias yra tas, kurį matote failų tvarkyklėje. Kai endpoint pasikeičia, ta pati eilutė ieškoma mašinoje, kuri niekada negirdėjo apie jūsų projekto katalogą, ir demonas arba praneša, kad šaltinio nėra, arba tyliai sukuria tuščią katalogą jo vietoje.

Štai kodėl pavadintas tomas veikia toliau, o bind mount – ne. -v appdata:/app įvardija saugyklą, kurią valdo demonas, todėl joks pagrindinės mašinos kelias neturi egzistuoti konkrečioje vietoje. Jei vienos paslaugos perkėlimas iš bind mount į pavadintą tomą pašalina klaidą, jūs problemos neišsprendėte. Jūs patvirtinote, kad klientas ir demonas nesutaria, kuriai failų sistemai priklauso kelias, ir tas nesutarimas grįžta tą akimirką, kai vėl prireikia tikro pagrindinės mašinos katalogo.

Atspausdinkite endpoint prieš liesdami prijungimą

Keli nustatymai gali nukreipti klientą į endpoint, ir jie ne visada sutaria: --context vėliavėlė, DOCKER_CONTEXT, DOCKER_HOST dabartiniame shell, ir kliento konfigūracijoje išsaugotas kontekstas. Užuot samprotavę apie pirmumą, atspausdinkite visus ir palyginkite atsakymus.

docker context show
docker context ls
docker version
docker info --format "{{.Name}} {{.OperatingSystem}} {{.ServerVersion}}"

Kliento konfigūracija yra ~/.docker/config.json Linux ir macOS, o %USERPROFILE%\.docker\config.json Windows, ir dabartiniame terminale eksportuota reikšmė pakeičia išsaugotą tik tai sesijai. Jei endpoint yra pagrindinės mašinos vardas, o ne vietinis socket, vardų sprendimas ir maršrutai nusprendžia, kur jis nusileis, ir būtent tai perrašo VPN klientas. Tunelis, kuris prideda maršrutą arba pakeičia resolverį, gali nusiųsti vardą, kuris anksčiau reiškė šį nešiojamąjį kompiuterį, į adresą įmonės tinkle.

Palyginkite būseną, o ne konfigūraciją. Paleiskite docker ps -a ir docker images su išjungtu tuneliu, tada vėl su įjungtu. Skirtingas konteinerių sąrašas yra stipresnis įrodymas už bet kurį konfigūracijos failą, nes rodo, kad į jūsų užklausą atsakė kitas demonas.

Paklauskite demono, ar kelias ten egzistuoja

Kai žinote, kurį demoną pasiekėte, leiskite jam pažiūrėti į katalogą. --mount forma nepavyksta su aiškesniu pranešimu nei trumpoji vėliavėlė, nes patikrina šaltinį prieš paleisdama konteinerį:

docker run --rm --mount type=bind,source=/srv/app,target=/app alpine ls -la /app

Jei jis praneša, kad šaltinio nėra, sukurkite jį mašinoje, kuri atsakė, arba nukreipkite paslaugą į pavadintą tomą ir nukopijuokite duomenis ten. Ko neturėtumėte daryti – iš naujo kurti tomus ir perinstaliuoti variklį prieš šį patikrinimą. Tie veiksmai pakankamai pakeičia aplinką, kad paslėptų neatitikimą, bet palieka jį vietoje.

Dar vienas kelias eina visai kitur: image traukimas yra demono, o ne kliento darbas. Sėkmingas traukimas įrodo tik tai, kad demonas pasiekia registry, o veikiantis bind mount – tik tai, kad kelias buvo išspręstas. Tikrinkite kiekvieną kelią ten, kur jis iš tikrųjų vykdomas, kitaip praleisite popietę su netinkamu.

Intraneto vardai nepavyksta dėl kitos priežasties

Antroji tos pačios ataskaitos pusė paprastai yra tai, kad konteineris negali pasiekti intranet.corp.example. Tai atskiras mechanizmas, o ne antra tomo problema. Konteineris gauna savo /etc/resolv.conf paleidžiant, sugeneruotą iš demono resolverio nustatymų, todėl DNS serveris, kurį VPN pridėjo po konteinerio sukūrimo, ten nepasirodys, kol konteineris nebus sukurtas iš naujo.

Docker įtaisytasis resolveris vartotojo apibrėžtame tinkle persiunčia išorines užklausas į pagrindinės mašinos sukonfigūruotus serverius, o tai padeda, kai VPN perrašo pagrindinės mašinos resolverį, ir kenkia, kai skaidomas DNS siunčia vidinę zoną serveriui, kurio demonas nebemato. Siauras, aiškus susiejimas apeina ginčą dėl vardų, kurie niekada nesikeičia:

services:
  web:
    extra_hosts:
      - "intranet.corp.example:10.20.30.40"

Tai įrašo įrašą į konteinerio hosts failą, todėl konteineris nieko nesužino apie tunelį, ir taip pat užšaldo adresą. Kai vidinis pagrindinės mašinos vardas pasislenka, įrašas lieka klaidingas, kol kas nors nesuredaguoja Compose failo. Naudokite jį fiksuotam įrenginiui ar prisegtai duomenų bazei, o judančius vardus palikite DNS.

Ką iš tikrųjų pakeičia perinstaliavimas

Docker Desktop perinstaliavimas iš naujo sukuria VM, socket ir kontekstų sąrašą, ir prijungimas vėl pradeda veikti. Tas rezultatas yra tikras ir nieko neišmoko, todėl ta pati gedimas grįžta po kito VPN atnaujinimo. Perinstaliavimas pakeitė endpoint, kurį naudojo klientas; jis nesuderino kelio, kurį įvardija jūsų projektas, su failų sistema, kurią demonas iš tikrųjų skaito.

Mano darbo tvarka trumpa. Patvirtinkite, kurį endpoint naudos klientas. Palyginę konteinerių sąrašus patvirtinkite, kuris demonas atsakė. Paprašykite to demono išvardyti šaltinio kelią. Tik tada redaguokite prijungimą, pridėkite hosts įrašą arba pakeiskite tomo tipą. Jei prižiūrite Compose failą komandai, kuri dirba per VPN, pirmenybę teikite pavadintiems tomams duomenims, kuriuos demonas turėtų valdyti, kad pagrindinės mašinos kelias niekada netaptų sutarties dalimi.

Susiję straipsniai