Речиси секој текст за овој проблем го обвинува томот, и токму затоа поправката трае толку долго. Имавте bind монтирање што работеше, корпоративниот VPN се поврза, и docker compose up сега не успева со патека до изворот што недостасува, празен директориум или монтирање што машината одбива да го создаде. Во средините што ги исчистив, датотеката Compose не беше променета и патеката беше точна. Она што се промени беше кој демон го доби барањето, а грешката при монтирање беше само првото место каде таа разлика стана видлива.

Томот никогаш не се премести; барањето се премести

Знамето -v /srv/app:/app не е копија на директориум што ја прави вашата обвивка. Клиентот го претвора во API барање, а демонот што одговара ја решава /srv/app во однос на сопствениот датотечен систем. Кога двете страни работат на исто јадро, таа патека е онаа што ја гледате во менаџерот на датотеки. Кога endpoint-от се менува, истиот текст се бара на машина што никогаш не чула за директориумот на вашиот проект, и демонот или го пријавува изворот како отсутен или тивко создава празен директориум на негово место.

Ова е и причината зошто именуван том продолжува да работи, а bind монтирањето не. -v appdata:/app именува складиште што демонот го поседува, па ниту една патека на домаќинот не мора да постои на одредено место. Ако замената на една услуга од bind монтирање со именуван том ја отстрани грешката, не сте го решиле проблемот. Потврдивте дека клиентот и демонот не се согласуваат на кој датотечен систем му припаѓа патеката, и тоа несогласување се враќа во моментот кога повторно ви треба вистински директориум на домаќинот.

Испечатете го endpoint-от пред да го допрете монтирањето

Неколку поставки можат да го насочат клиентот кон endpoint, и тие не се секогаш согласни: --context знамето, DOCKER_CONTEXT, DOCKER_HOST во тековната обвивка, и контекстот зачуван во конфигурацијата на клиентот. Наместо да расудувате за приоритетот, испечатете ги сите и споредете ги одговорите.

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

Конфигурацијата на клиентот се наоѓа во ~/.docker/config.json на Linux и macOS и во %USERPROFILE%\.docker\config.json на Windows, а вредноста извезена во тековниот терминал ја заменува зачуваната само за таа сесија. Ако endpoint-от е име на домаќин наместо локален socket, разрешувањето на имиња и рутите одлучуваат каде ќе слета, и токму тоа го препишува VPN клиентот. Тунел што додава рута или го менува резолверот може да испрати име што порано значеше овој преносен сметач на адреса внатре во корпоративната мрежа.

Споредете состојба наместо конфигурација. Извршете docker ps -a и docker images со исклучен тунел, потоа повторно со вклучен. Различен список на контејнери е посилен доказ од која било конфигурациска датотека, бидејќи покажува дека на вашето барање одговорил друг демон.

Прашајте го демонот дали патеката постои таму

Кога ќе знаете до кој демон стигнавте, натерајте го да го погледне директориумот. --mount формата не успева со појасна порака од краткото знаме, бидејќи го валидира изворот пред да го стартува контејнерот:

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

Ако го пријави изворот како отсутен, создадете го на машината што одговори, или насочете ја услугата кон именуван том и копирајте ги податоците таму. Она што не треба да го правите е повторно создавање на томови и реинсталирање на машината пред оваа проверка. Тие дејства доволно ја менуваат околината за да ја сокријат неусогласеноста, а сепак да ја остават на место.

Уште една патека оди сосема на друго место: влечењето на image е работа на демонот, не на клиентот. Успешното влечење докажува само дека демонот може да стигне до registry, а работечкото bind монтирање само дека патеката е решена. Тестирајте ја секоја патека таму каде што навистина се извршува, инаку ќе потрошите попладне на погрешната.

Имињата од интранетот не успеваат од друга причина

Втората половина од истиот извештај обично е дека контејнерот не може да стигне до intranet.corp.example. Тоа е посебен механизам, не втор проблем со том. Контејнерот го добива својот /etc/resolv.conf при стартување, генериран од поставките на резолверот на демонот, па DNS серверот што VPN го додал откако контејнерот е создаден нема да се појави таму додека контејнерот не се пресоздаде.

Вградениот резолвер на Docker на мрежа дефинирана од корисникот ги проследува надворешните барања до конфигурираните сервери на домаќинот, што помага кога VPN го препишува резолверот на домаќинот и штети кога поделениот DNS испраќа внатрешна зона до сервер што демонот веќе не го гледа. Тесно, експлицитно мапирање ја заобиколува расправата за имиња што никогаш не се менуваат:

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

Ова запишува ставка во датотеката hosts на контејнерот, па контејнерот не учи ништо за тунелот, и исто така ја замрзнува адресата. Кога внатрешниот домаќин ќе се премести, ставката останува погрешна додека некој не ја уреди датотеката Compose. Користете го за фиксен уред или закачена база на податоци, а имињата што се движат оставете ги на DNS.

Што навистина менува реинсталацијата

Реинсталирањето на Docker Desktop повторно ги создава VM, socket-от и списокот на контексти, и монтирањето повторно почнува да работи. Тој резултат е вистински и не учи ништо, затоа истата дефект се враќа по следното ажурирање на VPN. Реинсталацијата го замени endpoint-от што клиентот го користеше; таа не ја усогласи патеката што вашиот проект ја именува со датотечниот систем што демонот навистина го чита.

Мојот редослед на работа е краток. Потврдете кој endpoint ќе го користи клиентот. Потврдете кој демон одговори со споредување на списоците на контејнери. Побарајте од тој демон да ја наведе патеката до изворот. Само тогаш уредете го монтирањето, додајте ставка во hosts или сменете тип на том. Ако ја одржувате датотеката Compose за тим што работи преку VPN, претпочитајте именувани томови за податоците што демонот треба да ги поседува, за патеката на домаќинот никогаш да не стане дел од договорот.

Поврзани статии