Bu problemin demək olar ki, hər təsviri həcmi günahlandırır və düzəlişin bu qədər uzun çəkməsinin səbəbi məhz budur. İşləyən bir bind mount-unuz var idi, korporativ VPN qoşuldu və docker compose up indi çatışmayan mənbə yolu, boş qovluq və ya mühərrikin yaratmaqdan imtina etdiyi mount ilə uğursuz olur. Təmizlədiyim qurğularda Compose faylı dəyişməmişdi və yol düzgün idi. Dəyişən şey sorğunun hansı daemon-a çatması idi və mount xətası sadəcə bu fərqin göründüyü ilk yerdə idi.

Həcm heç yerə getmədi; sorğu getdi

-v /srv/app:/app bayrağı sizin shell-inizin etdiyi qovluq kopyası deyil. Klient onu API sorğusuna çevirir və cavab verən daemon /srv/app öz fayl sistemi üzərində həll edir. Hər iki tərəf eyni nüvədə işləyəndə bu yol fayl menecerinizdə gördüyünüz yoldur. Endpoint dəyişəndə eyni sətir layihə qovluğunuzu heç vaxt eşitməmiş maşında axtarılır və daemon ya mənbəni çatışmır kimi bildirir, ya da onun yerinə sakitcə boş qovluq yaradır.

Adlandırılmış həcmin işləməyə davam etməsinin, bind mount-un isə davam etməməsinin səbəbi də budur. -v appdata:/app daemon-un sahib olduğu yaddaşı adlandırır, ona görə host yolu konkret bir yerdə mövcud olmalı deyil. Bir xidməti bind mount-dan adlandırılmış həcmə keçirmək xətanı yox edirsə, siz problemi həll etməmisiniz. Siz klientlə daemon-un yolun hansı fayl sisteminə aid olduğu barədə razılaşmadığını təsdiqləmisiniz və bu uyğunsuzluq yenidən real host qovluğuna ehtiyac duyduğunuz anda qayıdır.

Mount-a toxunmadan əvvəl endpoint-i çap edin

Bir neçə parametr klienti endpoint-ə yönəldə bilər və onlar həmişə razılaşmır: --context bayrağı, DOCKER_CONTEXT, DOCKER_HOST cari shell-də, və klient konfiqurasiyasında saxlanan kontekst. Üstünlük barədə düşünmək əvəzinə hamısını çap edin və cavabları müqayisə edin.

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

Klient konfiqurasiyası ~/.docker/config.json Linux və macOS-da, %USERPROFILE%\.docker\config.json isə Windows-da yerləşir və cari terminalda ixrac edilən dəyər saxlananı yalnız həmin sessiya üçün üstələyir. Endpoint lokal socket əvəzinə host adıdırsa, ad həlli və marşrutlar onun hara düşdüyünü müəyyən edir və bunlar məhz VPN klientinin yenidən yazdığı şeylərdir. Marşrut əlavə edən və ya resolver-i dəyişən tunel, əvvəllər bu noutbuku bildirən adı korporativ şəbəkə daxilindəki ünvana göndərə bilər.

Konfiqurasiya əvəzinə vəziyyəti müqayisə edin. Tunel bağlı ikən docker ps -a və docker images işə salın, sonra tunel açıq ikən yenidən. Fərqli konteyner siyahısı hər hansı konfiqurasiya faylından güclü sübutdur, çünki sorğunuza başqa bir daemon-un cavab verdiyini göstərir.

Daemon-dan soruşun: yol orada varmı

Hansı daemon-a çatdığınızı bildikdən sonra ona qovluğa baxmağı əmr edin. --mount forması qısa bayraqdan daha aydın mesajla uğursuz olur, çünki konteyneri başlatmadan əvvəl mənbəni yoxlayır:

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

Əgər mənbəni çatışmır kimi bildirirsə, onu cavab verən maşında yaradın və ya xidməti adlandırılmış həcmə yönəldin və məlumatı ora köçürün. Etməməli olduğunuz şey bu yoxlamadan əvvəl həcmləri yenidən yaratmaq və mühərriki yenidən quraşdırmaqdır. Bu əməliyyatlar mühiti uyğunsuzluğu gizlədəcək qədər dəyişir, halbuki o yerində qalır.

Daha bir yol tamamilə başqa yerdə gedir: image çəkmək daemon işidir, klient işi deyil. Uğurlu çəkmə yalnız daemon-un registry-yə çata bildiyini sübut edir, işləyən bind mount isə yalnız bir yolun həll olunduğunu. Hər yolu həqiqətən icra olunduğu yerdə sınayın, əks halda bütün günortanı səhv yolda keçirəcəksiniz.

Daxili şəbəkə adları başqa səbəbdən uğursuz olur

Eyni hesabatın ikinci yarısı adətən konteynerin intranet.corp.example-a çata bilməməsidir. Bu ayrı mexanizmdir, ikinci həcm problemi deyil. Konteyner /etc/resolv.conf -nu başladığı anda daemon resolver parametrlərindən yaradılmış şəkildə alır, ona görə VPN-in konteyner yaradıldıqdan sonra əlavə etdiyi DNS serveri konteyner yenidən yaradılana qədər orada görünməyəcək.

İstifadəçi tərəfindən təyin edilmiş şəbəkədə Docker-in daxili resolver-i xarici sorğuları host-un konfiqurasiya edilmiş serverlərinə ötürür; bu, VPN host resolver-ini yenidən yazanda kömək edir, split DNS daxili zonanı daemon-un artıq görmədiyi serverə göndərəndə isə zərər verir. Heç vaxt dəyişməyən adlar üçün dar və açıq bir xəritələmə bu mübahisəni yan keçir:

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

Bu, konteynerin hosts faylına bir giriş yazır, beləcə konteyner tunel haqqında heç nə öyrənmir, həm də ünvanı dondurur. Daxili host yerini dəyişəndə giriş kimsə Compose faylını redaktə edənə qədər səhv qalır. Onu sabit cihaz və ya sabitlənmiş verilənlər bazası üçün istifadə edin və hərəkət edən adları DNS-ə buraxın.

Yenidən quraşdırma əslində nəyi dəyişir

Docker Desktop-u yenidən quraşdırmaq VM-i, socket-i və kontekst siyahısını yenidən yaradır və mount yenidən işləməyə başlayır. Bu nəticə realdır və heç nə öyrətmir, buna görə eyni nasazlıq növbəti VPN yeniləməsindən sonra qayıdır. Yenidən quraşdırma klientin istifadə etdiyi endpoint-i əvəz etdi; layihənizin adlandırdığı yolu daemon-un həqiqətən oxuduğu fayl sistemi ilə uyğunlaşdırmadı.

İş qaydam qısadır. Klientin hansı endpoint-dən istifadə edəcəyini təsdiqləyin. Konteyner siyahılarını müqayisə edərək hansı daemon-un cavab verdiyini təsdiqləyin. Həmin daemon-dan mənbə yolunu siyahıya salmasını xahiş edin. Yalnız bundan sonra mount-u redaktə edin, hosts girişi əlavə edin və ya həcm tipini dəyişin. Komandası VPN üzərindən işləyən bir qrup üçün Compose faylını saxlayırsınızsa, daemon-un sahib olmalı olduğu məlumatlar üçün adlandırılmış həcmlərə üstünlük verin ki, host yolu heç vaxt müqavilənin hissəsinə çevrilməsin.

Əlaqəli məqalələr