डॉकटर कंटेनर तुरंत क्यों निकलता है


239

मैं बैकग्राउंड में एक कंटेनर चलाते हैं

 docker run -d --name hadoop h_Service

यह जल्दी से बाहर निकलता है। लेकिन अगर मैं अग्रभूमि में दौड़ता हूं, तो यह ठीक काम करता है। मैंने लॉग का उपयोग करके जाँच की

docker logs hadoop

कोई त्रुटि नहीं थी। कोई विचार?

DOCKERFILE

 FROM java_ubuntu_new
 RUN wget http://archive.cloudera.com/cdh4/one-click-install/precise/amd64/cdh4-repository_1.0_all.deb
 RUN dpkg -i cdh4-repository_1.0_all.deb
 RUN curl -s http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh/archive.key | apt-key add -
 RUN  apt-get update
 RUN apt-get install -y hadoop-0.20-conf-pseudo
 RUN dpkg -L hadoop-0.20-conf-pseudo
 USER hdfs
 RUN hdfs namenode -format
 USER root
 RUN apt-get install -y sudo
 ADD . /usr/local/
 RUN chmod 777 /usr/local/start-all.sh
 CMD ["/usr/local/start-all.sh"]

start-all.sh

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start
 /etc/init.d/hadoop-hdfs-datanode start
 /etc/init.d/hadoop-hdfs-secondarynamenode start
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start
 /bin/bash

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

जो भी आप पूरा करने की उम्मीद कर रहे हैं, chmod 777वह असुरक्षित और गलत है। आपको सनी अनुमतियों (शायद इस मामले में 755) पर वापस जाना चाहिए।
5

जवाबों:


125

एक डॉकटर कंटेनर बाहर निकलता है जब इसकी मुख्य प्रक्रिया समाप्त होती है।

इस मामले में आपकी start-all.shस्क्रिप्ट समाप्त होने पर यह बाहर निकल जाएगा । मैं आपको इस मामले में कैसे करना है, यह बताने के लिए हडूप के बारे में पर्याप्त नहीं जानता, लेकिन आपको अग्रभूमि में चल रहे कुछ को छोड़ने की जरूरत है या प्रक्रियाओं को चलाने के लिए रन मैनेजर या पर्यवेक्षक जैसे प्रक्रिया प्रबंधक का उपयोग करना चाहिए।

मुझे लगता है कि यदि आप निर्दिष्ट नहीं करते हैं तो आपको इसके बारे में गलत होना चाहिए -d; इसका ठीक वैसा ही प्रभाव होना चाहिए। मुझे संदेह है कि आपने इसे कुछ अलग कमांड के साथ लॉन्च किया है या -itजिसके उपयोग से चीजें बदल जाएंगी।

एक सरल समाधान कुछ जोड़ने की तरह हो सकता है:

while true; do sleep 1000; done

स्क्रिप्ट के अंत तक। मुझे यह पसंद नहीं है, क्योंकि स्क्रिप्ट को वास्तव में उन प्रक्रियाओं की निगरानी करनी चाहिए जो इसे बंद कर दिया था।

(मुझे कहना चाहिए कि मैंने https://github.com/fterenceiq/hadoop-docker/blob/master/bootstrap.sh से वह कोड चुरा लिया है )


217

इसने मेरे लिए चाल चली:

docker run -dit ubuntu

इसके बाद, मैंने उपयोग की जाने वाली प्रक्रियाओं के लिए जाँच की:

docker ps -a

कंटेनर को फिर से संलग्न करने के लिए

docker attach CONTAINER_NAME

टिप: कंटेनर प्रकार को रोकने के बिना बाहर निकलने के लिए: ^P^Q


15
@ टॉमी , docs.docker.com/engine/reference/commandline/run -d, --detach डिटैच्ड मोड: बैकग्राउंड में कमांड रन करें, -i, - -एक्टिव-एक्टिव STDIN को खुला रखें भले ही वह संलग्न न हो, -t, - शेट्टी को एक छद्म-टीटीवाई आवंटित -ditकरना केवल शॉर्टहैंड है

3
@ am17torres सही, माफ करना मुझे अपने भ्रामक सवाल स्पष्ट; डी अलग है और मैं इंटरैक्टिव है, इसलिए डी और मैं का संयोजन मेरे लिए भ्रमित कर रहा है। मुझे लगा कि d इसे पृष्ठभूमि (गैर-संवादात्मक) प्रक्रिया के रूप में लॉन्च करना था।
टॉमी

2
@ टॉमी जब ये विकल्प संयुक्त होते हैं, तो कंटेनर पृष्ठभूमि में इंटरैक्टिव मोड में प्रवेश करेगा ।
यॉन

2
@ टॉमी, @ am17torres -diन्यूनतम आवश्यक है, -tविकल्प निरर्थक है जब -dमैं सही ढंग से उपयोग के साथ प्रयोग किया जाता है
Renaud

2
यदि आप बिना -tसक्षम किए ही रिजेक्ट कर देते हैं, तो आप अपने प्रॉम्प्ट को नहीं देख पाएंगे ... लेकिन जब से मैं आम तौर पर execहर बार एक नया बैश देखता हूं, जब तक मैं नोटिस नहीं करता। मुझे समस्या है एक मैक से कोचिंग कर रहा था, लेकिन शायद मैं यह गलत कर रहा हूँ ..
रेनॉड

65

मैं कहना चाहूंगा कि मैं इसका विस्तार या साहस करना चाहता हूं, कैम्पस द्वारा बताए गए उत्तर को बेहतर बनाता हूं

जब तुम दौड़ते हो

docker run -dit ubuntu

आप मूल रूप से संवादात्मक मोड में पृष्ठभूमि में कंटेनर चला रहे हैं।

जब आप CTRL + D द्वारा कंटेनर को संलग्न करते हैं और बाहर निकलते हैं (इसे करने का सबसे आम तरीका), तो आप कंटेनर को रोक देते हैं क्योंकि आपने मुख्य प्रक्रिया को मार दिया है जिसे आपने उपरोक्त आदेश के साथ अपना कंटेनर शुरू किया था।

पहले से चल रहे कंटेनर का लाभ उठाते हुए, मैं बस बैश की एक और प्रक्रिया को कांटा और रन करके एक छद्म TTY प्राप्त करूंगा:

docker exec -it <container ID> /bin/bash

29

जब भी मैं चाहता हूं कि मेरे द्वारा जोड़े जाने वाले स्क्रिप्ट निष्पादन को पूरा करने के बाद एक कंटेनर ऊपर रहना चाहिए

&& tail -f /dev/null

कमांड के अंत में। तो यह होना चाहिए:

/usr/local/start-all.sh && tail -f /dev/null

19

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

यदि आप छवि को घूमने के लिए मजबूर करना चाहते हैं (कुछ डिबग करने या फ़ाइल सिस्टम की स्थिति की जांच करने के लिए) तो आप इसे शेल में बदलने के लिए प्रवेश बिंदु को ओवरराइड कर सकते हैं:

docker run -it --entrypoint=/bin/bash myimagename

18

एक अच्छा तरीका यह होगा कि आप अपनी प्रक्रियाओं और सेवाओं को पृष्ठभूमि में चलाना शुरू कर दें और wait [n ...]अपनी स्क्रिप्ट के अंत में कमांड का उपयोग करें । बैश में, प्रतीक्षा कमांड वर्तमान प्रक्रिया को निम्नलिखित के लिए मजबूर करती है:

प्रत्येक निर्दिष्ट प्रक्रिया की प्रतीक्षा करें और अपनी समाप्ति की स्थिति लौटाएं। यदि n नहीं दिया गया है, तो वर्तमान में सभी सक्रिय बच्चे प्रक्रियाओं के लिए इंतजार कर रहे हैं, और वापसी की स्थिति शून्य है।

मुझे यह विचार सेबास्टियन पुजदास की उनकी एल्क बिल्ड की स्क्रिप्ट से मिला ।

मूल प्रश्न से लेते हुए, आपका start-all.sh कुछ इस तरह दिखेगा ...

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start &
 /etc/init.d/hadoop-hdfs-datanode start &
 /etc/init.d/hadoop-hdfs-secondarynamenode start &
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start &
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start &
 wait

5

इसे डॉकरफाइल के अंत में जोड़ें:

CMD tail -f /dev/null

नमूना डॉकर फ़ाइल:

FROM ubuntu:16.04

# other commands

CMD tail -f /dev/null

संदर्भ


CMD tail -f /dev/nullइसके माध्यम से चलाता है sh -c "..."। क्या हम execइसके बजाय फॉर्म का उपयोग कर सकते हैं ? IeCMD ["tail", "-f", "/dev/null"]
मेगालियो

4

मेरा प्रचारक डॉकरीफाइल में एक शेल शुरू करता है जो तुरंत बाहर नहीं निकलेगा CMD [ "sh", "-c", "service ssh start; bash"], फिर चलाएगा docker run -dit image_name। इस तरह (ssh) सेवा और कंटेनर चल रहा है।


1

मैंने readअंत में शेल स्टेटमेंट जोड़ा । यह कंटेनर की मुख्य प्रक्रिया - स्टार्टअप शेल स्क्रिप्ट - रनिंग को बनाए रखता है।


1

जोड़ा जा रहा है

exec "$@"

मेरी शेल स्क्रिप्ट के अंत में मेरा फिक्स था!


इसका मतलब है कि यह आपके cmd को चलाएगा, अगर आपका cmd सिर्फ 'bash' है तो यह अभी भी काम नहीं करेगा
Shardj

1

यदि आप कंटेनरों से डॉकरफाइल की जांच करते हैं, उदाहरण के लिए fballiano / magento2-apache-php

आप देखेंगे कि उसकी फ़ाइल के अंत में वह निम्न कमांड जोड़ता है: जबकि सच है; सो जाओ 1; किया हुआ

अब, मैं जो सलाह देता हूं, वह यह है कि आप ऐसा करते हैं

docker container ls --all | grep 127

फिर, आप देखेंगे कि यदि आपकी docker छवि में कोई त्रुटि थी, यदि वह 0 से बाहर निकलती है, तो संभवतः उसे इनमें से एक आदेश की आवश्यकता है जो हमेशा के लिए सो जाएगा।


0

बहुत से संभावित तरीके हैं जो एक docker को तुरंत बाहर निकलने का कारण बनाते हैं। मेरे लिए, यह मेरे साथ समस्या थी Dockerfile। उस फाइल में एक बग था। मैं इसके ENTRYPOINT ["dotnet", "M4Movie_Api.dll]बजाय था ENTRYPOINT ["dotnet", "M4Movie_Api.dll"]। जैसा कि आप देख सकते हैं कि मैं अंत में एक उद्धरण (") से चूक गया था।

समस्या का विश्लेषण करने के लिए मैंने अपना कंटेनर शुरू किया और अपने कंटेनर को जल्दी से जोड़ा ताकि मैं देख सकूँ कि सही समस्या क्या थी।

C:\SVenu\M4Movie\Api\Api>docker start 4ea373efa21b


C:\SVenu\M4Movie\Api\Api>docker attach 4ea373efa21b

जहां 4ea373efa21b मेरा कंटेनर आईडी है। यह मुझे वास्तविक मुद्दे पर ले जाता है।

यहां छवि विवरण दर्ज करें

समस्या खोजने के बाद, मुझे अपने कंटेनर को फिर से बनाना, पुनर्स्थापित करना, प्रकाशित करना था।


0

डुप्लिकेट से आ रहा है, मुझे यहां कोई जवाब नहीं दिखता है जो आपके मुख्य कार्यभार को पृष्ठभूमि की नौकरी के रूप में चलाने के बहुत ही सामान्य एंटीपैटर को संबोधित करता है, और फिर सोचता है कि डॉकटर क्यों बाहर निकलता है।

सरल शब्दों में, यदि आपके पास है

my-main-thing &

फिर या तो &अग्रभूमि में काम चलाने के लिए, या जोड़ें

wait

स्क्रिप्ट के अंत में सभी पृष्ठभूमि नौकरियों के लिए प्रतीक्षा करें।

यह तब भी बाहर निकल जाएगा यदि मुख्य कार्यभार से बाहर निकलता है, तो शायद while trueइसे एक लूप में चलाएं ताकि इसे हमेशा के लिए फिर से शुरू करने के लिए मजबूर किया जा सके:

while true; do
    my-main-thing &
    other things which need to happen while the main workload runs in the background
    maybe if you have such things
    wait
done

(यह भी देखें कि कैसे लिखना है while true। यह मूर्खतापूर्ण चीजों को देखने के लिए आम है जैसे कि while [ true ]या while [ 1 ]जो संयोग से काम करने के लिए होता है, लेकिन इसका मतलब यह नहीं है कि लेखक ने शायद कल्पना की थी कि उनका मतलब क्या होना चाहिए।)


0

आपको पृष्ठभूमि में डेमन के रूप में चलने के लिए इसे -d ध्वज के साथ चलाने की आवश्यकता है।

docker रन -d -it ubuntu bash


-5

आप इस पुनरारंभ ध्वज का उपयोग करके कंटेनर चला सकते हैं।

docker run -d --name=<some-name> -p xxxx:xxxx ... <image-name> --restart=unless-stopped

-8

चूंकि छवि एक लिनक्स है, जांच करने के लिए एक बात यह सुनिश्चित करना है कि कंटेनर में उपयोग किए जाने वाले किसी भी शेल स्क्रिप्ट में यूनिक्स लाइन एंडिंग्स हैं। यदि उनके पास अंत में ^ M है तो वे विंडो लाइन एंडिंग हैं। उन्हें ठीक करने का एक तरीका है dos2unix के साथ /usr/local/start-all.sh पर उन्हें विंडोज़ से यूनिक्स में बदलना। इंटरैक्टिव मोड में डॉक चलाने से अन्य समस्याओं का पता लगाने में मदद मिल सकती है। आपके पास कोई फ़ाइल नाम टाइपो या कुछ हो सकता है। देख https://en.wikipedia.org/wiki/Newline

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