Hampir setiap tulisan tentang masalah ini menyalahkan volum, dan itulah sebabnya pembaikan mengambil masa begitu lama. Anda mempunyai bind mount yang berfungsi, VPN korporat disambung, dan docker compose up kini gagal dengan laluan sumber yang hilang, direktori kosong atau lekapan yang enjin enggan cipta. Dalam persekitaran yang saya bersihkan, fail Compose tidak berubah dan laluan itu betul. Yang berubah ialah daemon mana yang menerima permintaan, dan ralat lekapan hanyalah tempat pertama perbezaan itu kelihatan.

Volum tidak pernah bergerak; permintaan yang bergerak

Bendera -v /srv/app:/app bukan salinan direktori yang dilakukan oleh shell anda. Klien menukarnya menjadi permintaan API, dan daemon yang menjawab menyelesaikan /srv/app terhadap sistem failnya sendiri. Apabila kedua-dua pihak berjalan pada kernel yang sama, laluan itu ialah yang anda lihat dalam pengurus fail. Apabila endpoint berubah, rentetan yang sama dicari pada mesin yang tidak pernah mendengar tentang direktori projek anda, dan daemon sama ada melaporkan sumber itu hilang atau diam-diam mencipta direktori kosong di tempatnya.

Itulah juga sebab volum bernama terus berfungsi manakala bind mount tidak. -v appdata:/app menamakan storan yang dimiliki daemon, jadi tiada laluan hos perlu wujud di mana-mana tempat tertentu. Jika menukar satu perkhidmatan daripada bind mount kepada volum bernama membuat ralat hilang, anda belum membaiki masalahnya. Anda telah mengesahkan bahawa klien dan daemon tidak bersetuju tentang sistem fail mana laluan itu milik, dan perselisihan itu kembali pada saat anda memerlukan direktori hos sebenar semula.

Cetak endpoint sebelum anda menyentuh lekapan

Beberapa tetapan boleh menunjuk klien ke endpoint, dan ia tidak selalu bersetuju: --context bendera, DOCKER_CONTEXT, DOCKER_HOST dalam shell semasa, dan konteks yang disimpan dalam konfigurasi klien. Daripada menaakul keutamaan, cetak semuanya dan bandingkan jawapannya.

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

Konfigurasi klien terletak di ~/.docker/config.json pada Linux dan macOS dan di %USERPROFILE%\.docker\config.json pada Windows, dan nilai yang dieksport dalam terminal semasa mengatasi yang disimpan hanya untuk sesi itu. Jika endpoint ialah nama hos dan bukan socket tempatan, penyelesaian nama dan laluan menentukan di mana ia mendarat, dan itulah yang ditulis semula oleh klien VPN. Terowong yang menambah laluan atau menukar penyelesai boleh menghantar nama yang dahulunya bermaksud komputer riba ini ke alamat dalam rangkaian korporat.

Bandingkan keadaan dan bukan konfigurasi. Jalankan docker ps -a dan docker images dengan terowong dimatikan, kemudian sekali lagi dengan terowong dihidupkan. Senarai kontena yang berbeza ialah bukti lebih kukuh daripada mana-mana fail konfigurasi, kerana ia menunjukkan bahawa daemon lain menjawab permintaan anda.

Tanya daemon sama ada laluan itu wujud di sana

Setelah anda tahu daemon mana yang dicapai, suruh ia melihat direktori itu. --mount bentuk itu gagal dengan mesej yang lebih jelas daripada bendera pendek, kerana ia mengesahkan sumber sebelum memulakan kontena:

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

Jika ia melaporkan sumber itu hilang, cipta ia pada mesin yang menjawab, atau halakan perkhidmatan ke volum bernama dan salin data ke sana. Apa yang anda tidak patut lakukan ialah mencipta semula volum dan memasang semula enjin sebelum pemeriksaan ini. Tindakan itu mengubah persekitaran cukup untuk menyembunyikan ketidakpadanan sambil membiarkannya di tempatnya.

Satu lagi laluan berjalan di tempat yang sama sekali berbeza: menarik image ialah kerja daemon, bukan kerja klien. Tarikan yang berjaya hanya membuktikan bahawa daemon boleh mencapai registry, dan bind mount yang berfungsi hanya membuktikan bahawa sesuatu laluan telah diselesaikan. Uji setiap laluan di tempat ia benar-benar dilaksanakan, atau anda akan menghabiskan satu petang pada yang salah.

Nama intranet gagal atas sebab yang berbeza

Separuh kedua laporan yang sama biasanya ialah kontena tidak dapat mencapai intranet.corp.example. Itu mekanisme berasingan, bukan masalah volum kedua. Kontena mendapat /etc/resolv.conf nya semasa bermula, dijana daripada tetapan penyelesai daemon, jadi pelayan DNS yang ditambah VPN selepas kontena dicipta tidak akan muncul di sana sehingga kontena dicipta semula.

Penyelesai terbina dalam Docker pada rangkaian yang ditakrifkan pengguna memajukan carian luaran kepada pelayan yang dikonfigurasikan pada hos, yang membantu apabila VPN menulis semula penyelesai hos dan merosakkan apabila DNS terbelah menghantar zon dalaman kepada pelayan yang tidak lagi dilihat daemon. Pemetaan sempit dan jelas mengelak perdebatan untuk nama yang tidak pernah berubah:

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

Ini menulis entri dalam fail hosts kontena, jadi kontena tidak pernah mengetahui apa-apa tentang terowong, dan ia juga membekukan alamat. Apabila hos dalaman berpindah, entri itu kekal salah sehingga seseorang mengedit fail Compose. Gunakannya untuk perkakas tetap atau pangkalan data yang dipin, dan biarkan DNS mengendalikan nama yang bergerak.

Apa yang sebenarnya diubah oleh pemasangan semula

Memasang semula Docker Desktop mencipta semula VM, socket dan senarai konteks, dan lekapan mula berfungsi semula. Hasil itu nyata dan ia tidak mengajar apa-apa, itulah sebabnya kegagalan yang sama kembali selepas kemas kini VPN seterusnya. Pemasangan semula menggantikan endpoint yang digunakan oleh klien; ia tidak menyelaraskan laluan yang dinamakan projek anda dengan sistem fail yang benar-benar dibaca daemon.

Urutan kerja saya pendek. Sahkan endpoint mana yang akan digunakan oleh klien. Sahkan daemon mana yang menjawab dengan membandingkan senarai kontena. Minta daemon itu menyenaraikan laluan sumber. Hanya selepas itu edit lekapan, tambah entri hosts atau tukar jenis volum. Jika anda menyelenggara fail Compose untuk pasukan yang bekerja melalui VPN, utamakan volum bernama untuk data yang sepatutnya dimiliki daemon, supaya laluan hos tidak pernah menjadi sebahagian daripada kontrak.

Artikel berkaitan