Skoraj vsak zapis o tej težavi krivi zvezek, in prav zato popravilo traja tako dolgo. Imeli ste bind mount, ki je deloval, korporativni VPN se je povezal in docker compose up zdaj spodleti z manjkajočo potjo do vira, praznim imenikom ali priklopom, ki ga pogon noče ustvariti. V okoljih, ki sem jih počistil, se datoteka Compose ni spremenila in pot je bila pravilna. Spremenilo se je, kateri daemon je prejel zahtevo, in napaka pri priklopu je bila le prvo mesto, kjer je ta razlika postala vidna.

Zvezek se ni nikoli premaknil; zahteva se je

Zastavica -v /srv/app:/app ni kopija imenika, ki bi jo izvedla vaša lupina. Odjemalec jo spremeni v zahtevo API, daemon, ki odgovori, pa razreši /srv/app glede na svoj lastni datotečni sistem. Ko obe strani tečeta na istem jedru, je ta pot tista, ki jo vidite v upravitelju datotek. Ko se endpoint spremeni, se isti niz išče na stroju, ki ni nikoli slišal za imenik vašega projekta, in daemon bodisi sporoči, da vir manjka, bodisi na njegovem mestu tiho ustvari prazen imenik.

Zato tudi poimenovani zvezek deluje naprej, bind mount pa ne. -v appdata:/app poimenuje shrambo, ki jo daemon ima, zato nobena pot gostitelja ne mora obstajati na določenem mestu. Če zamenjava ene storitve z bind mounta na poimenovani zvezek povzroči, da napaka izgine, težave niste odpravili. Potrdili ste, da se odjemalec in daemon ne strinjata, kateremu datotečnemu sistemu pripada pot, in to nesoglasje se vrne v trenutku, ko spet potrebujete pravi imenik gostitelja.

Izpišite endpoint, preden se dotaknete priklopa

Več nastavitev lahko usmeri odjemalca na endpoint in niso vedno soglasne: --context zastavica, DOCKER_CONTEXT, DOCKER_HOST v trenutni lupini in kontekst, shranjen v konfiguraciji odjemalca. Namesto razpravljanja o prednosti izpišite vse in primerjajte odgovore.

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

Konfiguracija odjemalca je v ~/.docker/config.json na Linuxu in macOS ter v %USERPROFILE%\.docker\config.json na Windows, in vrednost, izvožena v trenutnem terminalu, prepiše shranjeno samo za to sejo. Če je endpoint ime gostitelja namesto lokalne vtičnice, o tem, kam bo pristal, odločata razreševanje imen in poti, in prav to prepisuje odjemalec VPN. Predor, ki doda pot ali zamenja razreševalnik, lahko pošlje ime, ki je nekoč pomenilo ta prenosnik, na naslov znotraj korporativnega omrežja.

Primerjajte stanje, ne konfiguracije. Zaženite docker ps -a in docker images s spuščenim predorom, nato znova z dvignjenim. Drugačen seznam vsebnikov je močnejši dokaz kot katera koli konfiguracijska datoteka, ker kaže, da je na vašo zahtevo odgovoril drug daemon.

Vprašajte daemona, ali pot tam obstaja

Ko veste, do katerega daemona ste prišli, naj pogleda v imenik. --mount oblika spodleti z jasnejšim sporočilom kot kratka zastavica, ker preveri vir, preden zažene vsebnik:

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

Če sporoči, da vir manjka, ga ustvarite na stroju, ki je odgovoril, ali usmerite storitev na poimenovani zvezek in kopirajte podatke tja. Česar ne bi smeli storiti, je poustvarjanje zvezkov in ponovna namestitev pogona pred tem preverjanjem. Ta dejanja dovolj spremenijo okolje, da skrijejo neskladje, hkrati pa ga pustijo na mestu.

Še ena pot poteka povsem drugje: vlečenje image je delo daemona, ne odjemalca. Uspešno vlečenje dokaže le, da daemon doseže registry, delujoč bind mount pa le, da je bila pot razrešena. Preizkusite vsako pot tam, kjer se dejansko izvaja, sicer boste popoldne porabili za napačno.

Imena intraneta spodletijo iz drugega razloga

Druga polovica istega poročila je običajno, da vsebnik ne doseže intranet.corp.example. To je ločen mehanizem, ne druga težava z zvezkom. Vsebnik dobi svoj /etc/resolv.conf ob zagonu, ustvarjen iz nastavitev razreševalnika daemona, zato se strežnik DNS, ki ga je VPN dodal po ustvaritvi vsebnika, ne bo pojavil tam, dokler vsebnika ne ustvarite znova.

Vgrajeni razreševalnik Dockerja v omrežju, ki ga določi uporabnik, posreduje zunanje poizvedbe na konfigurirane strežnike gostitelja, kar pomaga, ko VPN prepiše razreševalnik gostitelja, in škodi, ko razdeljeni DNS pošlje notranjo cono na strežnik, ki ga daemon ne vidi več. Ozko, izrecno preslikavanje se izogne prepiru za imena, ki se nikoli ne spremenijo:

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

To zapiše vnos v datoteko hosts vsebnika, zato se vsebnik ne nauči ničesar o predoru, in tudi zamrzne naslov. Ko se notranji gostitelj premakne, vnos ostane napačen, dokler nekdo ne uredi datoteke Compose. Uporabite ga za fiksno napravo ali pripeto podatkovno bazo, imena, ki se premikajo, pa prepustite DNS.

Kaj ponovna namestitev v resnici spremeni

Ponovna namestitev Docker Desktop znova ustvari VM, vtičnico in seznam kontekstov, priklop pa spet začne delovati. Ta izid je resničen in ničesar ne nauči, zato se ista okvara vrne po naslednji posodobitvi VPN. Ponovna namestitev je zamenjala endpoint, ki ga je odjemalec uporabljal; ni uskladila poti, ki jo imenuje vaš projekt, z datotečnim sistemom, ki ga daemon dejansko bere.

Moj vrstni red dela je kratek. Potrdite, kateri endpoint bo odjemalec uporabil. Potrdite, kateri daemon je odgovoril, s primerjavo seznamov vsebnikov. Prosite tega daemona, da navede pot do vira. Šele nato uredite priklop, dodajte vnos hosts ali spremenite vrsto zvezka. Če vzdržujete datoteko Compose za ekipo, ki dela prek VPN, dajte prednost poimenovanim zvezkom za podatke, ki naj bi jih imel daemon, da pot gostitelja nikoli ne postane del pogodbe.

Sorodni članki