لماذا تتجاهل حاويات Docker مُحلِّل DNS الخاص بشبكة VPN
تنسخ الحاوية إعدادات مُحلِّل المضيف عند تشغيلها، لذلك تبقى شبكة VPN التي تعيد كتابة DNS لاحقًا غير مرئية بداخلها. مرّر المُحلِّل صراحةً.
شبكة VPN تعمل، والمتصفح يصل إلى المواقع الداخلية، ومع ذلك لا تزال الحاوية عاجزة عن تحليل الأسماء نفسها. يفشل تثبيت حزمة بخطأ في تحليل الأسماء مثل EAI_AGAIN، أو لا يستطيع تطبيق ما العثور على مضيف قاعدة بيانات يحلّه جهاز المضيف دون أي شكوى. الحاوية لا تستخدم المُحلِّل الذي ثبّته الـVPN. لقد نسخ Docker إعدادات المُحلِّل الخاصة بالمضيف عند إنشاء الحاوية، ولم ينسخها أحد مرة أخرى بعد ذلك.
منظران للمُحلِّل على جهاز واحد
على Linux، يمنح Docker كل حاوية نسخة من إعدادات المُحلِّل الخاصة بالمضيف وقت الإنشاء، مع استبعاد عناوين loopback، ويشغّل خادم DNS مدمجًا على 127.0.0.11 يمرّر الاستعلامات إلى الخارج. عميل VPN يعيد كتابة /etc/resolv.conf بعد بدء الحاوية لا يغيّر شيئًا داخلها. إعادة تشغيل الحاوية لا تساعد إلا إذا صادف أن مُحلِّل المضيف صحيح في تلك اللحظة.
يضيف Docker Desktop على macOS أو Windows طبقة إضافية، لأن الخدمة الخلفية تعيش داخل جهاز افتراضي. قد لا يكون مُحلِّل الـVPN الخاص بالمضيف مرئيًا لذلك الجهاز الافتراضي أبدًا، لذا فإن إعادة التشغيل لا تغيّر شيئًا على الإطلاق. قارن المنظرين قبل اختيار حل: docker exec mycontainer cat /etc/resolv.conf إلى جانب قائمة مُحلِّلات المضيف.
الحاوية التي تسرد مُحلِّلًا عامًا بينما يسرد المضيف مُحلِّلًا داخليًا ستحلّ الأسماء العامة وتفشل في الداخلية. هذا الانقسام هو بصمة هذه المشكلة.
الخيار A: تمرير مُحلِّل النفق لكل حاوية
يقبل Docker إعدادات DNS لكل حاوية، وهو أصغر تغيير ينجح. اقرأ عناوين مُحلِّل الـVPN أولًا: scutil --dns على macOS، و resolvectl status أو مخرجات الحالة الخاصة بالعميل على Linux. ثم ابدأ الحاوية بها، على سبيل المثال docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage. في Compose يكون الإعداد نفسه قائمة تحت الخدمة، حيث يعيش في إدارة النسخ بدلًا من سجل أوامر شخص ما.
مصفوفة dns في /etc/docker/daemon.json تنطبق على كل حاوية جديدة، وهو ما يبدو أنظف وليس كذلك. تنطبق أيضًا عندما يكون النفق معطلًا، وعندها يكسر مُحلِّل لا يمكن الوصول إليه إلا عبر الـVPN عمليات سحب الصور العادية. إعدادات كل حاوية أسهل في التبرير وأسهل في التراجع.
الخيار B: ترك الحاوية تشارك شبكة المضيف
شبكة المضيف تتجاوز النسخ تمامًا، لأن الحاوية تستخدم مُحلِّل المضيف ونفق المضيف. وهي أيضًا تزيل العزل الشبكي الذي أردته على الأرجح، ولا تتصرف بالطريقة نفسها تحت Docker Desktop. على Linux يكون الخيار العملي لأداة تُستخدم مرة واحدة وتحتاج إلى تحليل أسماء داخلية.
بالنسبة إلى عمليات البناء، لا ينطبق أي من الخيارين، لأن خطوات البناء لا ترث أعلام وقت التشغيل. ابنِ باستخدام شبكة المضيف حيث تسمح المنصة بذلك، أو أبقِ تثبيت التبعيات في مرحلة لا تحتاج إلى النفق.
ما لا يصلحه أي من الخيارين
عنوان DNS عديم النفع إذا لم يكن للحاوية مسار إليه. عادةً يجلس مُحلِّل الـVPN داخل فضاء عناوين النفق، لذا تحتاج الحاوية إلى مسار إلى تلك البادئة. الجسر الافتراضي في Docker يوجّه عادةً عبر المضيف، وهذا كافٍ عندما يكون لدى المضيف مسار النفق وتكون إعادة التوجيه مفعّلة. قد تتصادم الشبكات الجسرية المخصصة ذات تجمعات العناوين الخاصة بها مع شبكة VPN الفرعية، وعندها تذهب الاستعلامات إلى مكان آخر تمامًا.
افحص الشبكة الفرعية لشبكة Docker مقابل الشبكة الفرعية للـVPN قبل أن تنقّح المُحلِّل نفسه. التداخل ينتج عطلًا يشبه تمامًا خادم DNS معطوبًا.
تحقّق داخل الحاوية
اختبر باستخدام getent hosts db.internal داخل الحاوية بدلًا من متصفح أو بيئة تشغيل لغوية، لأن تلك تطبّق سياستها الخاصة في DNS وتخزينها المؤقت الخاص. إذا حلّ getent الاسم وظلّ التطبيق يفشل، فالمُحلِّل صحيح الآن والمشكلة المتبقية على مستوى التطبيق. وإذا لم يحلّه، فخطوة DNS لم تكتمل.
أعِد إنشاء الحاوية بعد تغيير إعدادات DNS الخاصة بها. تحرير /etc/resolv.conf داخل حاوية قيد التشغيل يزول معها ويخفي مشكلة الإعدادات للمدة التي يحتاجها أحدهم لإعادة تشغيلها بالضبط.