दूसरे कंटेनर से एक डॉक कंटेनर को एक्सेस करना


93

मैंने दो अलग-अलग छवियों के आधार पर दो डॉकटर कंटेनर बनाए। एक डीबी और दूसरा वेबसर्वर के लिए। दोनों कंटेनर मेरे मैक ओएक्सएक्स पर चल रहे हैं।

मैं मेजबान मशीन से डीबी कंटेनर का उपयोग कर सकता हूं और उसी तरह मेजबान मशीन से वेबसर्वर का उपयोग कर सकता हूं।

हालाँकि, मैं वेबसर्वर से db कनेक्शन का उपयोग कैसे करूँ?

जिस तरह से मैंने db कंटेनर शुरू किया है

docker run --name oracle-db -p 1521:1521 -p 5501:5500 oracle/database:12.1.0.2-ee

मैं wls कंटेनर के रूप में शुरू कर दिया

docker run --name oracle-wls -p 7001:7001 wls-image:latest

मैं होस्ट से db को कनेक्ट करके एक्सेस कर सकता हूं

sqlplus scott/welcome1@//localhost:1521/ORCLCDB

मैं मेजबान के रूप में भेड़ियों का उपयोग कर सकता हूं

http://localhost:7001/console

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

यह उत्तर मैक ओएस में एक कंटेनर से लोकलहोस्ट का उपयोग करने में मदद कर सकता है
चाजुन झोंग

बाहरी नेटवर्किंग के लिए, इस समाधान ने मेरे लिए काम किया stackoverflow.com/a/38089080/1770571
सलमा गोमा

जवाबों:


51

सबसे आसान तरीका है --link का उपयोग करना, हालाँकि docker के नए संस्करण उससे दूर जा रहे हैं और वास्तव में स्विच को जल्द ही हटा दिया जाएगा।

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

https://deis.com/blog/2016/connecting-docker-containers-1/

जिस हिस्से में आप रुचि रखते हैं, वह दो कंटेनरों के बीच का संचार है। सबसे आसान तरीका है, वेबसर्वर कंटेनर से नाम से DB कंटेनर को देखें।

उदाहरण:

आपने डीबी कंटेनर db1और वेबसर्वर कंटेनर का नाम दिया web0। कंटेनर दोनों पुल नेटवर्क पर होना चाहिए, जिसका अर्थ है कि वेब कंटेनर को DB कंटेनर से कनेक्ट करने में सक्षम होना चाहिए।

इसलिए यदि आपके पास आपके ऐप के लिए एक वेब कॉन्फिग फ़ाइल है, तो DB होस्ट के लिए आप नाम का उपयोग करेंगे db1

यदि आप docker के पुराने संस्करण का उपयोग कर रहे हैं, तो आपको --link का उपयोग करना चाहिए।

उदाहरण:

चरण 1: docker run --name db1 oracle/database:12.1.0.2-ee

तब जब आप वेब ऐप शुरू करते हैं। उपयोग:

चरण 2: docker run --name web0 --link db1 webapp/webapp:3.0

और वेब ऐप को डीबी से जोड़ा जाएगा। हालाँकि, जैसा कि मैंने कहा था - जल्द ही स्विच को हटा दिया जाएगा।

मैं इसके बजाय docker कंपोज़ का उपयोग करूंगा, जो आपके लिए एक नेटवर्क बनाएगा। तथापि; आपको अपने सिस्टम के लिए डॉक कम्पोज़ डाउनलोड करने की आवश्यकता होगी। https://docs.docker.com/compose/install/#prerequisites

एक उदाहरण सेटअप इस तरह है:

फ़ाइल का नाम है base.yml

version: "2"
services:
  webserver:
    image: "moodlehq/moodle-php-apache:7.1
    depends_on:
      - db
    volumes:
      - "/var/www/html:/var/www/html"
      - "/home/some_user/web/apache2_faildumps.conf:/etc/apache2/conf-enabled/apache2_faildumps.conf"
    environment:
      MOODLE_DOCKER_DBTYPE: pgsql
      MOODLE_DOCKER_DBNAME: moodle
      MOODLE_DOCKER_DBUSER: moodle
      MOODLE_DOCKER_DBPASS: "m@0dl3ing"
      HTTP_PROXY: "${HTTP_PROXY}"
      HTTPS_PROXY: "${HTTPS_PROXY}"
      NO_PROXY: "${NO_PROXY}"
  db:
    image: postgres:9
    environment:
      POSTGRES_USER: moodle
      POSTGRES_PASSWORD: "m@0dl3ing"
      POSTGRES_DB: moodle
      HTTP_PROXY: "${HTTP_PROXY}"
      HTTPS_PROXY: "${HTTPS_PROXY}"
      NO_PROXY: "${NO_PROXY}"

यह नेटवर्क को एक सामान्य नाम देगा, मैं अपने सिर के ऊपर से याद नहीं रख सकता कि यह नाम क्या है, जब तक कि आप --name स्विच का उपयोग न करें।

अर्थात docker-compose --name setup1 up base.yml

नोट: यदि आप --नाम स्विच का उपयोग करते हैं, तो आपको इसे तब उपयोग करने की आवश्यकता होगी जब कभी कॉल करने वाला डॉकिंग कॉल करता है, इसलिए docker-compose --name setup1 downऐसा आपके पास अधिक हो सकता है तो वेबसर्वर और डीबी का एक उदाहरण है, और इस मामले में, इसलिए डॉक कंपोजर जानता है कि क्या उदाहरण आप के खिलाफ आदेश चलाना चाहते हैं; और यह भी कि आप एक बार में एक और अधिक हो सकता है। CI / CD के लिए बढ़िया, यदि आप समान सर्वर पर समानांतर में परीक्षण चला रहे हैं।

डॉकर कंपोज़ में भी डॉकटर के समान कमांड हैं docker-compose --name setup1 exec webserver do_some_command

सबसे अच्छा हिस्सा है, अगर आप db या ऐसा कुछ बदलना चाहते हैं, जिसमें यूनिट टेस्ट के लिए आप एक अतिरिक्त .yml फ़ाइल को कमांड में शामिल कर सकते हैं और यह समान नामों के साथ किसी भी आइटम को अधिलेखित कर देगा, मुझे लगता है कि यह एक महत्वपूर्ण => मूल्य प्रतिस्थापन के रूप में है। ।

उदाहरण:

db.yml

version: "2"
services:
  webserver:
    environment:
      MOODLE_DOCKER_DBTYPE: oci
      MOODLE_DOCKER_DBNAME: XE
  db:
    image: moodlehq/moodle-db-oracle

फिर कॉल करो docker-compose --name setup1 up base.yml db.yml

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

मुझे लगता है कि यह वास्तव में आपके मामले में अधिक उपयोगी सेटअप हो सकता है। चूंकि आप उन सभी चरों को सेट कर सकते हैं जिनकी आपको yml फ़ाइलों में आवश्यकता होती है और जब आप उन्हें शुरू करते हैं तो केवल docker कंपोज़ के लिए कमांड चलाते हैं। तो एक और इसे शुरू करें और इसे सेटअप भूल जाएं।

नोट: मैंने उपयोग नहीं किया --portकमांड, चूंकि कंटेनर को उजागर करने के लिए कंटेनर-> कंटेनर संचार की आवश्यकता नहीं है। यह केवल तभी आवश्यक है जब आप होस्ट को कंटेनर से कनेक्ट करना चाहते हैं, या होस्ट के बाहर से आवेदन करना चाहते हैं। यदि आप पोर्ट को उजागर करते हैं, तो पोर्ट सभी संचार के लिए खुला है जिसे होस्ट अनुमति देता है। तो पोर्ट 80 पर वेब को उजागर करना भौतिक मेजबान पर एक वेबसर्वर शुरू करने के समान है और यदि बाहरी इसे अनुमति देता है, तो बाहरी कनेक्शन की अनुमति देगा। इसके अलावा, अगर आप एक बार में एक वेब ऐप चलाना चाहते हैं, तो किसी भी कारण से, तो पोर्ट 80 को उजागर करने से आप अतिरिक्त वेब-वे को चलाने से रोक सकते हैं यदि आप उस पोर्ट पर भी एक्सपोज़ करने की कोशिश करते हैं। इसलिए, CI / CD के लिए बंदरगाहों को उजागर नहीं करना सबसे अच्छा है, और यदि --name स्विच के साथ docker कंपोज़ का उपयोग करते हैं, तो सभी कंटेनर अपने स्वयं के नेटवर्क पर होंगे, इसलिए वे टकराएंगे नहीं। तो आपके पास बहुत सारे कंटेनर होंगे।

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

उदाहरण:

docker network create test_network

उपरोक्त कमांड एक "test_network" बनाएगा जिसे आप अन्य कंटेनरों को भी संलग्न कर सकते हैं। जिसे --networkस्विच ऑपरेटर के साथ आसान बनाया गया है ।

उदाहरण:

docker run \
    --detach \
    --name db1 \
    --network test_network \
    -e MYSQL_ROOT_PASSWORD="${DBPASS}" \
    -e MYSQL_DATABASE="${DBNAME}" \
    -e MYSQL_USER="${DBUSER}" \
    -e MYSQL_PASSWORD="${DBPASS}" \
    --tmpfs /var/lib/mysql:rw \
    mysql:5

बेशक, अगर आपके पास प्रॉक्सी नेटवर्क सेटिंग्स हैं, तो आपको "-e" या "-env-file" स्विच स्टेटमेंट का उपयोग करके उन कंटेनरों में पास करना चाहिए। तो कंटेनर इंटरनेट के साथ संवाद कर सकता है। डॉकर का कहना है कि प्रॉक्सी सेटिंग्स को डॉकटर के नए संस्करणों में कंटेनर द्वारा अवशोषित किया जाना चाहिए; हालाँकि, मैं अभी भी आदत के रूप में उन्हें पारित करता हूं। यह "--लिंक" स्विच के लिए प्रतिस्थापन है जो दूर जा रहा है। एक बार जब कंटेनर आपके द्वारा बनाए गए नेटवर्क से जुड़ जाते हैं, तब भी आप कंटेनर के 'नाम' का उपयोग करके अन्य कंटेनरों से उन कंटेनरों को संदर्भित कर सकते हैं। ऊपर दिए गए उदाहरण के अनुसार db1। आपको बस यह सुनिश्चित करना है कि सभी कंटेनर एक ही नेटवर्क से जुड़े हैं, और आप जाने के लिए अच्छे हैं।

एक cicd पाइपलाइन में नेटवर्क का उपयोग करने के विस्तृत उदाहरण के लिए, आप इस लिंक का उल्लेख कर सकते हैं: https://git.in.moodle.com/integration/nightlyscripts/blob/master/runner/master/run.sh

कौन सी स्क्रिप्ट है जो मडल के लिए एक विशाल एकीकरण परीक्षणों के लिए जेनकिंस में चलाई गई है, लेकिन विचार / उदाहरण का उपयोग कहीं भी किया जा सकता है। मुझे उम्मीद है कि इससे दूसरों को मदद मिलेगी।


1
यदि पहला लिंक काम नहीं करता है, तो आप इस का उपयोग कर सकते हैं। linode.com/docs/applications/containers/…
Caperneoignis

1
डॉकिंग कंपोज़ करने या नेटवर्क करने के लिए, वेबसर्वर डीबी को कैसे संदर्भित करेगा? क्या यह कंटेनर के नाम का उपयोग करेगा? ऐसा लगता है कि दूसरी कड़ी में यह मामला है: इसलिए यदि आप एक डीबी और एक एपीपी को परिभाषित करते हैं, तो ऐप को इस मामले में संदर्भ देना होगा: psql -U {USER} -h database -p 5432 {DATABASE}कंटेनर के भीतर से अगर मुझे इसमें खोल दिया गया था
19

1
@Fallenreaper यदि आप कंटेनर में हैं और docker की रचना है तो आप "सेवाओं:" के तहत उपयोग किए जाने वाले नाम का उपयोग करेंगे, यदि आपने स्पष्ट रूप से इसे नाम नहीं दिया है। तो उदाहरण में आप "वेबसर्वर" का उपयोग करेंगे यदि आप शेल में "डीबी" कंटेनर से कनेक्ट करने का प्रयास कर रहे थे। उदाहरण के लिए db.yml को देखें आप वेबसर्वर और db नामों का उपयोग करेंगे। देरी के लिए क्षमा करें, हटा दिया गया और सूचना भूल गया।
Caperneoignis

52

यह आसान है। यदि आपके पास दो या अधिक चलने वाले कंटेनर हैं, तो अगले चरण पूरा करें:

docker network create myNetwork
docker network connect myNetwork web1
docker network connect myNetwork web2

अब आप web1 से web2 कंटेनर या दूसरे तरीके से जोड़ते हैं।

आंतरिक नेटवर्क IP पते का उपयोग करें जिन्हें आप चलाकर पा सकते हैं:

docker network inspect myNetwork

ध्यान दें कि केवल आंतरिक आईपी पते और पोर्ट नेटवर्क ब्रिज से जुड़े कंटेनरों के लिए सुलभ हैं।

उदाहरण के लिए, यह मानकर कि web1 कंटेनर को इसके साथ शुरू किया गया था: docker run -p 80:8888 web1(इसका अर्थ है कि इसका सर्वर आंतरिक रूप से पोर्ट 8888 पर चल रहा है), और निरीक्षण से myNetworkपता चलता है कि web1 का IP 172.0.0.2 है, आप web2 से web1 का उपयोग करके कनेक्ट कर सकते हैं curl 172.0.0.2:8888)।


1
नमस्ते, और मैं web1 से web2 से कैसे जुड़ूं? IP, होस्टनाम द्वारा? यह जानकारी कहाँ से मिलेगी?
हेनरी .विला

फ़ाइल docker-compose.yml में नेटवर्क बनाएँ: myNetwork।
MxWild

14
@ हेनरीविला आप केवल web1होस्टनाम के रूप में कंटेनर के नाम (जैसे ) का उपयोग करते हैं।
पास्कल

19

आपको होस्ट मशीन के आईपी के माध्यम से डीबी तक पहुंचना होगा, या यदि आप इसे लोकलहोस्ट के माध्यम से एक्सेस करना चाहते हैं: 1521, तो वेबसर्वर चलाएं जैसे -

docker run --net=host --name oracle-wls wls-image:latest

यहाँ देखें


1
यह वास्तविक जीवन में कैसे काम करेगा क्योंकि मशीन के कंटेनर चल रहे हैं, इसके आधार पर मेजबान के आईपी बदल जाएंगे।
विक

1
यह तभी मान्य है जब मशीन में स्टैटिक आईपी या डीएनएस हो, अन्यथा दूसरे दृष्टिकोण के साथ जाएं।
xitter

मैं इस के साथ मुद्दा है लगता है। मेरा सटीक रन कमांड है: docker run --name ora-tools-wls -it -p 7001: 7001 यह काम करता है और मुझे इस कंटेनर पर चलने वाले अपने सर्वर को लोकलहोस्ट के रूप में एक्सेस करने की अनुमति देता है : 7001 / कंसोल हालांकि, सर्वर की डीबी एक्सेस की जरूरत है डीबी चलाने वाले दूसरे कंटेनर तक पहुंचने के लिए सटीक आईपी। अगर मैं docker run --name ora-tools-wls -it -p 7001: 7001 --network = "host" orawls के साथ जाता हूं, तो सर्वर लोकलहोस्ट के साथ db को आईपी के रूप में एक्सेस करने में सक्षम है जैसा कि आपने उल्लेख किया है, लेकिन होस्ट सर्वर ब्राउज़र में एक्सेस सर्वर विफल रहता है।
विक

3
आपको परिभाषित करने की आवश्यकता नहीं है -p 7001:7001, क्योंकि सभी कंटेनर होस्ट के नेटवर्क स्टैक का उपयोग कर रहे हैं।
xitter

@ विक, मुझे एक ही परेशानी थी और पाया कि यह मैक पर समर्थित नहीं है। हो सकता है कि आप भी यही कर रहे हों। > होस्ट नेटवर्किंग ड्राइवर केवल लिनक्स होस्ट पर काम करता है, और मैक के लिए डॉकर डेस्कटॉप, विंडोज के लिए डॉकर डेस्कटॉप या विंडोज सर्वर के लिए डॉकर ईई पर समर्थित नहीं है। docs.docker.com/network/host
ब्रेंट फिशर

9

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

version: '2.1'
services:
  mongo:
    image: mongo:3.2.11
  redis:
    image: redis:3.2.10
  api:
    image: some-image
    depends_on:
      - mongo
      - solr
    links:
      - "mongo:mongo.openconceptlab.org"
      - "solr:solr.openconceptlab.org"
      - "some-service:some-alias"

और फिर एक होस्ट नाम के रूप में निर्दिष्ट उपनाम का उपयोग करके सेवा का उपयोग करें, उदाहरण के mongo.openconceptlab.orgलिए mongoइस मामले में।

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