فشل ربط وحدة تخزين Docker بعد اتصال VPN: افحص الـ daemon
ربط المجلد لديك سليم. اتصال VPN يغيّر أي daemon يستجيب للعميل، لذا اطبع نقطة النهاية، وأثبت وجود المسار هناك، وتوقّف عن تعديل وحدة التخزين.
تكاد كل كتابة عن هذه المشكلة تلقي اللوم على وحدة التخزين، وهذا بالضبط سبب استغراق الإصلاح وقتًا طويلًا. كان لديك ربط مجلد يعمل، واتصلت شبكة VPN الخاصة بالشركة، ثم أصبح docker compose up يفشل الآن بسبب مسار مصدر مفقود، أو مجلد فارغ، أو ربط يرفض المحرك إنشاءه. في الوحدات التي نظّفتها، لم يكن ملف Compose قد تغيّر وكان المسار صحيحًا. الذي تغيّر هو أي daemon تلقّى الطلب، وكان خطأ الربط مجرد أول موضع ظهر فيه هذا الاختلاف.
وحدة التخزين لم تتحرك قط؛ الطلب هو الذي تحرّك
إن -v /srv/app:/app ليس نسخ مجلد يقوم به shell لديك. يحوّله العميل إلى طلب API، ويحلّ الـ daemon الذي يجيب /srv/app على نظام ملفاته هو. عندما يعمل الطرفان على النواة نفسها، يكون ذلك المسار هو ما تراه في مدير الملفات. وعندما تتغيّر نقطة النهاية، يُبحث عن السلسلة نفسها على جهاز لم يسمع قط بمجلد مشروعك، فيبلّغ الـ daemon عن المصدر كمفقود أو ينشئ بصمت مجلدًا فارغًا في مكانه.
وهذا أيضًا سبب استمرار عمل وحدة التخزين المسماة بينما لا يعمل ربط المجلد. -v appdata:/app تسمّي تخزينًا يملكه الـ daemon، فلا حاجة لوجود مسار مضيف في مكان بعينه. وإذا كان تحويل خدمة من ربط مجلد إلى وحدة تخزين مسماة يجعل الخطأ يختفي، فأنت لم تصلح المشكلة. لقد أكّدت أن العميل والـ daemon يختلفان حول أي نظام ملفات ينتمي إليه المسار، وهذا الخلاف يعود في اللحظة التي تحتاج فيها مجلد مضيف حقيقيًا مرة أخرى.
اطبع نقطة النهاية قبل أن تلمس الربط
عدة إعدادات يمكنها توجيه العميل إلى نقطة نهاية، وهي لا تتفق دائمًا: --context ، وعلامة DOCKER_CONTEXT، و DOCKER_HOST في shell الحالي، والسياق المحفوظ في إعدادات العميل. وبدلًا من التفكير في الأولوية، اطبعها كلها وقارن الإجابات.
docker context show
docker context ls
docker version
docker info --format "{{.Name}} {{.OperatingSystem}} {{.ServerVersion}}"
يعيش إعداد العميل في ~/.docker/config.json على Linux وmacOS وفي %USERPROFILE%\.docker\config.json على Windows، والقيمة المصدَّرة في الطرفية الحالية تتجاوز المحفوظة لهذه الجلسة فقط. وإذا كانت نقطة النهاية اسم مضيف بدلًا من مقبس محلي، فإن تحليل الأسماء والمسارات هي ما يحدد أين تهبط، وهي بالضبط ما يعيد عميل VPN كتابته. النفق الذي يضيف مسارًا أو يبدّل المحلّل يمكنه أن يرسل اسمًا كان يعني هذا الحاسوب المحمول إلى عنوان داخل شبكة الشركة.
قارن الحالة بدلًا من الإعدادات. شغّل docker ps -a و docker images والنفق مغلق، ثم مرة أخرى وهو مفتوح. قائمة حاويات مختلفة دليل أقوى من أي ملف إعدادات، لأنها تُظهر أن daemon آخر أجاب طلبك.
اسأل الـ daemon هل المسار موجود هناك
بعد أن تعرف أي daemon وصلت إليه، اجعله ينظر إلى المجلد. صيغة --mount تفشل برسالة أوضح من العلامة القصيرة، لأنها تتحقق من المصدر قبل أن تبدأ الحاوية:
docker run --rm --mount type=bind,source=/srv/app,target=/app alpine ls -la /app
إذا أبلغ عن المصدر كمفقود، فأنشئه على الجهاز الذي أجاب، أو وجّه الخدمة إلى وحدة تخزين مسماة وانسخ البيانات إليها. ما لا ينبغي فعله هو إعادة إنشاء وحدات التخزين وإعادة تثبيت المحرك قبل هذا الفحص. تلك الإجراءات تغيّر البيئة بما يكفي لإخفاء عدم التطابق مع إبقائه في مكانه.
هناك مسار آخر يجري في مكان مختلف تمامًا: سحب صورة عمل الـ daemon، لا عمل العميل. السحب الناجح يثبت فقط أن الـ daemon يستطيع الوصول إلى registry، وربط المجلد العامل يثبت فقط أن مسارًا قد حُلّ. اختبر كل مسار حيث يُنفَّذ فعليًا، وإلا فستقضي عصرًا كاملًا على المسار الخاطئ.
أسماء الشبكة الداخلية تفشل لسبب مختلف
النصف الثاني من التقرير نفسه عادةً هو أن الحاوية لا تستطيع الوصول إلى intranet.corp.example. تلك آلية منفصلة، لا مشكلة وحدة تخزين ثانية. تحصل الحاوية على /etc/resolv.conf عند بدء تشغيلها، مولّدًا من إعدادات المحلّل في الـ daemon، لذا فإن خادم DNS أضافته VPN بعد إنشاء الحاوية لن يظهر فيه حتى يُعاد إنشاء الحاوية.
محلّل Docker المدمج على شبكة يعرّفها المستخدم يمرّر الاستعلامات الخارجية إلى الخوادم المضبوطة في المضيف، وهذا يساعد عندما تعيد VPN كتابة محلّل المضيف ويضر عندما يرسل DNS المنقسم منطقة داخلية إلى خادم لم يعد الـ daemon يراه. التعيين الضيق الصريح يتجاوز الجدل بشأن الأسماء التي لا تتغير أبدًا:
services:
web:
extra_hosts:
- "intranet.corp.example:10.20.30.40"
يكتب هذا مدخلًا في ملف hosts الخاص بالحاوية، فلا تتعلم الحاوية شيئًا عن النفق، كما يجمّد العنوان. وعندما ينتقل المضيف الداخلي، يبقى المدخل خاطئًا حتى يعدّل أحدهم ملف Compose. استخدمه لجهاز ثابت أو قاعدة بيانات مثبّتة، واترك DNS يتعامل مع الأسماء التي تتحرك.
ما الذي تغيّره إعادة التثبيت فعليًا
إعادة تثبيت Docker Desktop تعيد إنشاء الآلة الافتراضية والمقبس وقائمة السياقات، ويبدأ الربط بالعمل مجددًا. تلك النتيجة حقيقية ولا تعلّم شيئًا، ولهذا يعود العطل نفسه بعد تحديث VPN التالي. لقد استبدلت إعادة التثبيت نقطة النهاية التي كان العميل يستخدمها؛ ولم توفّق بين المسار الذي يسميه مشروعك ونظام الملفات الذي يقرأه الـ daemon فعليًا.
ترتيب عملي قصير. تأكد من أي نقطة نهاية سيستخدمها العميل. تأكد من أي daemon أجاب بمقارنة قوائم الحاويات. اطلب من ذلك الـ daemon سرد مسار المصدر. وبعد ذلك فقط عدّل الربط، أو أضف مدخل hosts، أو غيّر نوع وحدة التخزين. وإذا كنت تصون ملف Compose لفريق يعمل عبر VPN، ففضّل وحدات التخزين المسماة للبيانات التي يجب أن يملكها الـ daemon، حتى لا يصبح مسار المضيف جزءًا من العقد أبدًا.