Gotovo svaki tekst o ovom problemu okrivljuje volumen i upravo zato popravak traje tako dugo. Imali ste bind montiranje koje je radilo, korporativni VPN se spojio i docker compose up sada ne uspijeva zbog nedostajuće izvorne putanje, praznog direktorija ili montiranja koje engine odbija stvoriti. U okruženjima koja sam počistio, Compose datoteka nije bila promijenjena i putanja je bila ispravna. Promijenilo se to koji je daemon primio zahtjev, a greška montiranja bila je samo prvo mjesto na kojem je ta razlika postala vidljiva.

Volumen se nikada nije pomaknuo; zahtjev se pomaknuo

Zastavica -v /srv/app:/app nije kopiranje direktorija koje izvodi vaš shell. Klijent je pretvara u API zahtjev, a daemon koji odgovara razrješava /srv/app prema vlastitom datotečnom sustavu. Kada obje strane rade na istom kernelu, ta putanja je ona koju vidite u upravitelju datoteka. Kada se endpoint promijeni, isti se niz traži na stroju koji nikada nije čuo za direktorij vašeg projekta, pa daemon ili prijavi izvor kao nedostajući ili tiho stvori prazan direktorij na njegovom mjestu.

To je i razlog zašto imenovani volumen nastavlja raditi, a bind montiranje ne. -v appdata:/app imenuje pohranu koju daemon posjeduje, pa nijedna putanja hosta ne mora postojati na određenom mjestu. Ako zamjena jedne usluge s bind montiranja na imenovani volumen učini da greška nestane, niste riješili problem. Potvrdili ste da se klijent i daemon ne slažu oko toga kojem datotečnom sustavu putanja pripada, a to neslaganje vraća se u trenutku kada ponovno zatrebate pravi direktorij hosta.

Ispišite endpoint prije nego što dirnete u montiranje

Nekoliko postavki može usmjeriti klijent na endpoint i one se ne slažu uvijek: zastavica --context , DOCKER_CONTEXT, DOCKER_HOST u trenutnom shellu i kontekst spremljen u konfiguraciji klijenta. Umjesto da razmišljate o prioritetu, ispišite sve i usporedite odgovore.

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

Konfiguracija klijenta nalazi se u ~/.docker/config.json na Linuxu i macOS-u te u %USERPROFILE%\.docker\config.json na Windowsu, a vrijednost izvezena u trenutnom terminalu nadjačava spremljenu samo za tu sesiju. Ako je endpoint ime hosta umjesto lokalnog socketa, razrješavanje imena i rute odlučuju gdje će sletjeti, a upravo to VPN klijent prepisuje. Tunel koji dodaje rutu ili mijenja resolver može poslati ime koje je nekada označavalo ovo prijenosno računalo na adresu unutar korporativne mreže.

Usporedite stanje umjesto konfiguracije. Pokrenite docker ps -a i docker images s isključenim tunelom, pa ponovno s uključenim. Drugačiji popis kontejnera jači je dokaz od bilo koje konfiguracijske datoteke, jer pokazuje da je na vaš zahtjev odgovorio drugi daemon.

Pitajte daemon postoji li putanja tamo

Kada znate kojem ste daemonu došli, natjerajte ga da pogleda direktorij. Oblik --mount ne uspijeva s jasnijom porukom od kratke zastavice, jer provjerava izvor prije nego što pokrene kontejner:

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

Ako prijavi izvor kao nedostajući, stvorite ga na stroju koji je odgovorio ili usmjerite uslugu na imenovani volumen i kopirajte podatke unutra. Ono što ne biste trebali raditi je ponovno stvaranje volumena i ponovna instalacija enginea prije ove provjere. Te radnje mijenjaju okruženje dovoljno da sakriju nesklad, a ostavljaju ga na mjestu.

Još jedna putanja odvija se posve drugdje: povlačenje slike posao je daemona, ne klijenta. Uspješno povlačenje dokazuje samo da daemon može doći do registryja, a ispravno bind montiranje samo da se putanja razriješila. Testirajte svaku putanju tamo gdje se stvarno izvodi, inače ćete potrošiti poslijepodne na pogrešnu.

Imena intraneta ne uspijevaju iz drugog razloga

Druga polovica istog izvještaja obično je da kontejner ne može doći do intranet.corp.example. To je odvojen mehanizam, a ne drugi problem s volumenom. Kontejner dobiva svoj /etc/resolv.conf pri pokretanju, generiran iz postavki resolvera daemona, pa se DNS poslužitelj koji je VPN dodao nakon stvaranja kontejnera neće pojaviti u njemu dok se kontejner ne ponovno stvori.

Ugrađeni Docker resolver na mreži koju je definirao korisnik prosljeđuje vanjske upite konfiguriranim poslužiteljima hosta, što pomaže kada VPN prepisuje resolver hosta, a šteti kada split DNS pošalje internu zonu na poslužitelj koji daemon više ne vidi. Usko, izričito mapiranje zaobilazi raspravu za imena koja se nikada ne mijenjaju:

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

To upisuje zapis u datoteku hosts kontejnera, pa kontejner nikada ne sazna ništa o tunelu, a također zamrzava adresu. Kada se interni host premjesti, zapis ostaje pogrešan dok netko ne uredi Compose datoteku. Koristite ga za fiksni uređaj ili prikvačenu bazu podataka, a imena koja se kreću prepustite DNS-u.

Što ponovna instalacija zapravo mijenja

Ponovna instalacija Docker Desktopa ponovno stvara VM, socket i popis konteksta, a montiranje ponovno počinje raditi. Taj je ishod stvaran i ničemu ne uči, zato se ista greška vraća nakon sljedećeg VPN ažuriranja. Ponovna instalacija zamijenila je endpoint koji je klijent koristio; nije uskladila putanju koju vaš projekt imenuje s datotečnim sustavom koji daemon stvarno čita.

Moj redoslijed rada je kratak. Potvrdite koji će endpoint klijent koristiti. Potvrdite koji je daemon odgovorio usporedbom popisa kontejnera. Zamolite taj daemon da izlista izvornu putanju. Tek tada uredite montiranje, dodajte zapis u hosts ili promijenite vrstu volumena. Ako održavate Compose datoteku za tim koji radi preko VPN-a, preferirajte imenovane volumene za podatke koje daemon treba posjedovati, kako putanja hosta nikada ne bi postala dio ugovora.

Povezani članci