Docker-volumen kan ikke monteres efter VPN-forbindelse: undersøg daemonen
Din bind mount er i orden. En VPN ændrer, hvilken daemon der svarer klienten, så udskriv endpointet, bevis stien der, og hold op med at redigere volumenet.
Næsten enhver beskrivelse af dette problem giver volumenet skylden, og det er netop derfor rettelsen tager så lang tid. Du havde en bind mount, der virkede, den virksomheds-VPN blev forbundet, og docker compose up fejler nu med en manglende kilde-sti, en tom mappe eller en montering, som motoren nægter at oprette. I de miljøer, jeg har ryddet op i, var Compose-filen ikke ændret, og stien var korrekt. Det, der ændrede sig, var hvilken daemon der modtog anmodningen, og monteringsfejlen var blot det første sted, hvor denne forskel blev synlig.
Volumenet flyttede sig aldrig; anmodningen gjorde
Et -v /srv/app:/app flag er ikke en mappe-kopiering, som din shell udfører. Klienten gør det til en API-anmodning, og den daemon, der svarer, opløser /srv/app mod sit eget filsystem. Når begge sider kører på samme kerne, er den sti den, du ser i din filhåndtering. Når endpointet ændres, slås den samme streng op på en maskine, der aldrig har hørt om din projektmappe, og daemonen rapporterer enten kilden som manglende eller opretter lydløst en tom mappe i stedet.
Det er også derfor et navngivet volumen bliver ved med at virke, mens en bind mount ikke gør. -v appdata:/app navngiver lager, som daemonen ejer, så ingen værtssti behøver at findes noget bestemt sted. Hvis det at skifte en tjeneste fra en bind mount til et navngivet volumen får fejlen til at forsvinde, har du ikke løst problemet. Du har bekræftet, at klienten og daemonen er uenige om, hvilket filsystem stien tilhører, og den uenighed vender tilbage i det øjeblik, du igen har brug for en rigtig værtsmappe.
Udskriv endpointet, før du rører monteringen
Flere indstillinger kan pege klienten mod et endpoint, og de er ikke altid enige: et --context flag, DOCKER_CONTEXT, DOCKER_HOST i den aktuelle shell og den kontekst, der er gemt i klientkonfigurationen. I stedet for at ræsonnere om forrang kan du udskrive dem alle og sammenligne svarene.
docker context show
docker context ls
docker version
docker info --format "{{.Name}} {{.OperatingSystem}} {{.ServerVersion}}"
Klientkonfigurationen ligger i ~/.docker/config.json på Linux og macOS og i %USERPROFILE%\.docker\config.json på Windows, og en værdi, der eksporteres i den aktuelle terminal, tilsidesætter den gemte kun for den session. Hvis endpointet er et værtsnavn i stedet for en lokal socket, afgør navneopløsning og ruter, hvor det lander, og det er præcis det, en VPN-klient omskriver. En tunnel, der tilføjer en rute eller skifter resolveren, kan sende et navn, der plejede at betyde denne laptop, til en adresse inde i det virksomhedsnetværk.
Sammenlign tilstand i stedet for konfiguration. Kør docker ps -a og docker images med tunnelen nede, og derefter igen med den oppe. En anden liste af containere er stærkere bevis end nogen konfigurationsfil, fordi den viser, at en anden daemon svarede på din anmodning.
Spørg daemonen, om stien findes der
Når du ved, hvilken daemon du nåede, så få den til at se på mappen. Formen --mount fejler med en klarere meddelelse end det korte flag, fordi den validerer kilden, før den starter containeren:
docker run --rm --mount type=bind,source=/srv/app,target=/app alpine ls -la /app
Hvis den rapporterer kilden som manglende, kan du oprette den på den maskine, der svarede, eller pege tjenesten mod et navngivet volumen og kopiere dataene ind. Det, du ikke bør gøre, er at genskabe volumener og geninstallere motoren før denne kontrol. De handlinger ændrer miljøet nok til at skjule uoverensstemmelsen, mens den bliver på sin plads.
En sti mere kører et helt andet sted: at trække et image er daemon-arbejde, ikke klient-arbejde. Et vellykket træk beviser kun, at daemonen kan nå et registry, og en fungerende bind mount beviser kun, at en sti blev opløst. Test hver sti, hvor den faktisk udføres, ellers bruger du en eftermiddag på den forkerte.
Intranet-navne fejler af en anden grund
Den anden halvdel af den samme rapport er normalt, at containeren ikke kan nå intranet.corp.example. Det er en separat mekanisme, ikke et andet volumenproblem. En container får sin /etc/resolv.conf når den starter, genereret ud fra daemonens resolver-indstillinger, så en DNS-server, som VPN'en tilføjede efter containeren blev oprettet, vises ikke der, før containeren genskabes.
Docker's indbyggede resolver på et brugerdefineret netværk videresender eksterne opslag til værtens konfigurerede servere, hvilket hjælper, når VPN'en omskriver værtsresolveren, og skader, når opdelt DNS sender en intern zone til en server, som daemonen ikke længere ser. En snæver, eksplicit mapping omgår diskussionen for navne, der aldrig ændrer sig:
services:
web:
extra_hosts:
- "intranet.corp.example:10.20.30.40"
Dette skriver en post i containerens hosts-fil, så containeren lærer aldrig noget om tunnelen, og det fryser også adressen. Når den interne vært flytter sig, forbliver posten forkert, indtil nogen redigerer Compose-filen. Brug det til en fast enhed eller en fastlåst database, og lad DNS håndtere navne, der flytter sig.
Hvad en geninstallation faktisk ændrer
Geninstallation af Docker Desktop genskaber VM'en, socket'en og kontekstlisten, og monteringen begynder at virke igen. Det resultat er virkeligt og lærer intet, og derfor vender den samme fejl tilbage efter den næste VPN-opdatering. Geninstallationen erstattede det endpoint, klienten brugte; den forligede ikke den sti, dit projekt navngiver, med det filsystem, daemonen faktisk læser.
Min arbejdsrækkefølge er kort. Bekræft, hvilket endpoint klienten vil bruge. Bekræft, hvilken daemon der svarede, ved at sammenligne containerlister. Bed den daemon om at liste kilde-stien. Først derefter redigerer du monteringen, tilføjer en hosts-post eller ændrer en volumenstype. Hvis du vedligeholder Compose-filen for et team, der arbejder over en VPN, foretræk navngivne volumener til data, som daemonen bør eje, så en værtssti aldrig bliver en del af kontrakten.