"होस्टनाम" के माध्यम से डॉकटर कंटेनरों के बीच संवाद कैसे करें


91

मैंने अपने अखंड सर्वर को कई छोटे डॉकटर कंटेनरों में विभाजित करने की योजना बनाई है, लेकिन अभी तक "इंटर-कंटेनर संचार" के लिए एक अच्छा समाधान नहीं मिला है। यह मेरा लक्ष्य परिदृश्य है:

लक्ष्य परिदृश्य

मुझे पता है कि कंटेनरों को एक साथ कैसे जोड़ा जाए और बंदरगाहों को कैसे उजागर किया जाए, लेकिन इनमें से कोई भी समाधान मेरे लिए संतोषजनक नहीं है।

क्या पारंपरिक सर्वर नेटवर्क में कंटेनरों के बीच होस्टनाम (कंटेनर नामों) के माध्यम से संवाद करने का कोई समाधान है?


मैंने हाल ही में एक दस्तावेज लिखा है, जिसे आप ढूंढ रहे हैं। यह मूल रूप से कई कंटेनरों (एक प्रति प्रक्रिया) को स्थापित करने और उन्हें एकीकृत करने के लिए कैसे दस्तावेज़ करता है। "अंतर-कंटेनर संचार" खेल का हिस्सा है
xuhdev

मुझे बस टुट्टम ब्लॉग मिला और आधिकारिक डॉकिंग प्रलेखन में इस अनुच्छेद पर ठोकर खाई । मुझे नहीं पता कि क्या मैं इस पैराग्राफ को हर समय याद करता था या क्या इसे नया जोड़ा गया था, लेकिन यह वही होना चाहिए जो मुझे चाहिए :)
पैट्रिक गॉटहार्ड

docker 1.10 बाहर है, और docker कनेक्ट कमाल है ( github.com/docker/docker/blob/… )। देखें नीचे मेरी संपादित जवाब
VonC

2
मुझे लगता है कि आपको डॉक-कंपोज़ करने की कोशिश करनी चाहिए । बहुत अच्छा काम करता है।
सुहास चिक्कन्ना

जवाबों:


27

संपादित करें: डॉकर 1.9 के बाद, docker networkकमांड (नीचे देखें https://stackoverflow.com/a/35184695/977939 ) इसे प्राप्त करने के लिए अनुशंसित तरीका है।


डीएनएस रिकॉर्ड को स्वचालित रूप से अपडेट करने के लिए होस्ट पर एक समाधान के लिए मेरा समाधान है: "ए" रिकॉर्ड में कंटेनरों के नाम हैं और स्वचालित रूप से (हर 10 सेकंड) कंटेनर के आईपी पते को इंगित करते हैं। स्वचालित अपडेट की स्क्रिप्ट यहाँ चिपकाया जाता है:

#!/bin/bash

# 10 seconds interval time by default
INTERVAL=${INTERVAL:-10}

# dnsmasq config directory
DNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.}

# commands used in this script
DOCKER=${DOCKER:-docker}
SLEEP=${SLEEP:-sleep}
TAIL=${TAIL:-tail}

declare -A service_map

while true
do
    changed=false
    while read line
    do
        name=${line##* }
        ip=$(${DOCKER} inspect --format '{{.NetworkSettings.IPAddress}}' $name)
        if [ -z ${service_map[$name]} ] || [ ${service_map[$name]} != $ip ] # IP addr changed
        then
            service_map[$name]=$ip
            # write to file
            echo $name has a new IP Address $ip >&2
            echo "host-record=$name,$ip"  > "${DNSMASQ_CONFIG}/docker-$name"
            changed=true
        fi
    done < <(${DOCKER} ps | ${TAIL} -n +2)

    # a change of IP address occured, restart dnsmasq
    if [ $changed = true ]
    then
        systemctl restart dnsmasq
    fi

    ${SLEEP} $INTERVAL
done

सुनिश्चित करें कि आपकी dnsmasq सेवा उपलब्ध है docker0। फिर, --dns HOST_ADDRESSइस मिनी डीएनएस सेवा का उपयोग करने के लिए अपने कंटेनर को शुरू करें ।

संदर्भ: http://docs.blowb.org/setup-host/dnsmasq.html


यह दिलचस्प लग रहा है, बहुत लचीला मेरे जवाब से ज्यादा लचीला है। +1
वॉनसी

@VonC ऐसा लगता है कि नया libnetwork इस वर्कअराउंड को प्रतिस्थापित कर सकता है। हालांकि देखते हैं।
xuhdev

@xuhdev में के रूप में मैं सेटअप dnsmasq docs.blowb.org/setup-host/dnsmasq.html । लेकिन जब मैं डॉकटर कंटेनर से खुदाई का उपयोग करता हूं, तो यह समय समाप्त हो जाता है। लेकिन होस्ट docker0 इंटरफ़ेस आईपी के लिए पिंग करता है। साथ ही डॉक होस्ट कार्यों से समान docker0 आईपी के साथ खुदाई करें। क्या आपके पास कोई sugestions है?
सत्येश

1
@ शतेश शायद यह आपकी फ़ायरवॉल सेटिंग्स है जो आपके कंटेनर को होस्ट से DNS को क्वेरी करने से रोकती है?
xuhdev

@xuhdev धन्यवाद, यह मेरे मेजबान मशीन में फायरवॉल है, जो इस मुद्दे का कारण बना। एक बार जब मैंने फायरवाल को रोका, तो मेरा कंटेनर होस्ट पर dnsmasq के साथ संवाद करता है
सतीश

205

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

1) नया नेटवर्क बनाएं

$ docker network create <network-name>       

2) कंटेनरों को नेटवर्क से कनेक्ट करें

$ docker run --net=<network-name> ...

या

$ docker network connect <network-name> <container-name>

3) पिंग कंटेनर नाम से

docker exec -ti <container-name-A> ping <container-name-B> 

64 bytes from c1 (172.18.0.4): icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from c1 (172.18.0.4): icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from c1 (172.18.0.4): icmp_seq=3 ttl=64 time=0.074 ms
64 bytes from c1 (172.18.0.4): icmp_seq=4 ttl=64 time=0.074 ms

प्रलेखन के इस भाग को देखें ;

नोट: विरासत linksके विपरीत नई नेटवर्किंग पर्यावरण चर नहीं बनाएगी, न ही अन्य कंटेनरों के साथ पर्यावरण चर साझा करेगी

यह सुविधा वर्तमान में उपनामों का समर्थन नहीं करती है


4
बहुत अच्छा काम करता है। डिफ़ॉल्ट नेटवर्क डिफ़ॉल्ट रूप से इसे सक्षम क्यों नहीं करता है ??
स्टीफन

कम स्पष्ट हिस्सा यह है कि, आपको एक अलग कंटेनर में चलने वाले ऐप को पुनरारंभ करना होगा। तो कंटेनर A, B को पुनरारंभ करने के लिए कंटेनर B में चलने वाला ऐप कैसे बना सकता है? स्पष्ट रूप से, किसी प्रकार की संचार बस की आवश्यकता प्रतीत होती है। मेरे दिमाग में सबसे ऊपर सिग्नलिंग और इंटर-कंटेनर संचार के लिए रेडिस का उपयोग करना है .. इसलिए सभी कंटेनर रेडिस चैनल की सदस्यता लेते हैं और यह वहीं होगा कि वे बात करेंगे ... docker-compose में प्रकाशित बंदरगाहों में बदलाव के बारे में कैसे .yml फ़ाइल एक पूर्ण की आवश्यकता है docker-compose down,up,restart?
eigenfield

यह वही है जो मैं पूरे दिन देख रहा हूँ! पता नहीं था कि आप कंटेनर नाम / आईडी के द्वारा नेटवर्क नोड का उल्लेख कर सकते हैं। धन्यवाद!
इलियटवेसऑफ

1
@ स्टीफन यह डिफ़ॉल्ट में विकलांग bridgeपश्च संगतता की वजह से नेटवर्क लेकिन हां, मैं मानता हूँ, यह चाहिए निश्चित रूप से डिफ़ॉल्ट रूप से सक्षम हो!
हेल्मेसो

15

यही कारण है कि होना चाहिए क्या --linkके लिए है होस्टनाम भाग के लिए कम से कम,।
साथ डोकर 1.10, और पीआर 19,242 , कि होगा:

docker network create --net-alias=[]: Add network-scoped alias for the container

(नीचे अंतिम अनुभाग देखें)

यह वह है जो फ़ाइल विवरण को अपडेट कर रहा है/etc/hosts

पर्यावरण चर के अलावा, डॉकर /etc/hostsफ़ाइल में स्रोत कंटेनर के लिए एक मेजबान प्रविष्टि जोड़ता है ।

उदाहरण के लिए, LDAP सर्वर लॉन्च करें:

docker run -t  --name openldap -d -p 389:389 larrycai/openldap

और LDAP सर्वर का परीक्षण करने के लिए एक छवि परिभाषित करें:

FROM ubuntu
RUN apt-get -y install ldap-utils
RUN touch /root/.bash_aliases
RUN echo "alias lds='ldapsearch -H ldap://internalopenldap -LL -b
ou=Users,dc=openstack,dc=org -D cn=admin,dc=openstack,dc=org -w
password'" > /root/.bash_aliases
ENTRYPOINT bash

आप परीक्षण छवि के भीतर ' openldap' कंटेनर को ' internalopenldap' के रूप में उजागर कर सकते हैं -

 docker run -it --rm --name ldp --link openldap:internalopenldap ldaptest

फिर, यदि आप 'lds' टाइप करते हैं, तो वह उपनाम काम करेगा:

ldapsearch -H ldap://internalopenldap ...

वह लोगों को लौटा देगा। मतलब इमेज internalopenldapसे सही तरीके से पहुंचा है ldaptest


बेशक, डॉकटर 1.7 जोड़ देगा libnetwork, जो कंटेनरों को जोड़ने के लिए एक देशी गो कार्यान्वयन प्रदान करता है। ब्लॉग पोस्ट देखें ।
इसने कंटेनर नेटवर्क मॉडल (CNM) के साथ एक और पूर्ण वास्तुकला पेश किया।

https://blog.docker.com/media/2015/04/cnm-model.jpg

यह नए "नेटवर्क" कमांड के साथ डॉकर सीएलआई को अपडेट करेगा, और दस्तावेज़ों को " -net" ध्वज का उपयोग कैसे किया जाता है, जो कंटेनरों को नेटवर्क में असाइन करने के लिए उपयोग किया जाता है।


डॉकटर १.१० में एक नया खंड नेटवर्क-स्कॉप्ड उर्फ ​​है , जिसे अब आधिकारिक रूप से प्रलेखित किया गया हैnetwork connect :

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

उपरोक्त उदाहरण के साथ जारी रखते हुए, isolated_nwनेटवर्क उपनाम के साथ एक और कंटेनर बनाएं ।

$ docker run --net=isolated_nw -itd --name=container6 -alias app busybox
8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17

--alias=[]         

कंटेनर के लिए नेटवर्क-स्कॉप्ड उपनाम जोड़ें

आप --linkकिसी अन्य कंटेनर को पसंदीदा उपनाम से लिंक करने के लिए विकल्प का उपयोग कर सकते हैं

आप उन कंटेनरों को रोक सकते हैं, पुनः आरंभ कर सकते हैं, और उन कंटेनरों को रोक सकते हैं जो एक नेटवर्क से जुड़े हैं। रुके हुए कंटेनर जुड़े रहते हैं और एक नेटवर्क निरीक्षण द्वारा प्रकट किया जा सकता है। जब कंटेनर बंद हो जाता है, तो यह नेटवर्क पर तब तक दिखाई नहीं देता है जब तक आप इसे पुनरारंभ नहीं करते हैं।

यदि निर्दिष्ट किया जाता है, तो कंटेनर के आईपी पते (एस) को फिर से लागू किया जाता है जब एक रोका कंटेनर को पुनरारंभ किया जाता है। यदि IP पता अब उपलब्ध नहीं है, तो कंटेनर प्रारंभ करने में विफल रहता है।

यह निर्धारित करने का एक तरीका है कि आईपी पता उपलब्ध है --ip-range, नेटवर्क बनाते समय निर्दिष्ट करना है, और उस सीमा के बाहर से स्थिर आईपी पता (तों) चुनना है। यह सुनिश्चित करता है कि आईपी पता किसी अन्य कंटेनर को नहीं दिया गया है जबकि यह कंटेनर नेटवर्क पर नहीं है।

$ docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 multi-host-network

$ docker network connect --ip 172.20.128.2 multi-host-network container2
$ docker network connect --link container1:c1 multi-host-network container2

3
--Link की समस्या यह है, कि आप लिंक किए गए कंटेनरों को पुनः आरंभ किए बिना एक कंटेनर को पुनरारंभ करने में असमर्थ हैं। जब आप मेरे ग्राफिक को देखते हैं, तो MySQL कंटेनर को रीस्टार्ट करने से अन्य कंटेनर रीस्टार्ट का एक कैस्केड हो जाएगा।
पैट्रिक गोथार्ड

3

संपादित करें : यह अब एजिंग ब्लीडिंग नहीं है: http://blog.docker.com/2016/02/docker-1-10/

मूल उत्तर
मैंने पूरी रात उसके साथ संघर्ष किया। यदि आप एजिंग ब्लीडिंग से डरते नहीं हैं, तो डॉक इंजन और डॉकर के नवीनतम संस्करण में लिबनेटवर्क लागू किया जाता है।

सही कॉन्फ़िगरेशन फ़ाइल (जिसे संस्करण 2 में डालने की आवश्यकता है) के साथ, आप ऐसी सेवाएँ बनाएंगे जो सभी एक-दूसरे को देखेंगे। और, बोनस, आप उन्हें डॉक-कंपोज़ के साथ स्केल कर सकते हैं (आप किसी भी सेवा को स्केल कर सकते हैं जो होस्ट के लिए पोर्ट को बाध्य नहीं करता है)

यहाँ एक उदाहरण फ़ाइल है

version: "2"
services:
  router:
    build: services/router/
    ports:
      - "8080:8080"
  auth:
    build: services/auth/
  todo:
    build: services/todo/
  data:
    build: services/data/

और कम्पोज़ फ़ाइल के इस नए संस्करण के लिए संदर्भ: https://github.com/docker/compose/blob/1.6.0-rc1/docs/networking.md


1

जहां तक ​​मुझे पता है, केवल डॉकर का उपयोग करके यह संभव नहीं है। कंटेनर आईपी को होस्ट करने के लिए आपको कुछ DNS की आवश्यकता है: होस्टनाम में।

यदि आप बॉक्स समाधान से बाहर चाहते हैं। एक समाधान उदाहरण के लिए उपयोग करना है Kontena । यह बुन से नेटवर्क ओवरले तकनीक के साथ आता है और इस तकनीक का उपयोग प्रत्येक सेवा के लिए वर्चुअल प्राइवेट लैन नेटवर्क बनाने के लिए किया जाता है और हर सेवा तक पहुंचा जा सकता है service_name.kontena.local-address

यहाँ Wordpress एप्लीकेशन की YAML फ़ाइल का सरल उदाहरण है जहाँ Wordpress सेवा MySQL सर्वर से wordpress-mysql.kontena.local पते के साथ जुड़ती है:

wordpress:                                                                         
  image: wordpress:4.1                                                             
  stateful: true                                                                   
  ports:                                                                           
    - 80:80                                                                      
  links:                                                                           
    - mysql:wordpress-mysql                                                        
  environment:                                                                     
    - WORDPRESS_DB_HOST=wordpress-mysql.kontena.local                              
    - WORDPRESS_DB_PASSWORD=secret                                                 
mysql:                                                                             
  image: mariadb:5.5                                                               
  stateful: true                                                                   
  environment:                                                                     
    - MYSQL_ROOT_PASSWORD=secret
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.