Амаль кожнае апісанне гэтай праблемы вінаваціць том, і менавіта таму выпраўленне займае так шмат часу. У вас было працоўнае 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 — гэта імя хоста, а не лакальны сокет, развязанне імёнаў і маршруты вырашаюць, куды ён трапіць, і менавіта іх перапісвае кліент VPN. Тунель, які дадае маршрут або замяняе рэзалвер, можа адправіць імя, што раней азначала гэты ноўтбук, на адрас унутры карпаратыўнай сеткі.

Параўноўвайце стан, а не канфігурацыю. Запусціце docker ps -a і docker images пры выключаным тунелі, потым зноў пры ўключаным. Іншы спіс кантэйнераў — мацнейшы доказ, чым любы файл канфігурацыі, бо ён паказвае, што на ваш запыт адказаў іншы дэман.

Спытайце дэман, ці існуе шлях там

Калі вы ведаеце, да якога дэмана дабраліся, прымусьце яго паглядзець на дырэкторыю. Форма --mount падае з больш ясным паведамленнем, чым кароткі сцяг, бо правярае крыніцу перад запускам кантэйнера:

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

Калі ён паведамляе, што крыніца адсутнічае, стварыце яе на машыне, якая адказала, або накіруйце сэрвіс на іменны том і скапіруйце туды даныя. Чаго рабіць не варта — гэта пераствараць тамы і пераўсталёўваць рухавік да гэтай праверкі. Гэтыя дзеянні змяняюць асяроддзе дастаткова, каб схаваць неадпаведнасць, пакідаючы яе на месцы.

Яшчэ адзін шлях ідзе зусім у іншым месцы: выцягванне вобраза — гэта праца дэмана, а не кліента. Паспяховае выцягванне даказвае толькі, што дэман можа дабрацца да registry, а працоўнае bind-мантаванне — толькі што шлях развязаўся. Тэстуйце кожны шлях там, дзе ён фактычна выконваецца, інакш вы выдаткаваеце пасляабедзенны час на няправільны.

Імёны ўнутранай сеткі падаюць з іншай прычыны

Другая палова таго ж справаздачы звычайна ў тым, што кантэйнер не можа дабрацца да intranet.corp.example. Гэта асобны механізм, а не другая праблема тома. Кантэйнер атрымлівае свой /etc/resolv.conf пры запуску, згенераваны з налад рэзалвера дэмана, таму DNS-сервер, які VPN дадаў пасля стварэння кантэйнера, не з'явіцца там, пакуль кантэйнер не будзе пераствораны.

Убудаваны рэзалвер Docker у сетцы, вызначанай карыстальнікам, перадае знешнія запыты на серверы, наладжаныя на хосце, што дапамагае, калі VPN перапісвае рэзалвер хоста, і шкодзіць, калі split DNS адпраўляе ўнутраную зону на сервер, якога дэман ужо не бачыць. Вузкае, яўнае супастаўленне абыходзіць спрэчку для імёнаў, якія ніколі не змяняюцца:

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

Гэта запісвае запіс у файл hosts кантэйнера, таму кантэйнер нічога не даведваецца пра тунель, а таксама замарозіць адрас. Калі ўнутраны хост пераязджае, запіс застаецца няправільным, пакуль хтосьці не адрэдагуе файл Compose. Выкарыстоўвайце яго для фіксаванай прылады або замацаванай базы даных, а імёны, што рухаюцца, пакіньце DNS.

Што насамрэч змяняе пераўсталёўка

Пераўсталёўка Docker Desktop перастварае VM, сокет і спіс кантэкстаў, і мантаванне зноў пачынае працаваць. Гэты вынік рэальны і нічога не вучыць, таму тая ж памылка вяртаецца пасля наступнага абнаўлення VPN. Пераўсталёўка замяніла endpoint, які выкарыстоўваў кліент; яна не ўзгадніла шлях, які называе ваш праект, з файлавай сістэмай, якую дэман фактычна чытае.

Мой парадак працы кароткі. Пацвердзіце, які endpoint будзе выкарыстоўваць кліент. Пацвердзіце, які дэман адказаў, параўнаўшы спісы кантэйнераў. Папрасіце гэты дэман пералічыць шлях крыніцы. Толькі пасля гэтага правіце мантаванне, дадавайце запіс hosts або змяняйце тып тома. Калі вы падтрымліваеце файл Compose для каманды, якая працуе праз VPN, аддавайце перавагу іменным тамам для даных, якімі павінен валодаць дэман, каб шлях хоста ніколі не стаў часткай дамовы.

Падобныя артыкулы