एक अलग भौतिक नेटवर्क इंटरफ़ेस और डिफ़ॉल्ट गेटवे का उपयोग करते हुए डॉक कंटेनर से रूटिंग


13

पृष्ठभूमि की जानकारी

मेरे पास दो नेटवर्क इंटरफेस के साथ एक सर्वर है जो डॉकर चला रहा है। डॉकर, कुछ वर्चुअलाइजेशन टूल की तरह, एक लिनक्स ब्रिज इंटरफेस बनाता है जिसे कहा जाता है docker0। यह इंटरफ़ेस डिफ़ॉल्ट रूप से IP के साथ कॉन्फ़िगर किया गया है 172.17.42.1और सभी डॉकटर कंटेनर इस इंटरफ़ेस के साथ अपने गेटवे के रूप में संवाद करते हैं और एक ही /16श्रेणी में IP पते असाइन किए जाते हैं । जैसा कि मैं इसे समझता हूं, कंटेनरों से / के लिए सभी नेटवर्क ट्रैफ़िक एक NAT के माध्यम से जाता है, इसलिए आउटबाउंड से यह प्रतीत होता है 172.17.42.1, और इनबाउंड इसे भेजा जाता है 172.17.42.1

मेरा सेटअप ऐसा दिखता है:

                                          +------------+        /
                                          |            |       |
                            +-------------+ Gateway 1  +-------
                            |             | 10.1.1.1   |     /
                     +------+-------+     +------------+    |
                     |     eth0     |                      /
                     |   10.1.1.2   |                      |
                     |              |                      |
                     | DOCKER HOST  |                      |
                     |              |                      | Internet
                     |   docker0    |                      |
                     |   (bridge)   |                      |
                     |  172.17.42.1 |                      |
                     |              |                      |
                     |     eth1     |                      |
                     |  192.168.1.2 |                      \
                     +------+-------+     +------------+    |
                            |             |            |     \
                            +-------------+ Gateway 2  +-------
                                          | 192.168.1.1|       |
                                          +------------+            

समस्या

मैं दूसरे ट्रैफ़िक के लिए / से किसी भी डॉकटर कंटेनरों तक के सभी ट्रैफ़िक eth1 192.168.1.2को एक डिफ़ॉल्ट गेटवे के लिए रूट करना चाहता हूं 192.168.1.1, जबकि होस्ट मशीन के लिए / से सभी ट्रैफ़िक eth0 10.1.1.2इंटरफ़ेस को डिफ़ॉल्ट गेटवे के लिए बाहर जाना है 10.1.1.1। मैंने अब तक कोई फायदा नहीं उठाने के लिए कई तरह की कोशिश की है, लेकिन मुझे लगता है कि सही करने के लिए सबसे करीब एक चीज है iproute2 का उपयोग करना।

# Create a new routing table just for docker
echo "1 docker" >> /etc/iproute2/rt_tables

# Add a rule stating any traffic from the docker0 bridge interface should use 
# the newly added docker routing table
ip rule add from 172.17.42.1 table docker

# Add a route to the newly added docker routing table that dictates all traffic
# go out the 192.168.1.2 interface on eth1
ip route add default via 192.168.1.2 dev eth1 table docker

# Flush the route cache
ip route flush cache

# Restart the Docker daemon so it uses the correct network settings
# Note, I do this as I found Docker containers often won't be able
# to connect out if any changes to the network are made while it's     
# running
/etc/init.d/docker restart

जब मैं एक कंटेनर लाता हूं, तो मैं ऐसा करने के बाद इसे बिल्कुल भी बाहर नहीं निकाल सकता। मैं अनिश्चित हूँ अगर पुल इंटरफेस को उसी तरह से नियंत्रित किया जाता है जैसे कि इस तरह के रूटिंग के लिए भौतिक इंटरफेस हैं, और बस एक पवित्रता की जांच के साथ-साथ इस पर कोई भी सुझाव देना चाहिए कि मैं इस सरल कार्य को कैसे पूरा कर सकता हूं।


NAT के बारे में आपकी टिप्पणी सही नहीं है। यह 172.17.0.0/16 स्रोत पते पर प्रसारित करने के लिए सेट है जहां आउटपुट इंटरफ़ेस docker0 नहीं है। यानी- POSTROUTING -s 172.17.0.0/16! -o docker0 -j MASQUERADE इसका मतलब यह है कि अगर डॉक कंटेनर से निकलने वाला पैकेट eth0 या eth1 के माध्यम से बाहर निकलता है तो यह उस आईपी एड्रेस को लेगा, न कि 172.17.xx IP को।
मैट

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

मुझे यकीन नहीं है कि मैंने जो सुझाया वह काम नहीं कर रहा है। लेकिन एक अन्य विकल्प पाइपवर्क का उपयोग करना हो सकता है। github.com/jpetazzo/pipework इसके अलावा docker मदद का उन्नत नेटवर्किंग अनुभाग पढ़ने के लिए उपयोगी हो सकता है। docs.docker.com/articles/networking
मैट

@ इस पर आपके सुझाव के लिए मै आपको धन्यवाद देता हूँ। मैंने जो पढ़ा है उससे पाइपवर्क करने के लिए कंटेनर को सही गेटवे तक पहुंचाने के लिए अतिरिक्त कमांड की आवश्यकता होती है जो सुरक्षा भेद्यता की तरह लगता है। यह मूल रूप से कई मेजबानों को एक साथ कंटेनरों को जोड़ने के लिए बनाया गया था, जो वास्तव में यहाँ मेरा लक्ष्य नहीं है। डॉकर उन्नत नेटवर्किंग डॉक्स के लिए, मैं एक बार फिर देखूंगा, लेकिन यह इस स्थिति में अब तक मददगार नहीं रहा है (मैंने यहां पोस्ट करने से पहले इसे पढ़ा था)। मैं इस पोस्ट का लिंक docker Github जारी करने वाले पेज पर पोस्ट करने जा रहा हूं और देखता हूं कि यह वहां से कैसे जाता है।

यहाँ Github मुद्दे पर वापस लिंक दिया गया है: github.com/docker/docker/issues/13762

जवाबों:


1

आपको iptables सेटअप पर भी अधिक देखना पड़ सकता है। डॉकटर सब ट्रैफ़िक को कंटेनर सबनेट से उत्पन्न करता है, जो 172.17.0.0/16, 0.0.0.0 तक कहता है। यदि आप चलते हैं iptables -L -n -t nat, तो आप नेट टेबल के नीचे POSTROUTING श्रृंखला देख सकते हैं जो ऐसा करती है -

चेन पोस्टिंग (पॉलिसी ACCEPT)
लक्ष्य विरोध ऑप्ट स्रोत गंतव्य
MASQUERADE सभी - 172.17.0.0/16 0.0.0.0/0

अब, आप इस नियम को हटा सकते हैं और इसे एक नियम से बदल सकते हैं, जो कंटेनरों के सबनेट से निकलने वाले सभी ट्रैफ़िक को आपके दूसरे इंटरफ़ेस के IP - 192.168.1.2 पर भेज देता है, जैसा कि आप चाहते हैं। हटाने का नियम यह मानते हुए होगा कि यह पोस्टिंग श्रृंखला के तहत पहला नियम है -

iptables -t nat -D POSTROUTING 1

फिर आप इस कस्टम नियम को जोड़ते हैं -

iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -j SNAT --to-source 192.168.1.2

वास्तव में यह आउटपुट इंटरफ़ेस के लिए masquarades है। वह गंतव्य भाग केवल यह कह रहा है कि स्रोत सबनेट से किसी भी गंतव्य के लिए आने वाले किसी भी ट्रैफ़िक को मास्क किया जाएगा।
मैट

दुर्भाग्य से यह काम नहीं किया। मेरे पूरी प्रक्रिया को चलाने के लिए किया गया था: ip rule add from 172.17.0.0/16 table docker ip route add default via 192.168.1.2 dev eth1 table docker ip route flush cache iptables -t nat -D POSTROUTING 1 iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -j SNAT --to-source 192.168.1.2 /etc/init.d/docker restart। फिर मैंने एक कंटेनर से एक पिंग आउट और एक ट्रेसरआउट चलाने की कोशिश की, और कुछ भी करने में असमर्थ था।

मेरे पास एक समान आवश्यकता थी, मेजबान के पास सार्वजनिक आईपी तक पहुंचने के लिए द्वितीयक आईपी सेटअप है। और मैं चाहता था कि डॉकटर कंटेनर उसी का पालन करें। इस मामले में यह काम किया: "iptables -t nat -I POSTROUTING 1 -s 172.17.0.0/16 -d PUBIP / 32 -j SNAT --to-source SECONDARYIP"
Ram

1

एक मित्र और मैं इस सटीक समस्या में भाग गए, जहाँ हम कई नेटवर्क इंटरफेस सर्विसिंग अनुरोधों का समर्थन करना चाहते थे। हम विशेष रूप से AWS EC2 सेवा के साथ काम कर रहे थे, जहाँ हम अतिरिक्त इंटरफेस भी ला रहे थे / कॉन्फ़िगर / कॉन्फ़िगर कर रहे थे। इस परियोजना में , आपकी आवश्यकता से अधिक है इसलिए मैं केवल वही शामिल करने का प्रयास करूंगा जिसकी आपको यहां आवश्यकता है।

सबसे पहले, हमने जो किया उसके लिए एक अलग रूट तालिका बनाई गई eth1:

ip route add default via 192.168.1.2 dev eth1 table 1001

आगे हमने कुछ कनेक्शन चिह्नों को सेट करने के लिए मैंगल तालिका को कॉन्फ़िगर किया है eth1:

iptables -t mangle -A PREROUTING -i eth1 -j MARK --set-xmark 0x1001/0xffffffff
iptables -t mangle -A PREROUTING -i eth1 -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff

अंत में हम सभी fwmarkबनाए गए नए टेबल का उपयोग करने के लिए इस नियम को जोड़ते हैं ।

ip rule add from all fwmark 0x1001 lookup 1001

नीचे दिए गए iptablesकमांड कनेक्शन के निशान को पुनर्स्थापित करेगा और फिर रूटिंग नियम को सही रूटिंग टेबल का उपयोग करने की अनुमति देगा।

iptables -w -t mangle -A PREROUTING -i docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff

मेरा मानना ​​है कि यह सब हमारे अधिक जटिल उदाहरण से आवश्यक है जहां (जैसे मैंने कहा) हमारी परियोजना eth1बूट समय पर इंटरफ़ेस को संलग्न / कॉन्फ़िगर / ला रही थी।

अब यह उदाहरण कनेक्शन के eth0अनुरोधों से सेवा लेने से नहीं रोक docker0सकता, लेकिन मेरा मानना ​​है कि आप इसे रोकने के लिए एक रूटिंग नियम जोड़ सकते हैं।


@stuntmachine अगर आप इसे बाहर की कोशिश करने का मौका था तो बस उत्सुक? यदि आप पहले से ही अपने दम पर कुछ पता लगा चुके हैं, तो क्या आप अपना समाधान साझा कर पाएंगे?
विलियम्सबदेव

हाय @ विलियम्सबदेव - पुरानी पोस्ट और एक लंबा शॉट, लेकिन क्या आपको लगता है कि यह समाधान एसओ पर मेरे मुद्दे के लिए भी काम करेगा? stackoverflow.com/questions/51312310/…
जॉली रोजर

2
जॉली रोजर - मुझे विश्वास है कि यह आपके मुद्दे को हल करेगा। मैंने हाल ही में एक और टीम से इस ब्लॉग पोस्ट के बारे में पूछा है (मूल रूप से यहाँ भी यही समाधान है) और उन्होंने कहा कि इसने बहुत अच्छा काम किया। williamsbdev.com/posts/docker-connection-marking
विलियम्सबेडदेव

0

बहाना 172.17.42.1 से नहीं है, बल्कि है

 -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

इसका मतलब है कि यह नियम सही काम नहीं करेगा।

ip rule add from 172.17.42.1 table docker

इसके बजाय कोशिश करें

ip rule add from 172.17.0.0/16 table docker

दुर्भाग्य से यह काम नहीं किया। मेरे कंटेनर अभी भी होस्ट के रूप में एक ही डिफ़ॉल्ट गेटवे से बाहर जा रहे थे। यहाँ मैं क्या भागा: ip rule add from 172.17.0.0/16 table docker ip route add default via 192.168.1.2 dev eth1 table docker ip route flush cache /etc/init.d/docker restart कंटेनर में से मैं एक ट्रेसरआउट चला और पहला हॉप 10.1.1.1 था जब इसे 192.168.1.1 होना चाहिए था
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.