VPN चालू है, ब्राउज़र आंतरिक साइटों तक पहुँचता है, और कंटेनर अब भी वही नाम हल नहीं कर पाता। पैकेज इंस्टॉल EAI_AGAIN जैसी नाम-समाधान त्रुटि से मर जाता है, या कोई एप्लिकेशन ऐसा डेटाबेस होस्ट नहीं ढूँढ पाता जिसे होस्ट मशीन बिना किसी शिकायत के हल कर लेती है। कंटेनर उस रिज़ॉल्वर का उपयोग नहीं कर रहा जो VPN ने इंस्टॉल किया था। कंटेनर बनते समय Docker ने होस्ट का रिज़ॉल्वर कॉन्फ़िगरेशन कॉपी किया, और उसके बाद किसी ने उसे दोबारा कॉपी नहीं किया।

एक ही मशीन पर रिज़ॉल्वर के दो दृश्य

Linux पर, Docker बनते समय हर कंटेनर को होस्ट के रिज़ॉल्वर कॉन्फ़िगरेशन की एक कॉपी देता है, लूपबैक पते छान देता है, और 127.0.0.11 पर एक एम्बेडेड DNS सर्वर चलाता है जो प्रश्न बाहर भेजता है। कंटेनर शुरू होने के बाद /etc/resolv.conf को फिर से लिखने वाला VPN क्लाइंट उसके अंदर कुछ नहीं बदलता। कंटेनर को फिर से शुरू करना केवल तब मदद करता है जब उस पल होस्ट रिज़ॉल्वर संयोग से सही हो।

macOS या Windows पर Docker Desktop एक परत जोड़ता है, क्योंकि डेमन एक वर्चुअल मशीन में रहता है। होस्ट का VPN रिज़ॉल्वर उस VM को कभी दिख ही न पाए, इसलिए फिर से शुरू करने से कुछ भी नहीं बदलता। उपाय चुनने से पहले दोनों दृश्यों की तुलना करें: होस्ट की रिज़ॉल्वर सूची के साथ docker exec mycontainer cat /etc/resolv.conf।

जब होस्ट आंतरिक रिज़ॉल्वर सूचीबद्ध करता है और कंटेनर सार्वजनिक रिज़ॉल्वर सूचीबद्ध करता है, तो वह सार्वजनिक नाम हल करेगा और आंतरिक नामों पर विफल होगा। यही विभाजन इस समस्या का हस्ताक्षर है।

विकल्प A: हर कंटेनर के लिए टनल रिज़ॉल्वर पास करें

Docker प्रति-कंटेनर DNS सेटिंग स्वीकार करता है, और यह सबसे छोटा काम करने वाला बदलाव है। पहले VPN के रिज़ॉल्वर पते पढ़ें: macOS पर scutil --dns, Linux पर resolvectl status या क्लाइंट का अपना स्टेटस आउटपुट। फिर उनके साथ कंटेनर शुरू करें, उदाहरण के लिए docker run --dns 192.168.2.1 --dns 192.168.123.1 myimage। Compose में वही सेटिंग सेवा के अंतर्गत एक सूची है, जहाँ वह किसी के शेल इतिहास के बजाय वर्ज़न कंट्रोल में रहती है।

/etc/docker/daemon.json में dns सरणी हर नए कंटेनर पर लागू होती है, जो अधिक व्यवस्थित लगता है और है नहीं। यह तब भी लागू होती है जब टनल बंद हो, और तब केवल VPN से पहुँचने योग्य रिज़ॉल्वर सामान्य इमेज पुल तोड़ देता है। प्रति-कंटेनर सेटिंग्स समझाना आसान और वापस लेना आसान है।

विकल्प B: कंटेनर को होस्ट नेटवर्क साझा करने दें

होस्ट नेटवर्किंग कॉपी को पूरी तरह से बचा लेती है, क्योंकि कंटेनर होस्ट का रिज़ॉल्वर और होस्ट की टनल उपयोग करता है। यह वह नेटवर्क अलगाव भी हटा देती है जो आप शायद चाहते थे, और Docker Desktop के अंतर्गत यह वैसा व्यवहार नहीं करती। Linux पर आंतरिक नाम हल करने वाले एक-बार के औज़ार के लिए यह व्यावहारिक चुनाव है।

बिल्ड के लिए दोनों में से कोई विकल्प लागू नहीं होता, क्योंकि बिल्ड चरण रनटाइम फ़्लैग विरासत में नहीं लेते। जहाँ प्लेटफ़ॉर्म अनुमति दे वहाँ होस्ट नेटवर्किंग के साथ बिल्ड करें, या निर्भरता इंस्टॉल को ऐसे चरण में रखें जिसे टनल की आवश्यकता न हो।

दोनों विकल्प जो ठीक नहीं करते

अगर कंटेनर के पास उस तक कोई मार्ग नहीं है तो DNS पता बेकार है। VPN रिज़ॉल्वर आमतौर पर टनल के पता-स्थान के भीतर बैठता है, इसलिए कंटेनर को उस प्रीफ़िक्स तक रास्ता चाहिए। Docker का डिफ़ॉल्ट ब्रिज आमतौर पर होस्ट के ज़रिये बाहर रूट करता है, और यह तब पर्याप्त है जब होस्ट के पास टनल मार्ग हो और फ़ॉरवर्डिंग सक्षम हो। अपने पता-पूल वाले कस्टम ब्रिज नेटवर्क VPN सबनेट से टकरा सकते हैं, और तब प्रश्न पूरी तरह कहीं और चले जाते हैं।

खुद रिज़ॉल्वर को डीबग करने से पहले Docker नेटवर्क का सबनेट VPN सबनेट के सामने जाँचें। ओवरलैप एक विफलता पैदा करता है जो ठीक खराब DNS सर्वर जैसी दिखती है।

कंटेनर के अंदर जाँचें

ब्राउज़र या भाषा रनटाइम के बजाय कंटेनर के अंदर getent hosts db.internal से परीक्षण करें, क्योंकि वे अपनी DNS नीति और अपना कैशिंग लागू करते हैं। अगर getent नाम हल करता है और एप्लिकेशन फिर भी विफल होता है, तो रिज़ॉल्वर अब सही है और बची हुई समस्या एप्लिकेशन स्तर की है। अगर वह हल नहीं करता, तो DNS चरण पूरा नहीं हुआ।

DNS सेटिंग बदलने के बाद कंटेनर फिर से बनाएँ। चल रहे कंटेनर के अंदर /etc/resolv.conf संपादित करना उसके साथ गायब हो जाता है और कॉन्फ़िगरेशन समस्या को ठीक उतनी देर छिपाता है जितनी देर में कोई उसे फिर से शुरू करता है।

संबंधित लेख