Pripojenie zväzku Docker zlyhá po pripojení VPN: skontrolujte daemona
Váš bind mount je v poriadku. VPN mení, ktorý daemon odpovedá klientovi, preto vypíšte endpoint, dokážte cestu tam a prestaňte upravovať zväzok.
Takmer každý text o tomto probléme obviňuje zväzok, a práve preto oprava trvá tak dlho. Mali ste bind mount, ktorý fungoval, firemná VPN sa pripojila a docker compose up teraz zlyháva s chýbajúcou cestou k zdroju, prázdnym adresárom alebo pripojením, ktoré engine odmieta vytvoriť. V prostrediach, ktoré som upratoval, sa súbor Compose nezmenil a cesta bola správna. Zmenilo sa to, ktorý daemon dostal požiadavku, a chyba pripojenia bola len prvým miestom, kde sa tento rozdiel stal viditeľným.
Zväzok sa nikdy nepohol; požiadavka áno
Prepínač -v /srv/app:/app nie je kópia adresára, ktorú vykonáva váš shell. Klient z neho urobí požiadavku API a daemon, ktorý odpovedá, vyhodnocuje /srv/app voči svojmu vlastnému systému súborov. Keď obe strany bežia na tom istom jadre, je to tá cesta, ktorú vidíte v správcovi súborov. Keď sa endpoint zmení, ten istý reťazec sa hľadá na stroji, ktorý o adresári vášho projektu nikdy nepočul, a daemon buď oznámi zdroj ako chýbajúci, alebo na jeho mieste ticho vytvorí prázdny adresár.
To je aj dôvod, prečo pomenovaný zväzok funguje ďalej, kým bind mount nie. -v appdata:/app pomenúva úložisko, ktoré daemon vlastní, takže žiadna cesta hostiteľa nemusí existovať na konkrétnom mieste. Ak výmena jednej služby z bind mountu za pomenovaný zväzok spôsobí, že chyba zmizne, problém ste neopravili. Potvrdili ste, že klient a daemon sa nezhodujú v tom, ktorému systému súborov cesta patrí, a tento nesúlad sa vráti vo chvíli, keď znova potrebujete skutočný adresár hostiteľa.
Vypíšte endpoint, skôr než sa dotknete pripojenia
Niekoľko nastavení môže nasmerovať klienta na endpoint a nie vždy sa zhodujú: --context prepínač, DOCKER_CONTEXT, DOCKER_HOST v aktuálnom shelli a kontext uložený v konfigurácii klienta. Namiesto uvažovania o priorite vypíšte všetky a porovnajte odpovede.
docker context show
docker context ls
docker version
docker info --format "{{.Name}} {{.OperatingSystem}} {{.ServerVersion}}"
Konfigurácia klienta je v ~/.docker/config.json na Linuxe a macOS a v %USERPROFILE%\.docker\config.json na Windows a hodnota exportovaná v aktuálnom termináli prepisuje uloženú len pre túto reláciu. Ak je endpoint názov hostiteľa namiesto lokálneho socketu, o tom, kam dopadne, rozhoduje preklad názvov a trasy, a práve tie klient VPN prepisuje. Tunel, ktorý pridá trasu alebo vymení resolver, môže poslať názov, ktorý kedysi znamenal tento notebook, na adresu vnútri firemnej siete.
Porovnávajte stav, nie konfiguráciu. Spustite docker ps -a a docker images s vypnutým tunelom a potom znova so zapnutým. Iný zoznam kontajnerov je silnejší dôkaz než akýkoľvek konfiguračný súbor, pretože ukazuje, že na vašu požiadavku odpovedal iný daemon.
Opýtajte sa daemona, či tam cesta existuje
Keď viete, ku ktorému daemonovi ste sa dostali, prinúťte ho pozrieť sa na adresár. --mount forma zlyhá s jasnejšou správou ako krátky prepínač, pretože overuje zdroj skôr, než spustí kontajner:
docker run --rm --mount type=bind,source=/srv/app,target=/app alpine ls -la /app
Ak oznámi zdroj ako chýbajúci, vytvorte ho na stroji, ktorý odpovedal, alebo nasmerujte službu na pomenovaný zväzok a skopírujte tam údaje. Čo by ste robiť nemali, je znova vytvárať zväzky a preinštalovať engine pred touto kontrolou. Tie akcie menia prostredie natoľko, že nesúlad skryjú, ale ponechajú ho na mieste.
Ešte jedna cesta beží úplne inde: sťahovanie image je práca daemona, nie klienta. Úspešné stiahnutie dokazuje len to, že sa daemon dostane do registry, a fungujúci bind mount len to, že sa cesta vyhodnotila. Testujte každú cestu tam, kde sa skutočne vykonáva, inak strávite popoludnie na tej nesprávnej.
Názvy z intranetu zlyhávajú z iného dôvodu
Druhá polovica tej istej správy býva, že kontajner sa nedostane na intranet.corp.example. To je samostatný mechanizmus, nie druhý problém so zväzkom. Kontajner dostane svoj /etc/resolv.conf pri štarte, vygenerovaný z nastavení resolvera daemona, takže server DNS, ktorý VPN pridala po vytvorení kontajnera, sa v ňom neobjaví, kým kontajner znova nevytvoríte.
Vstavaný resolver Dockeru na používateľsky definovanej sieti preposiela externé dopyty na nakonfigurované servery hostiteľa, čo pomáha, keď VPN prepisuje resolver hostiteľa, a škodí, keď rozdelený DNS pošle internú zónu na server, ktorý daemon už nevidí. Úzke, explicitné mapovanie obíde spor pri názvoch, ktoré sa nikdy nemenia:
services:
web:
extra_hosts:
- "intranet.corp.example:10.20.30.40"
Tým sa zapíše záznam do súboru hosts kontajnera, takže kontajner sa o tuneli nič nedozvie, a tiež sa adresa zafixuje. Keď sa interný hostiteľ presunie, záznam zostane nesprávny, kým niekto neupraví súbor Compose. Použite ho pre pevné zariadenie alebo pripnutú databázu a názvy, ktoré sa hýbu, nechajte na DNS.
Čo preinštalácia skutočne zmení
Preinštalácia Docker Desktop znova vytvorí VM, socket a zoznam kontextov a pripojenie začne znova fungovať. Ten výsledok je skutočný a nič nenaučí, a preto sa tá istá porucha vráti po ďalšej aktualizácii VPN. Preinštalácia nahradila endpoint, ktorý klient používal; nezjednotila cestu, ktorú váš projekt pomenúva, so systémom súborov, ktorý daemon skutočne číta.
Môj postup je krátky. Potvrďte, ktorý endpoint klient použije. Potvrďte, ktorý daemon odpovedal, porovnaním zoznamov kontajnerov. Požiadajte toho daemona, aby vypísal cestu k zdroju. Až potom upravte pripojenie, pridajte záznam hosts alebo zmeňte typ zväzku. Ak spravujete súbor Compose pre tím, ktorý pracuje cez VPN, uprednostnite pomenované zväzky pre údaje, ktoré má daemon vlastniť, aby sa cesta hostiteľa nikdy nestala súčasťou kontraktu.