network_mode: service:vpn واسم مضيف db المفقود
مشاركة نطاق شبكة VPN خيار في البنية. إما أن يحتفظ db بعنوانه الخاص وينضم vpn إلى تلك الشبكة، وإما أن يجيب كل شيء على loopback.
تضيف network_mode: service:vpn إلى التطبيق، ثم تعيد تشغيل المجموعة، فيموت التطبيق لأن db لم يعد يُحلَّل. لم يُعَد تسمية أي شيء في ملف compose، لذا فإن المشتبه بهما الواضحان هما DNS وقاعدة البيانات. التغيير الحقيقي أصغر وأغرب: لم يعد التطبيق عضواً في شبكة Compose التي يوجد فيها ذلك الاسم. وإلى أن تقرر من أي نطاق يجب أن تجيب قاعدة البيانات، فإن كل إصلاح لاسم المضيف ضرب من التخمين.
لماذا توقف اسم المضيف db عن الإجابة
الخدمة التي تستخدم network_mode ليس لها عنوان خاص بها على شبكة Compose؛ بل تستعير نطاق الخدمة المسمّاة. يجلب ذلك النطاق واجهاته ومساره وفضاء منافذه ومحلله الخاص، ويحل محل ارتباط التطبيق بشبكة backend. الاسم db لم يكن مجرداً قط: لقد عاش على تلك الشبكة وحُلَّ عبر DNS المدمج فيها. أزل الارتباط فلن يجد الاسم مكاناً يُحلَّ فيه.
تحقق من ذلك من داخل الحاويات لا من المضيف. بحث يفشل في التطبيق وينجح في حاوية قاعدة البيانات يعني أن الاسم سليم والعضوية ليست كذلك. وتضع تلك النتيجة الإصلاح أيضاً في بنية compose لا في إعدادات المحلل في التطبيق.
ثلاثة أسئلة قبل تحرير الملف
أجب عنها بالترتيب، لأن كل سؤال يضيّق البنية. على ماذا يجب أن تجيب قاعدة البيانات: على اسم مضيف تستخدمه حاويات أخرى، أم على التطبيق وحده على loopback؟ هل يجب أن ينشر التطبيق منفذاً إلى المضيف، وأي خدمة ستملكه؟ هل يجب أن تكون قاعدة البيانات قابلة للوصول من المضيف أو من جهاز آخر، أم من داخل النفق فقط؟
إذا كانت قاعدة البيانات بحاجة إلى اسمها الخاص والتطبيق لا ينشر شيئاً، فأبقهما على ارتباطين منفصلين. وإذا كان على التطبيق نشر منفذ وكل شيء يمر عبر النفق، فضع قاعدة البيانات في نطاق VPN واستخدم loopback. خلط الاثنين ينتج مجموعة تبدأ بنظافة وتفشل عند الاتصال.
أبقِ قاعدة البيانات حيث هي
التغيير الأصغر يربط مالك النطاق بالشبكة التي تحتوي قاعدة البيانات أصلاً. يرث التطبيق ذلك الارتباط لأنه يشارك مجموعة vpn، ويُحلَّ db تماماً كما كان من قبل.
services:
vpn:
networks:
- backend
app:
network_mode: service:vpn
db:
networks:
- backend
networks:
backend:لا تضف networks إلى التطبيق أيضاً. يرفض Compose تلك الخاصية إلى جانب network_mode في الخدمة نفسها، ويشير الخطأ إلى الملف لا إلى الزوج. وإذا كان عميل VPN يرشّح وجهة backend داخل نطاقه، فعدّل أيضاً سياسة الشبكة المحلية المدعومة لديه؛ فالارتباط المشترك يوفر مساراً لكنه لا يتجاوز ذلك المرشح.
انقل قاعدة البيانات إلى النطاق
التغيير الأكبر يضع قاعدة البيانات في النطاق نفسه ويوجه التطبيق إلى 127.0.0.1 بالمنفذ الحقيقي. لا يمكن لعمليتين أن تربطا العنوان والمنفذ نفسه لمجرد أنهما بدأتا في حاويتين مختلفتين، لذا فإن قاعدة بيانات تستمع أيضاً على عنوان wildcard ستتصادم مع أي شيء آخر يفعل ذلك. افحص المستمع قبل نقله.
المنافذ المنشورة تنتمي إلى الخدمة المالكة للنطاق. إضافة ports إلى التطبيق تُرفض إلى جانب network_mode، واختلاق عنوان تطبيق منفصل يصف واجهة غير موجودة.
الجاهزية والحجب والمحلل
depends_on يرتب بدء الحاويات؛ وهو ليس دليلاً على أن النفق يعمل، ولا يوقف الحركة عند سقوط النفق. عامل إمكانية الوصول وجاهزية النفق وحجب الأعطال كثلاثة متطلبات منفصلة. المجموعة التي تلبي الأول فقط تنجح في اختبار يدوي في يوم جيد وتسرّب في يوم سيئ. اكتب الأجوبة الثلاثة بجانب ملف compose، حيث سينظر الشخص التالي.
مشاركة النطاق تعني أيضاً أن التطبيق يرث محلل حاوية VPN، وهو ما يساعد عندما يدفع النفق خوادم DNS ويُربك عندما لا يفعل. افحص ما يحتويه النطاق فعلاً بدل افتراض أن محلل المضيف ينطبق. وثيقة مرجع خدمات Compose توثّق في مكان واحد كلاً من network_mode و ports وسلوك الاعتماديات، بما في ذلك سبب عدم امتلاك خدمة network_mode لعنوان خاص بها.