कंटेनर ऑफ़िस LAN पर जवाब देते हैं, और कंपनी का VPN जुड़ते ही जवाब देना बंद कर देते हैं। कंटेनर में कुछ नहीं बदला: न रीस्टार्ट, न इमेज अपडेट, न कॉन्फ़िग में बदलाव। जो बदला है वह होस्ट की रूटिंग तालिका है, जहाँ टनल द्वारा जोड़ा गया एक रूट अब Docker द्वारा दिए गए पते को ढक लेता है। सबनेट संपादित करने या VPN छूट माँगने से पहले दोनों पता योजनाएँ साथ-साथ रखें, क्योंकि सुधार बहुत अलग-अलग समय लेते हैं।

कॉन्फ़िग बदलने से पहले रूट पढ़ें

उस नेटवर्क से शुरू करें जो Docker ने वास्तव में बनाया। IPAM ब्लॉक पता योजना है, और सबनेट वह पंक्ति है जो मायने रखती है:

docker network inspect project_default --format '{{json .IPAM.Config}}'
# [{"Subnet":"172.18.0.0/16","Gateway":"172.18.0.1"}]

Compose डिफ़ॉल्ट रूप से हर नए प्रोजेक्ट को /16 देता है, इसलिए दो सेवाएँ 65,536 पतों की सीमा के भीतर रह सकती हैं। यही चौड़ाई ओवरलैप को सामान्य बनाती है: बेतरतीब ढंग से चुना गया /16 उस साइट को निगलने के लिए काफ़ी बड़ा है जहाँ आप टनल से पहुँचते हैं, और जब तक टनल ऊपर नहीं आता कोई ध्यान नहीं देता।

फिर एक कंटेनर पते के लिए रूट चयन की तुलना करें, एक बार टनल बंद और एक बार चालू होने पर:

ip route get 172.18.0.7
# 172.18.0.7 dev br-3f2a9c src 172.18.0.1

जवाब के दो आकार अलग-अलग जगहों पर ले जाते हैं। अगर आउटपुट tun0, wg0 या किसी अन्य टनल डिवाइस का नाम लेता है, तो VPN प्रीफ़िक्स ब्रिज रूट जितना ही विशिष्ट है और पैकेट कभी कंटेनर तक नहीं पहुँचता. अगर वह अब भी ब्रिज का नाम लेता है, तो होस्ट कंटेनर तक पहुँच सकता है, और आपकी खराबी फ़िल्टरिंग, DNS या केवल एक दिशा में विफल होने वाला वापसी मार्ग है।

क्यों /16 टकराव आसानी से होता है

Docker निजी पूल से ब्रिज नेटवर्क लेता है, और डिफ़ॉल्ट पूल 172.16.0.0/12 ब्लॉक से /16 टुकड़ों में आता है। कॉर्पोरेट नेटवर्क अक्सर वही निजी स्थान इस्तेमाल करते हैं, और रिमोट-एक्सेस VPN उन प्रीफ़िक्स को हर जुड़ने वाले क्लाइंट तक धकेलता है। जब दोनों पक्ष मानते हैं कि 172.18.0.0/16 उनके पास है, तो एक रूटिंग तालिका दो विरोधाभासी दावे रखती है।

विजेता प्रीफ़िक्स की लंबाई तय करती है, न कि रूट किस क्रम में दिखते हैं। जो टनल 10.0.0.0/8 धकेलता है वह 172.18.0.0/16 ब्रिज रूट को नहीं हराता, क्योंकि /8 कम विशिष्ट है। जो टनल 172.18.0.0/16, या 172.18.5.0/24 उसके भीतर धकेलता है, वह जीतता है। इसीलिए एक लैपटॉप ऑफ़िस नेटवर्क पर काम करता है और होटल Wi-Fi पर उसी VPN के साथ विफल हो जाता है: क्लाइंट को अलग-अलग प्रीफ़िक्स मिलते हैं।

वही तालिका दूसरी दिशा भी नियंत्रित करती है। जिस कंटेनर को 10.8.4.20 पर आंतरिक होस्ट चाहिए वह पैकेट अपने ब्रिज गेटवे को भेजता है, और फिर होस्ट उसे टनल में रूट करता है। यह मार्ग सामान्यतः काम करता है क्योंकि होस्ट NAT करता है, लेकिन यह तब विफल होता है जब कॉर्पोरेट पक्ष केवल लैपटॉप का VPN पता स्वीकार करता है, या जब रिवर्स-पाथ फ़िल्टरिंग असममित जवाब गिरा देती है।

तीनों सुधारों की तुलना करें

बाहर निकलने के केवल तीन रास्ते हैं, और वे इस बात में अलग हैं कि किसे मंज़ूरी देनी होगी और एक लागू करते समय क्या टूटता है।

RepairWho owns itWhat it costs
Renumber the container networkYouRecreates the network, restarts services, invalidates literal addresses in configs and scripts
Exclude your range from the tunnelNetwork teamChanges what every laptop sees, needs a change request and a client profile update
Reach the service through a published portYou and the clientOne port only, no direct container-to-container routing across the tunnel

रीनंबरिंग वह अकेला सुधार है जो आप बिना टिकट पूरा कर सकते हैं, और इसीलिए ज़्यादातर लेख वहीं रुक जाते हैं। यह नए प्रोजेक्ट में सस्ता है और महँगा तब हो जाता है जब कोई माइग्रेशन टूल या सहेजी गई कनेक्शन स्ट्रिंग किसी शाब्दिक पते की ओर इशारा करे। YAML संपादित करने से पहले उन संदर्भों की गिनती करें, बाद में नहीं।

टनल से छूट सबसे साफ़ जवाब है जब ओवरलैप उस सीमा में हो जो आपकी कंपनी वास्तव में रखती है। यह सबसे धीमी भी है, और उस ठेकेदार के लिए बेकार है जो क्लाइंट प्रोफ़ाइल नहीं बदल सकता। प्रकाशित पोर्ट या छोटा रिवर्स प्रॉक्सी बहस से बचते हैं: क्लाइंट ऐसे पते से बात करता है जिसे टनल पहले से सही रूट करता है, और केवल वही पोर्ट पहुँच योग्य होना चाहिए।

जानबूझकर एक सीमा तय करें

एक प्रोजेक्ट के लिए, compose फ़ाइल में सबनेट घोषित करें ताकि प्रोजेक्ट साझा पूल से लेना बंद कर दे:

networks:
  default:
    ipam:
      config:
        - subnet: 10.201.7.0/24

वह सीमा उस रजिस्ट्री से लें जो आपकी टीम रखती है, किसी ऐसे उदाहरण से नहीं जो खोजते समय मिला। इसे VPN द्वारा धकेले जाने वाले प्रीफ़िक्स, जिन घरेलू LAN से लोग काम करते हैं, और उसी होस्ट के अन्य कंटेनर नेटवर्क के विरुद्ध जाँचें। फिर पुनर्निर्माण की योजना बनाएँ, क्योंकि मौजूदा नेटवर्क अपना पुराना सबनेट रखता है: docker compose down, फिर up -d. docker network rm तब तक मना करता है जब तक एंडपॉइंट जुड़े हैं, और फ़ाइल में कोई भी ipv4_address प्रविष्टि नई सीमा के भीतर आनी चाहिए।

जो नेटवर्क Docker स्वयं बनाता है, उनके लिए /etc/docker/daemon.json में डेमन पूल सेट करें:

{
  "default-address-pools": [
    { "base": "10.201.0.0/16", "size": 24 },
    { "base": "10.202.0.0/16", "size": 24 }
  ]
}

पूल डेमन के फिर से शुरू होने के बाद बनाए गए नेटवर्क पर लागू होता है, और पहले से मौजूद ब्रिज अपने पते रखते हैं। यह सुविधाजनक है और भूलना आसान, इसलिए पुराने प्रोजेक्ट को तब तक ओवरलैपिंग मानें जब तक कोई उसका नेटवर्क फिर से न बनाए। Docker का इंजन नेटवर्किंग दस्तावेज़ आवंटन नियमों का वर्णन करता है, अगर समीक्षा में पूल का बचाव करना पड़े।

Linux ब्रिज और Docker Desktop अलग-अलग तरह से विफल होते हैं

Linux होस्ट पर, कंटेनर होस्ट के नेमस्पेस में ब्रिज पर बैठते हैं। एक तालिका सब कुछ तय करती है, इसलिए ऊपर की तुलना पूरी कहानी है: ब्रिज रूट पढ़ें, टनल रूट पढ़ें, और देखें कि वास्तविक कंटेनर पते के लिए कौन जीतता है।

Docker Desktop कंटेनर को अपने NAT वाले VM के पीछे रखता है। होस्ट के पास कंटेनर पते तक कोई रूट ही नहीं है; वह सेवा तक प्रकाशित पोर्ट के ज़रिए पहुँचता है, जो आमतौर पर 127.0.0.1 से बंधा होता है। इसलिए VPN क्लाइंट बिना किसी सबनेट ओवरलैप के सेवा तोड़ सकता है, या तो VM की आंतरिक सीमा के लिए रूट लगाकर, या टनल जुड़ा होने पर loopback ट्रैफ़िक रोककर। अगर होस्ट पर ip route get कंटेनर पते के लिए कोई रूट न होने की सूचना दे, तो यह अपेक्षित है, खराबी नहीं।

व्यावहारिक परिणाम यह है कि आप पहले कहाँ देखते हैं। Linux पर, रूटिंग तालिका से शुरू करें। Desktop पर, प्रकाशित पोर्ट और VPN क्लाइंट के फ़ायरवॉल नियमों से शुरू करें, फिर जाँचें कि VM का आंतरिक सबनेट टनल द्वारा धकेले जा रहे किसी चीज़ से टकराता है या नहीं।

टनल चालू रखकर सत्यापित करें

सुधरा हुआ कहने से पहले VPN को दो बार फिर से कनेक्ट करें, क्योंकि जो प्रोफ़ाइल कनेक्ट होने पर रूट धकेलता है और डिस्कनेक्ट पर वापस खींच लेता है, वह पहली कोशिश के बाद सही दिख सकता है। फिर वे जाँचें चलाएँ जो क्लाइंट वास्तव में चलाता है:

  1. ip route get होस्ट से, कंटेनर के वास्तविक पते का उपयोग करके।
  2. किसी अन्य कंटेनर से अनुरोध, यह साबित करने के लिए कि सेवा स्वयं स्वस्थ है।
  3. curl -sv http://127.0.0.1:8080/ टनल चालू होने पर क्लाइंट से, फिर traceroute -n LAN की किसी मशीन से कंटेनर पते तक।
  4. sysctl net.ipv4.conf.all.rp_filter अगर अनुरोध होस्ट तक पहुँचता है पर जवाब गायब हो जाता है।

अंत में, चुनी गई सीमा को उसी रजिस्ट्री में लिखें जिससे आपने उसे चुना था, तारीख और उसे रखने वाले प्रोजेक्ट के साथ। अगला ओवरलैप ऐसे प्रोजेक्ट से आएगा जिसे किसी ने प्रलेखित नहीं किया, और एकमात्र बचाव यह है कि सीमा जानबूझकर आरक्षित थी, बेतरतीब नहीं खींची गई।

संबंधित लेख