डॉक कंटेनर से होस्ट पर शेल स्क्रिप्ट कैसे चलाएं?


94

डॉकटर कंटेनर से होस्ट को कैसे नियंत्रित करें?

उदाहरण के लिए, होस्ट स्क्रिप्ट को होस्ट करने के लिए प्रतिलिपि कैसे निष्पादित करें?


8
क्या ऐसा नहीं होगा कि मेजबान को अलग करने वाले के विपरीत हो?
मार्कस मुलर

31
हाँ। लेकिन यह कभी-कभी जरूरी होता है।
एलेक्स उशाकोव


"कंट्रोल होस्ट" के बारे में निश्चित नहीं है, लेकिन मैं हाल ही में डेटा वैज्ञानिकों द्वारा एक बात कर रहा था जो भारी कार्यभार को संसाधित करने के लिए लिपियों का उपयोग कर रहे हैं (एडब्ल्यूएस जीपीयू का उपयोग करके) और मेजबान को परिणाम का उत्पादन करते हैं। एक बहुत ही दिलचस्प उपयोग मामला। अनिवार्य रूप से स्क्रिप्ट एक विश्वसनीय निष्पादन वातावरण के साथ काम करने के लिए धन्यवाद
KCD

@ केसीडी और वे सिस्टम-स्तरीय कंटेनरों (एलएक्ससी) का उपयोग करने के बजाय डॉकटर के माध्यम से ऐप-कंटेनरीकरण को क्यों पसंद करते हैं?
एलेक्स उशाकोव

जवाबों:


28

यह वास्तव में निर्भर करता है कि आपको उस बैश स्क्रिप्ट की क्या आवश्यकता है!

उदाहरण के लिए, यदि बैश स्क्रिप्ट बस कुछ आउटपुट देती है, तो आप बस कर सकते हैं

docker run --rm -v $(pwd)/mybashscript.sh:/mybashscript.sh ubuntu bash /mybashscript.sh

एक और संभावना यह है कि आप चाहते हैं कि बैश स्क्रिप्ट कुछ सॉफ़्टवेयर स्थापित करे- स्क्रिप्ट को डॉकटर-कंपोज़ स्थापित करने के लिए कहें। आप कुछ ऐसा कर सकते हैं

docker run --rm -v /usr/bin:/usr/bin --privileged -v $(pwd)/mybashscript.sh:/mybashscript.sh ubuntu bash /mybashscript.sh

लेकिन इस बिंदु पर आप वास्तव में अंतरंग रूप से यह जानने में जुटे हैं कि कंटेनर के अंदर से आपके मेजबान को इसकी विशिष्ट अनुमति के लिए स्क्रिप्ट क्या कर रही है।


1
मेरे पास कंटेनर बनाने का विचार था जो मेजबान से जुड़ता है और नए कंटेनर बनाता है।
एलेक्स उशकोव

1
डॉकर आपके रिश्तेदार माउंट को पसंद नहीं करता है। यह काम करना चाहिएdocker run --rm -v $(pwd)/mybashscript.sh:/work/mybashscript.sh ubuntu /work/mybashscript.sh
KCD

5
पहली पंक्ति एक नया ubuntu कंटेनर शुरू करती है, और उस स्क्रिप्ट को मापती है जहां इसे पढ़ा जा सकता है। यह उदाहरण के लिए, मेजबान फाइल सिस्टम में कंटेनर का उपयोग करने की अनुमति नहीं देता है। दूसरी पंक्ति /usr/binकंटेनर में मेजबान की उजागर करती है । न तो मामले में कंटेनर में मेजबान सिस्टम की पूरी पहुंच होती है। शायद मैं गलत हूं, लेकिन यह एक बुरे सवाल के बुरे जवाब की तरह लगता है।
पॉल

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

1
इस की कोशिश की, स्क्रिप्ट को कंटेनर में निष्पादित किया जाता है, मेजबान पर नहीं
All2Pie

60

मैं जिस समाधान का उपयोग करता हूं, वह मेजबान से कनेक्ट करने SSHऔर कमांड को इस तरह निष्पादित करने के लिए है:

ssh -l ${USERNAME} ${HOSTNAME} "${SCRIPT}"

अपडेट करें

जैसा कि यह जवाब वोटों को प्राप्त करता रहता है, मैं याद दिलाना चाहता हूं (और अत्यधिक अनुशंसा करता हूं), कि स्क्रिप्ट को लागू करने के लिए जिस खाते का उपयोग किया जा रहा है, वह एक खाता होना चाहिए जिसमें कोई अनुमति नहीं है, लेकिन केवल उस स्क्रिप्ट को निष्पादित करना sudo(जो कि हो सकता है) sudoersफ़ाइल से किया गया )।


एक अन्य वर्कअराउंड के रूप में, कंटेनर कमांड का एक सेट आउटपुट कर सकता है और कंटेनर बाहर निकलने के बाद मेजबान उन्हें चला सकता है: eval $ (docker run --rm -it container_name_to_output script)
parity3

मुझे डॉकटर कंटेनर के अंदर से होस्ट पर कमांड लाइन चलाने की आवश्यकता है, लेकिन जब मैं कंटेनर में जाता हूं, sshतो नहीं मिलता है। आपके पास कोई और सुझाव है?
रॉन रोसेनफेल्ड

@ रॉनसेनफेल्ड, आप किस डॉकर छवि का उपयोग कर रहे हैं? डेबियन / ubuntu के मामले में, इसे चलाएं apt update && apt install openssh-client:।
मोहम्मद नौरेलिन

यह जो कुछ भी मेरे Synology NAS पर स्थापित हो जाएगा। मेरे लिए कहना मुश्कित है?
रॉन रोसेनफ़ेल्ड

@RonRosenfeld, माफ करना मुझे समझ में नहीं आ रहा है कि आपका क्या मतलब है
मोहम्मद नौरेलिन

52

एक नामित पाइप का इस्तेमाल किया। होस्ट ओएस पर, लूप पर एक स्क्रिप्ट बनाएं और कमांड पढ़ें, और फिर आप उस पर eval कहते हैं।

क्या डॉकटर कंटेनर को उस नामित पाइप से पढ़ा जाता है।

पाइप तक पहुंचने में सक्षम होने के लिए, आपको इसे वॉल्यूम के माध्यम से माउंट करने की आवश्यकता है।

यह एसएसएच तंत्र (या समान सॉकेट आधारित विधि) के समान है, लेकिन आपको मेजबान डिवाइस के लिए ठीक से प्रतिबंधित करता है, जो संभवतः बेहतर है। साथ ही आपको प्रमाणीकरण जानकारी के आसपास से गुजरना नहीं पड़ता है।

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

कुछ अन्य जवाब। जैसे कि स्क्रिप्ट चलाना। कोई वॉल्यूम सामान्य रूप से काम नहीं करेगा क्योंकि उनके पास पूर्ण सिस्टम संसाधनों तक पहुंच नहीं होगी, लेकिन यह आपके उपयोग के आधार पर अधिक उपयुक्त हो सकता है।


14
ध्यान दें: यह सही / सर्वोत्तम उत्तर है, और इसे थोड़ी अधिक प्रशंसा की आवश्यकता है। हर दूसरा जवाब "आप क्या करने की कोशिश कर रहे हैं" और सामान के लिए अपवाद बनाने के लिए कह रहा है। मेरे पास एक बहुत ही विशिष्ट उपयोग-मामला है जिसके लिए मुझे ऐसा करने में सक्षम होना चाहिए, और यह एकमात्र अच्छा उत्तर imho है। ऊपर SSH को सुरक्षा / फ़ायरवॉल मानकों को कम करने की आवश्यकता होती है, और डॉक रन सामान केवल फ्लैट आउट गलत है। इसके लिए धन्यवाद। मुझे लगता है कि यह अधिक अपवित्र नहीं मिलता है क्योंकि यह एक साधारण कॉपी / पेस्ट उत्तर नहीं है, लेकिन यह उत्तर है। +100 अंक मुझ से अगर मैं कर सकता था
फ़ारले

3
कुछ और जानकारी की तलाश करने वालों के लिए, आप होस्ट मशीन पर चलने वाली निम्न स्क्रिप्ट का उपयोग कर सकते हैं: unix.stackexchange.com/a/369465 बेशक, आपको इसे 'nohup' से चलाना होगा और किसी प्रकार का पर्यवेक्षक आवरण बनाना होगा इसे जीवित बनाए रखने के लिए (शायद क्रोन जॉब का उपयोग करें: P)
सूक्रोट्रोनिक

7
यह एक अच्छा जवाब हो सकता है। हालाँकि, अधिक बेहतर होगा यदि आप अधिक विवरण और कुछ अधिक कमांड लाइन स्पष्टीकरण दें। क्या विस्तृत करना संभव है?
मोहम्मद नौरेलिन

5
Upvoted, यह काम करता है! 'Mkfifo host_executor_queue' का उपयोग करके एक नामांकित पाइप बनाएं जहां वॉल्यूम आरोहित है। फिर एक उपभोक्ता को जोड़ने के लिए, जो कमांड को होस्ट के खोल के रूप में कतार में लगाता है, का उपयोग करता है 'tail -f host_executor_queue | श & '। अंत में & इसे पृष्ठभूमि में चलाया जाता है। अंत में आदेशों को कतार में धकेलने के लिए 'इको टच फू> host_executor_queue' का उपयोग करें - यह परीक्षण होम डायरेक्टरी में एक अस्थायी फ़ाइल फू बनाता है। यदि आप चाहते हैं कि उपभोक्ता सिस्टम स्टार्टअप पर शुरू करे, तो '@reboot tail -f host_executor_queue' लगाएं sh और 'crontab में। Host_executor_queue के सापेक्ष पथ जोड़ें।
आसमान

1
क्या कोई उदाहरण कोड के साथ उत्तर को संपादित कर सकता है?
लुकास कुम्हार

6

यदि आप सुरक्षा के बारे में चिंतित नहीं हैं और आप ओपी जैसे किसी अन्य डॉकटर कंटेनर के भीतर से होस्ट पर एक डॉक कंटेनर शुरू करना चाहते हैं, तो आप डॉक कंटेनर में होस्ट पर चलने वाले डॉक सर्वर को साझा कर सकते हैं इसे सॉकेट सुन सकते हैं।

कृपया देखें https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface देखें और देखें कि क्या आपकी व्यक्तिगत जोखिम सहिष्णुता इस विशेष एप्लिकेशन के लिए अनुमति देती है।

आप अपने आरंभ कमांड में निम्न वॉल्यूम आर्गन जोड़कर ऐसा कर सकते हैं

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

या अपने docker में इस तरह फ़ाइल लिखें /var/run/docker.sock साझा करके:

version: '3'

services:
   ci:
      command: ...
      image: ...
      volumes
         - /var/run/docker.sock:/var/run/docker.sock

जब आप docker start कमांड को अपने docker कंटेनर के भीतर चलाते हैं, तो आपके host पर चलने वाले docker सर्वर रिक्वेस्ट को देखेंगे और sibre कंटेनर को प्रोविजन करेंगे।

साभार : http://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/


1
विचार करें कि डॉकटर को कंटेनर में स्थापित किया जाना चाहिए, अन्यथा आपको डॉक बाइनरी (जैसे /usr/bin/docker:/usr/bin/docker) के लिए एक वॉल्यूम माउंट करने की आवश्यकता होगी ।
गेरी

1
कृपया अपने कंटेनर में डॉक
DatGuyKaj

@DatGuyKaj धन्यवाद, मैंने आपके संसाधन द्वारा उल्लिखित मुद्दों को प्रतिबिंबित करने के लिए अपना उत्तर संपादित किया है।
मैट बुक्की

यह उस प्रश्न का उत्तर नहीं देता है, जो होस्ट पर स्क्रिप्ट चलाने के बारे में है, कंटेनर में नहीं
ब्रैंडन

5

यह उत्तर ब्रैडफोर्ड मेडीयरोस के समाधान का एक अधिक विस्तृत संस्करण है , जो मेरे लिए सबसे अच्छा जवाब है, इसलिए इसका श्रेय उन्हें जाता है।

अपने जवाब में, वह WHAT को करने के लिए ( नामित पाइप) बताते हैं ) लेकिन इसे करने के लिए बिल्कुल कैसे नहीं।

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

भाग 1 - डॉकटर के बिना नामित पाइप अवधारणा का परीक्षण

मुख्य होस्ट पर, उस फ़ोल्डर को चुना जहाँ आप अपनी नामित पाइप फ़ाइल, उदाहरण के लिए /path/to/pipe/और पाइप का नाम, उदाहरण के लिए mypipe, और उसके बाद रखना चाहते हैं:

mkfifo /path/to/pipe/mypipe

पाइप बनाया जाता है। प्रकार

ls -l /path/to/pipe/mypipe 

और एक्सेस अधिकारों की जांच "पी" से शुरू करें, जैसे कि

prw-r--r-- 1 root root 0 mypipe

अब चलाएं:

tail -f /path/to/pipe/mypipe

टर्मिनल अब इस पाइप में डेटा भेजे जाने की प्रतीक्षा कर रहा है

अब एक और टर्मिनल विंडो खोलें।

और फिर चलाएं:

echo "hello world" > /path/to/pipe/mypipe

पहले टर्मिनल (एक के साथ tail -f) की जांच करें, इसे "हैलो वर्ल्ड" प्रदर्शित करना चाहिए

भाग 2 - पाइप के माध्यम से कमांड चलाएं

होस्ट कंटेनर पर, रनिंग के बजाय tail -fजो इनपुट के रूप में भेजे गए आउटपुट को आउटपुट करता है, इस कमांड को चलाएं जो इसे कमांड के रूप में निष्पादित करेगा:

eval "$(cat /path/to/pipe/mypipe)"

फिर, दूसरे टर्मिनल से, चलाने का प्रयास करें:

echo "ls -l" > /path/to/pipe/mypipe

पहले टर्मिनल पर वापस जाएं और आपको ls -lकमांड का परिणाम देखना चाहिए ।

भाग 3 - इसे हमेशा के लिए सुनें

आपने देखा होगा कि पिछले भाग में, ls -lआउटपुट प्रदर्शित होने के ठीक बाद , यह कमांड्स के लिए सुनना बंद कर देता है।

इसके बजाय eval "$(cat /path/to/pipe/mypipe)", भागो:

while true; do eval "$(cat /path/to/pipe/mypipe)"; done

(आप कह सकते हैं कि)

अब आप एक के बाद एक असीमित संख्या में आदेश भेज सकते हैं, वे सभी निष्पादित होंगे, न कि केवल पहले एक।

भाग 4 - रिबूट होने पर भी इसे काम करें

एकमात्र चेतावनी है यदि मेजबान को रिबूट करना है, तो "जबकि" लूप काम करना बंद कर देगा।

रिबूट को संभालने के लिए, यहाँ मैंने क्या किया है:

हेडर के साथ while true; do eval "$(cat /path/to/pipe/mypipe)"; doneएक फ़ाइल में रखोexecpipe.sh#!/bin/bash

chmod +xइसे मत भूलना

इसे दौड़ने के साथ क्रस्टैब में जोड़ें

crontab -e

और फिर जोड़ना

@reboot /path/to/execpipe.sh

इस बिंदु पर, इसका परीक्षण करें: अपने सर्वर को रिबूट करें, और जब यह वापस आ जाता है, तो पाइप में कुछ कमांड को गूंजें और जांच करें कि क्या वे निष्पादित हैं। बेशक, आप कमांड का आउटपुट देखने में सक्षम नहीं हैं, इसलिए ls -lमदद नहीं करेगा, लेकिन touch somefileमदद करेगा।

एक अन्य विकल्प यह है कि आउटपुट को किसी फ़ाइल में डालने के लिए स्क्रिप्ट को संशोधित किया जाए, जैसे:

while true; do eval "$(cat /path/to/pipe/mypipe)" &> /somepath/output.txt; done

अब आप रन कर सकते हैं ls -lऔर आउटपुट ( &>बैश में स्टैडआउट और स्टेडर दोनों ) output.txt में होना चाहिए।

भाग 5 - इसे डॉकटर के साथ काम करें

यदि आप docker कंपोज़ और dockerfile दोनों का उपयोग कर रहे हैं जैसे मैं करता हूँ, यहाँ मैंने किया है:

मान लें कि आप /hostpipeअपने कंटेनर में mypipe के मूल फ़ोल्डर को माउंट करना चाहते हैं

इसे जोड़ो:

VOLUME /hostpipe

माउंट बिंदु बनाने के लिए अपने डॉकफाइल में

फिर इसे जोड़ें:

volumes:
   - /path/to/pipe:/hostpipe

अपने docker में / hostpipe के रूप में / path / to / पाइप को माउंट करने के लिए फ़ाइल लिखें

अपने डॉकटर कंटेनरों को पुनः आरंभ करें।

भाग 6 - परीक्षण

अपने डॉकटर कंटेनर में जाएं:

docker exec -it <container> bash

माउंट फ़ोल्डर में जाएं और जांचें कि आप पाइप देख सकते हैं:

cd /hostpipe && ls -l

अब कंटेनर के भीतर से कमांड चलाने का प्रयास करें:

echo "touch this_file_was_created_on_main_host_from_a_container.txt" > /hostpipe/mypipe

और यह काम करना चाहिए!

चेतावनी: यदि आपके पास एक OSX (मैक ओएस) होस्ट और एक लिनक्स कंटेनर है, तो यह काम नहीं करेगा (स्पष्टीकरण यहाँ https://stackoverflow.com/a/43474708/10018801 और यहाँ जारी करें https://github.com/docker के लिए-मैक / / मुद्दों / 483 ) क्योंकि पाइप कार्यान्वयन समान नहीं है, इसलिए आप लिनक्स से पाइप में जो लिखते हैं उसे केवल लिनक्स द्वारा पढ़ा जा सकता है और मैक ओएस से पाइप में आप जो लिखते हैं वह केवल एक द्वारा पढ़ा जा सकता है मैक ओएस (यह वाक्य बहुत सटीक नहीं हो सकता है, लेकिन बस एक क्रॉस-प्लेटफ़ॉर्म समस्या मौजूद है)।

उदाहरण के लिए, जब मैं अपने मैक ओएस कंप्यूटर से डीईवी में अपना डॉकटर सेटअप चलाता हूं, तो ऊपर दिया गया नाम का पाइप काम नहीं करता है। लेकिन मंचन और उत्पादन में, मेरे पास लिनक्स होस्ट और लिनक्स कंटेनर हैं, और यह पूरी तरह से काम करता है।

भाग 7 - Node.JS कंटेनर से उदाहरण

यहां बताया गया है कि मैं अपने नोड js कंटेनर से मुख्य होस्ट को एक कमांड भेजता हूं और आउटपुट प्राप्त करता हूं:

const pipePath = "/hostpipe/mypipe"
const outputPath = "/hostpipe/output.txt"
const commandToRun = "pwd && ls-l"

console.log("delete previous output")
if (fs.existsSync(outputPath)) fs.unlinkSync(outputPath)

console.log("writing to pipe...")
const wstream = fs.createWriteStream(pipePath)
wstream.write(commandToRun)
wstream.close()

console.log("waiting for output.txt...") //there are better ways to do that than setInterval
let timeout = 10000 //stop waiting after 10 seconds (something might be wrong)
const timeoutStart = Date.now()
const myLoop = setInterval(function () {
    if (Date.now() - timeoutStart > timeout) {
        clearInterval(myLoop);
        console.log("timed out")
    } else {
        //if output.txt exists, read it
        if (fs.existsSync(outputPath)) {
            clearInterval(myLoop);
            const data = fs.readFileSync(outputPath).toString()
            if (fs.existsSync(outputPath)) fs.unlinkSync(outputPath) //delete the output file
            console.log(data) //log the output of the command
        }
    }
}, 300);

यह अच्छी तरह से काम करता है। सुरक्षा के बारे में क्या? मैं एक चालू कंटेनर के भीतर से डॉक कंटेनर को शुरू / बंद करने के लिए इसका उपयोग करना चाहता हूं? क्या मैं सिर्फ docker कमांड चलाने के अलावा किसी विशेष सुविधा के बिना एक dockeruser बनाता हूं?
क्रिस्टोफ वैन वोवेसेल

4

पोर्ट पर एक साधारण सर्वर पायथन सर्वर को सुनें (8080 कहते हैं), पोर्ट -p 8080: 8080 को कंटेनर से बांधें, लोकलहोस्ट के लिए एक HTTP अनुरोध करें: 8080 पॉपन के लिए शेल स्क्रिप्ट चलाने वाले अजगर सर्वर से पूछें, कर्ल चलाएं या एक HTTP अनुरोध कर्ल -d '{"foo": "बार"} लोकलहोस्ट: 8080 बनाने के लिए कोड लिखना

#!/usr/bin/python
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
import subprocess
import json

PORT_NUMBER = 8080

# This class will handles any incoming request from
# the browser 
class myHandler(BaseHTTPRequestHandler):
        def do_POST(self):
                content_len = int(self.headers.getheader('content-length'))
                post_body = self.rfile.read(content_len)
                self.send_response(200)
                self.end_headers()
                data = json.loads(post_body)

                # Use the post data
                cmd = "your shell cmd"
                p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
                p_status = p.wait()
                (output, err) = p.communicate()
                print "Command output : ", output
                print "Command exit status/return code : ", p_status

                self.wfile.write(cmd + "\n")
                return
try:
        # Create a web server and define the handler to manage the
        # incoming request
        server = HTTPServer(('', PORT_NUMBER), myHandler)
        print 'Started httpserver on port ' , PORT_NUMBER

        # Wait forever for incoming http requests
        server.serve_forever()

except KeyboardInterrupt:
        print '^C received, shutting down the web server'
        server.socket.close()

IMO यह सबसे अच्छा जवाब है। होस्ट मशीन पर मनमाना कमांड चलाना किसी प्रकार के एपीआई (जैसे कि REST) ​​के माध्यम से किया जाना चाहिए। यह एकमात्र तरीका है कि सुरक्षा को लागू किया जा सकता है और चल रही प्रक्रियाओं को ठीक से नियंत्रित किया जा सकता है (उदाहरण के लिए हत्या, स्टड, स्टडआउट, निकास-कोड, और इसी तरह से संभालना)। यदि यह एपीआई डॉकर के अंदर चल सकता है, तो बेशक यह बहुत अच्छा होगा, लेकिन व्यक्तिगत रूप से मैं इसे सीधे मेजबान पर चलाने का मन नहीं करता।
बार्नी 7६५

2

मेरे आलस्य ने मुझे सबसे आसान समाधान खोजने के लिए प्रेरित किया जो यहां एक उत्तर के रूप में प्रकाशित नहीं हुआ था।

यह पर आधारित है महान लेख द्वारा ल्यूक juggery

आपको अपने डॉक कंटेनर के भीतर से अपने लिनक्स होस्ट को एक पूर्ण शेल प्राप्त करने के लिए करने की आवश्यकता है:

docker run --privileged --pid=host -it alpine:3.8 \
nsenter -t 1 -m -u -n -i sh

स्पष्टीकरण:

- विशेषाधिकारित: कंटेनर को अतिरिक्त अनुमति देता है, यह कंटेनर को होस्ट (/ देव) के उपकरणों तक पहुंच प्राप्त करने की अनुमति देता है

--pid = host: कंटेनरों को डॉकर होस्ट (वीएम जिसमें डॉकर डेमन चल रहा है) की प्रक्रियाओं के पेड़ का उपयोग करने की अनुमति देता है। एनसेंटर उपयोगिता: मौजूदा नेमस्पेस (बिल्डिंग ब्लॉक्स जो कंटेनरों को अलगाव प्रदान करता है) में एक प्रक्रिया को चलाने की अनुमति देता है

nsenter (-t 1 -m -n -n -i sh) पीआईडी ​​1 के साथ प्रक्रिया के रूप में प्रक्रिया को उसी अलगाव संदर्भ में चलाने की अनुमति देता है। पूरे कमांड तब वीएम में एक इंटरैक्टिव श खोल प्रदान करेगा।

इस सेटअप के प्रमुख सुरक्षा निहितार्थ हैं और इसका उपयोग सावधानी (यदि कोई हो) के साथ किया जाना चाहिए।


1
docker run --detach-keys="ctrl-p" -it -v /:/mnt/rootdir --name testing busybox
# chroot /mnt/rootdir
# 

3
हालांकि यह उत्तर ओपी के प्रश्न को हल कर सकता है, यह सुझाव दिया जाता है कि आप यह समझाते हैं कि यह कैसे काम करता है और क्यों यह समस्या को हल करता है। इससे नए डेवलपर्स को यह समझने में मदद मिलती है कि क्या चल रहा है और इसे कैसे ठीक किया जाए और इसी तरह के मुद्दों को स्वयं। योगदान के लिए धन्यवाद!
कालेब क्लेवेटर

1

मेरे पास एक सरल तरीका है।

चरण 1: Mount /var/run/docker.sock:/var/run/docker.sock (ताकि आप अपने कंटेनर के अंदर docker कमांड निष्पादित कर सकें)

चरण 2: अपने कंटेनर के अंदर इसे नीचे निष्पादित करें। यहाँ मुख्य भाग (- नेटवर्क होस्ट है क्योंकि यह होस्ट संदर्भ से निष्पादित होगा)

docker run -i --rm --network host -v /opt/test.sh:/test.sh अल्पाइन: 3.7 sh /test.sh

test.sh में कुछ कमांड्स होना चाहिए (ifconfig, netstat आदि ...) जो भी आपको चाहिए। अब आप मेजबान संदर्भ आउटपुट प्राप्त करने में सक्षम होंगे।


2
होस्ट नेटवर्क का उपयोग करते हुए नेटवर्किंग पर डॉकटर के आधिकारिक दस्तावेज के अनुसार, "हालांकि, अन्य सभी तरीकों से, जैसे भंडारण, प्रक्रिया नाम स्थान और उपयोगकर्ता नाम स्थान, प्रक्रिया होस्ट से पृथक है।" बाहर की जाँच करें - docs.docker.com/network/network-tutorial-host
पीटर Mutisya

0

जैसा कि मार्कस याद दिलाते हैं, डॉक मूल रूप से अलगाव की प्रक्रिया है। Docker 1.8 से शुरू होकर, आप होस्ट और कंटेनर के बीच फ़ाइलों को कॉपी कर सकते हैं, डॉक्स को देख सकते हैंdocker cp

https://docs.docker.com/reference/commandline/cp/

एक बार किसी फ़ाइल की प्रतिलिपि बना लेने पर, आप इसे स्थानीय रूप से चला सकते हैं


1
मुझे यह पता है। इस स्क्रिप्ट को दूसरे शब्दों में, डॉकटर कंटेनर के अंदर से कैसे चलाया जाए?
एलेक्स उशाकोव


2
@AlexUshakov: कोई रास्ता नहीं। ऐसा करने से डॉकटर के बहुत सारे फायदे होंगे। यह मत करो। यह कोशिश मत करो। आप क्या करने की जरूरत पर पुनर्विचार करें।
मार्कस मुलर

व्लाद के चाल मंचों को
t/

1
आप हमेशा होस्ट पर, अपने कंटेनर में कुछ वैरिएबल का मूल्य प्राप्त कर सकते हैं, कुछ ऐसा जैसे myvalue=$(docker run -it ubuntu echo $PATH)और इसे स्क्रिप्ट शेल में नियमित रूप से परीक्षण करना (बेशक, आप $ PATH के अलावा कुछ और उपयोग करेंगे, बस एक उदाहरण है), जब यह कुछ विशिष्ट मूल्य है, आप अपनी स्क्रिप्ट
user2915097

0

आप पाइप अवधारणा का उपयोग कर सकते हैं, लेकिन होस्ट पर एक फ़ाइल का उपयोग करें और डॉक कंटेनर से होस्ट मशीन पर स्क्रिप्ट निष्पादित करने के लिए लक्ष्य को पूरा करने के लिए fswatch । जैसे कि (अपने जोखिम पर उपयोग करें):

#! /bin/bash

touch .command_pipe
chmod +x .command_pipe

# Use fswatch to execute a command on the host machine and log result
fswatch -o --event Updated .command_pipe | \
            xargs -n1 -I "{}"  .command_pipe >> .command_pipe_log  &

 docker run -it --rm  \
   --name alpine  \
   -w /home/test \
   -v $PWD/.command_pipe:/dev/command_pipe \
   alpine:3.7 sh

rm -rf .command_pipe
kill %1

इस उदाहरण में, कंटेनर के अंदर / dev / कमांड_पाइप करने के लिए कमांड भेजें, जैसे:

/home/test # echo 'docker network create test2.network.com' > /dev/command_pipe

होस्ट पर, आप जाँच सकते हैं कि क्या नेटवर्क बनाया गया था:

$ docker network ls | grep test2
8e029ec83afe        test2.network.com                            bridge              local

-7

User2915097 की प्रतिक्रिया पर विस्तार करने के लिए :

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

हाँ। लेकिन यह कभी-कभी जरूरी होता है।

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


मेरे पास उपयोग का मामला है: मैंने डॉकटराइज़्ड सर्विस A( sith on github) की है। में Aरेपो मैं उचित हुक जो 'Git पुल' आदेश के बाद नई डोकर छवि बनाने और उन्हें चलाने (और निश्चित रूप से पुराने कंटेनर निकालने के लिए) पैदा करते हैं। अगला: github में वेब-हुक हैं जो मास्टर पर पुश करने के बाद मनमाने समापन बिंदु लिंक के लिए POST अनुरोध बनाने की अनुमति देते हैं। इसलिए मैं डॉक्यूमेंटेड सर्विस B नहीं बनाना चाहता, जो कि एंडपॉइंट होगा और जो केवल HOST मशीन में रेपो ए में 'git पुल' चलाएगा (महत्वपूर्ण: कमांड 'git पुल' को HOST वातावरण में निष्पादित किया जाना चाहिए - B में नहीं क्योंकि B नए कंटेनर A को B के अंदर नहीं चला सकते ...)
Kamil Kiełczewski

1
समस्या: मैं HOST में linux, git और docker के अलावा कुछ भी नहीं रखना चाहता। और मैं dockerizet सेवा A और सेवा B (जो वास्तव में git- पुश हैंडलर है जो रेपो A पर git पुल निष्पादित करता है, जब कोई मास्टर पर git धक्का देता है)। तो git ऑटो-तैनाती समस्याग्रस्त उपयोग-केस है
कामिल Kiełczewski

@ KamilKiełczewski मैं बिल्कुल वैसा ही करने की कोशिश कर रहा हूं, क्या आपने कोई समाधान ढूंढ लिया है?
user871784

1
यह कहते हुए, "नहीं, यह मामला नहीं है" संकीर्ण मानसिकता है और आप दुनिया में हर उपयोग-मामले को जानते हैं। हमारे उपयोग का मामला परीक्षण चल रहा है। उन्हें पर्यावरण को सही ढंग से परखने के लिए कंटेनरों में दौड़ने की आवश्यकता होती है, लेकिन परीक्षणों की प्रकृति को देखते हुए, उन्हें मेजबान पर स्क्रिप्ट निष्पादित करने की भी आवश्यकता होती है।
सेनिका गोंजालेज

1
सिर्फ उन लोगों के लिए जो सोचता है कि मैं एक -7 उत्तर क्यों छोड़ता हूं: क) यह गिरने योग्य होना ठीक है। मैं गलत था। यह ठीक है कि यह यहाँ प्रलेखित है। ख) टिप्पणी वास्तव में मूल्य का योगदान करती है; उत्तर को हटाने से उन्हें हटा दिया जाएगा। ग) यह अभी भी देखने का एक बिंदु है जो विचार करने के लिए बुद्धिमान हो सकता है (यदि आपके पास नहीं है तो अपने अलगाव को तोड़ें। कभी-कभी आपके पास, हालांकि)।
मार्कस मुलर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.