फॉरवर्ड होस्ट पोर्ट टू डूकर कंटेनर


167

क्या मेजबान द्वारा खोले गए डॉकटर कंटेनर एक्सेस पोर्ट होना संभव है? संभवतः मेरे पास होस्ट पर चलने वाले MongoDB और RabbitMQ हैं और मैं डेटाबेस को लिखने के लिए कतार (और वैकल्पिक रूप से) को सुनने के लिए एक डॉकर कंटेनर में एक प्रक्रिया चलाना चाहूंगा।

मुझे पता है कि मैं कंटेनर से होस्ट (-p विकल्प के माध्यम से) को एक पोर्ट अग्रेषित कर सकता हूं और डॉकटर कंटेनर के भीतर की बाहरी दुनिया (यानी इंटरनेट) से एक कनेक्शन है, लेकिन मैं RabbitMQ और MongoDB बंदरगाहों को उजागर नहीं करना चाहता मेजबान से लेकर बाहरी दुनिया तक।

संपादित करें: कुछ स्पष्टीकरण:

Starting Nmap 5.21 ( http://nmap.org ) at 2013-07-22 22:39 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00027s latency).
PORT     STATE SERVICE
6311/tcp open  unknown

joelkuiper@vps20528 ~ % docker run -i -t base /bin/bash
root@f043b4b235a7:/# apt-get install nmap
root@f043b4b235a7:/# nmap 172.16.42.1 -p 6311 # IP found via docker inspect -> gateway

Starting Nmap 6.00 ( http://nmap.org ) at 2013-07-22 20:43 UTC
Nmap scan report for 172.16.42.1
Host is up (0.000060s latency).
PORT     STATE    SERVICE
6311/tcp filtered unknown
MAC Address: E2:69:9C:11:42:65 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 13.31 seconds

कंटेनर के साथ किसी भी इंटरनेट कनेक्शन को प्राप्त करने के लिए मुझे यह चाल चलनी थी: मेरा फ़ायरवॉल नेटवर्क कनेक्शन को डॉकटर कंटेनर से बाहर तक रोक रहा है

संपादित करें : आखिरकार मैं पाइपवर्क का उपयोग करके एक कस्टम ब्रिज बनाने के साथ गया और पुल आईपी पर सेवाओं को सुनता रहा। मैं MongoDB और RabbitMQ डॉक पुल पर सुनने के बजाय इस दृष्टिकोण के साथ गया क्योंकि यह अधिक लचीलापन देता है।

जवाबों:


54

आपका डॉकटर होस्ट सभी कंटेनरों के लिए एक एडॉप्टर उजागर करता है। आप हाल के ubuntu पर हैं, तो आप चला सकते हैं

ip addr

यह आपको नेटवर्क एडेप्टर की एक सूची देगा, जिनमें से एक ऐसा कुछ दिखाई देगा

3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 22:23:6b:28:6b:e0 brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
inet6 fe80::a402:65ff:fe86:bba6/64 scope link
   valid_lft forever preferred_lft forever

आपको उस IP को (172.17.42.1) बाँधने के लिए खरगोश / मोंगो को बताना होगा। उसके बाद, आपको अपने कंटेनरों के भीतर से 172.17.42.1 पर कनेक्शन खोलने में सक्षम होना चाहिए।


36
कंटेनर को कैसे पता है कि किस आईपी को अनुरोध भेजना है? मैं यहाँ और मेरे परीक्षण रिग पर (172.17.42.1) मान को हार्डकोड कर सकता हूं, लेकिन क्या यह हमेशा सच है?), लेकिन यह किसी भी मेजबान के साथ काम करने के सिद्धांत के खिलाफ जाना लगता है!
जेपी।

2
@Seldo: उस इंटरफ़ेस को दिखाने के लिए कॉन्फ़िगरेशन की आवश्यकता है? मैं 1.7.1 docker का उपयोग कर रहा हूँ, और मेरे पास केवल loऔर है eth0
mknecht

8
क्या यह किसी भी तरह से संभव है, अगर मेजबान केवल 127.0.0.1 पर सुन रहा है?
हंसहॉर्फ़

5
"आपको उस आईपी (172.17.42.1) को बाँधने के लिए खरगोश / मोंगो को बताना होगा। उसके बाद, आपको अपने कंटेनरों के भीतर से 172.17.42.1 कनेक्शन खोलने में सक्षम होना चाहिए।" अच्छा होगा यदि आपने समझाया कि ऐसा कैसे किया जाए
Novaterata

1
जैसा कि @Novaterata ने उल्लेख किया है, क्या कोई कृपया उस प्रक्रिया को समझा सकता है
keskinsaf

122

--net=hostविकल्प का उपयोग करने के लिए एक सरल लेकिन अपेक्षाकृत असुरक्षित तरीका होगा docker run

यह विकल्प इसे बनाता है ताकि कंटेनर होस्ट के नेटवर्किंग स्टैक का उपयोग करे। तब आप होस्टनाम के रूप में "लोकलहोस्ट" का उपयोग करके होस्ट पर चलने वाली सेवाओं से जुड़ सकते हैं।

यह कॉन्फ़िगर करना आसान है क्योंकि आपको अपने docker कंटेनर के IP पते से कनेक्शन स्वीकार करने के लिए सेवा को कॉन्फ़िगर करने की आवश्यकता नहीं होगी, और आपको कनेक्ट करने के लिए docker कंटेनर को एक विशिष्ट IP पता या होस्ट नाम बताना नहीं होगा, बस एक बंदरगाह।

उदाहरण के लिए, आप निम्न कमांड को चलाकर इसका परीक्षण कर सकते हैं, जो मान लेता है कि आपकी छवि को कहा जाता है my_image, आपकी छवि में telnetउपयोगिता शामिल है , और जिस सेवा से आप जुड़ना चाहते हैं वह पोर्ट 25 पर है:

docker run --rm -i -t --net=host my_image telnet localhost 25

यदि आप इसे इस तरह करने पर विचार करते हैं, तो कृपया इस पृष्ठ पर सुरक्षा के बारे में सावधानी देखें:

https://docs.docker.com/articles/networking/

इसे कहते हैं:

--net = host - एक अलग नेटवर्क स्टैक के अंदर कंटेनर रखने को छोड़ने के लिए डॉकटर को बताता है। संक्षेप में, यह पसंद डॉकटर को कंटेनर की नेटवर्किंग को कम नहीं करने के लिए कहती है! हालांकि कंटेनर प्रक्रियाएं अपने स्वयं के फाइल सिस्टम और प्रक्रिया सूची और संसाधन सीमाओं तक सीमित रहेंगी, एक त्वरित आईपी एड्र कमांड आपको दिखाएगा कि, नेटवर्क-वार, वे मुख्य डॉकर होस्ट में "बाहर" रहते हैं और इसकी नेटवर्क इंटरफेस तक पूरी पहुंच है । ध्यान दें कि यह कंटेनर होस्ट नेटवर्क स्टैक को फिर से कॉन्फ़िगर करने की अनुमति नहीं देता है - जिसे --privileged = true - की आवश्यकता होगी, लेकिन यह कंटेनर प्रक्रियाओं को किसी अन्य रूट प्रक्रिया की तरह कम-संख्या वाले पोर्ट खोलने देता है। यह कंटेनर को डी-बस जैसी स्थानीय नेटवर्क सेवाओं का उपयोग करने की भी अनुमति देता है। इससे आपके कंप्यूटर को पुनरारंभ करने जैसे अप्रत्याशित कार्य करने में सक्षम होने के लिए कंटेनर में प्रक्रियाएँ हो सकती हैं।


12
लिनक्स पर डॉकटर का उपयोग नहीं करने वाले (उदाहरण के लिए कुछ वर्चुअलाइजेशन का उपयोग करने वाले) यह काम नहीं करेगा, क्योंकि मेजबान में वीएम होगा, न कि वास्तविक होस्ट ओएस।
सेबस्टियन ग्राफ

13
विशेष रूप से, MacOS पर, यह संभव नहीं है (कुछ वर्कअराउंड के बिना): docs.docker.com/docker-for-mac/networking/…
pje

15
MacOS पर, --net=hostअपने कंटेनर प्रक्रिया का उपयोग करके अपने होस्ट मशीन से कनेक्ट करने की अनुमति देने के लिए काम नहीं करता है localhost। इसके बजाय, अपने कंटेनर को विशेष MacOS से केवल होस्टनाम के docker.for.mac.host.internalबजाय कनेक्ट करें localhost। इसके लिए कोई अतिरिक्त पैरामीटर की आवश्यकता नहीं है docker run-eयदि आप अपना कंटेनर प्लेटफ़ॉर्म अज्ञेयवादी रखना चाहते हैं, तो आप इसे env var के रूप में पास कर सकते हैं । इस तरह आप env var में होस्ट नाम से कनेक्ट कर सकते हैं और docker.for.mac.host.internalMacOS और localhostLinux पर पास कर सकते हैं ।
तुल

18
नवीनतम होस्टनाम मैक के लिए है host.docker.internal, देखें doc
xysun

docker run --rm -it --net=host postgres bashफिर विंडोज के लिए समानpsql -h host.docker.internal -U postgres
लियो कैवलैंटे

12

आप एक ssh सुरंग भी बना सकते हैं।

docker-compose.yml:

---

version: '2'

services:
  kibana:
    image: "kibana:4.5.1"
    links:
      - elasticsearch
    volumes:
      - ./config/kibana:/opt/kibana/config:ro

  elasticsearch:
    build:
      context: .
      dockerfile: ./docker/Dockerfile.tunnel
    entrypoint: ssh
    command: "-N elasticsearch -L 0.0.0.0:9200:localhost:9200"

docker/Dockerfile.tunnel:

FROM buildpack-deps:jessie

RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive \
    apt-get -y install ssh && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

COPY ./config/ssh/id_rsa /root/.ssh/id_rsa
COPY ./config/ssh/config /root/.ssh/config
COPY ./config/ssh/known_hosts /root/.ssh/known_hosts
RUN chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/config && \
    chown $USER:$USER -R /root/.ssh

config/ssh/config:

# Elasticsearch Server
Host elasticsearch
    HostName jump.host.czerasz.com
    User czerasz
    ForwardAgent yes
    IdentityFile ~/.ssh/id_rsa

इस तरह से elasticsearchरनिंग सर्विस के साथ सर्वर के लिए एक सुरंग है (एलीस्टेकर्च, मोंगोडीबी, पोस्टग्रैसीक्यू) और उस सेवा के साथ पोर्ट 9200 को उजागर करता है।


8
आप मूल रूप से डॉकर छवि में निजी कुंजी डाल रहे हैं। रहस्य कभी भी डॉकटर की छवि में नहीं आना चाहिए।
Teoh Han Hui

2
यह अब तक का एकमात्र प्रयोग करने योग्य समझदार समाधान है।
helvete

5

मुझे एक समान समस्या एक डॉक कंटेनर से LDAP- सर्वर तक पहुँचने में थी। मैंने कंटेनर के लिए एक निश्चित आईपी सेट किया और एक फ़ायरवॉल नियम जोड़ा।

docker-compose.yml:

version: '2'
services:
  containerName:
    image: dockerImageName:latest
    extra_hosts:
      - "dockerhost:192.168.50.1"
    networks:
      my_net:
        ipv4_address: 192.168.50.2
networks:
  my_net:
    ipam:
      config:
      - subnet: 192.168.50.0/24

iptables नियम:

iptables -A INPUT -j ACCEPT -p tcp -s 192.168.50.2 -d $192.168.50.1 --dport portnumberOnHost

कंटेनर पहुंच के अंदर dockerhost:portnumberOnHost


3

यदि MongoDB और RabbitMQ होस्ट पर चल रहे हैं, तो पोर्ट को पहले से ही उजागर करना चाहिए क्योंकि यह डॉकर के भीतर नहीं है।

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

तो, मेरा अनुमान है कि आपको बिल्कुल भी ज़रूरत नहीं है -pऔर यह ठीक काम करना चाहिए :)


1
मुझे पता था कि, लेकिन ऐसा लगता है कि मुझे थोड़ी जानकारी याद आ रही है: हाल का संपादन देखें, क्योंकि मैं होस्ट पर बंदरगाहों तक पहुंचने में असमर्थ हूं।
जोएलकाइपर

2
आपको अपने मुख्य नेटवर्क इंटरफेस पर न केवल पुल को सुनने के लिए खरगोशबिट और मोंगॉडब को सेटअप करने की आवश्यकता है।
21

13
@ क्रेक आप पुल पर सुनने के लिए खरगोश और मोंगोडब कैसे प्राप्त करते हैं?
रयान वॉल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.