सेवाओं को शुरू करने के बाद डॉकटर कंटेनर को कैसे रखें?


156

मैंने ट्यूटोरियल का एक गुच्छा देखा है जो ऐसा लगता है कि मैं वही करने की कोशिश कर रहा हूं, लेकिन किसी कारण से मेरे डॉकटर कंटेनर से बाहर निकल जाते हैं। असल में, मैं एक डॉकर कंटेनर के अंदर एक वेब-सर्वर और कुछ डेमॉन स्थापित कर रहा हूं। मैं इसके अंतिम भागों को बैश स्क्रिप्ट के run-all.shमाध्यम से करता हूं जिसे मैं अपने डॉकफाइल में सीएमडी के माध्यम से चलाता हूं। run-all.shइस तरह दिखता है:

service supervisor start
service nginx start

और मैं इसे अपने डॉकरफाइल के अंदर शुरू करता हूं:

CMD ["sh", "/root/credentialize_and_run.sh"]

मैं देख सकता हूं कि जब मैं मैन्युअल रूप से चीजें चलाता हूं (यानी -t / bin / bash के साथ इमेज में), तो सब कुछ सही ढंग से शुरू हो जाता है, और जब मैं इमेज को चलाता हूं तो सब कुछ ऐसा दिखता है कि यह सही तरीके से चलता है, लेकिन यह एक बार निकल जाता है यह मेरी प्रक्रियाओं को पूरा करता है। मैं अनिश्चित काल तक चलने वाली प्रक्रियाओं को पसंद करता हूं, और जहां तक ​​मैं समझता हूं, ऐसा होने के लिए कंटेनर को चालू रखना होगा। फिर भी, जब मैं दौड़ता हूं, तो docker ps -aदेखता हूं:

➜  docker_test  docker ps -a
CONTAINER ID        IMAGE                            COMMAND                CREATED             STATUS                      PORTS               NAMES
c7706edc4189        some_name/some_repo:blah   "sh /root/run-all.sh   8 minutes ago       Exited (0) 8 minutes ago                        grave_jones

क्या देता है? क्यों निकल रहा है? मुझे पता है कि मैं इसे रखने के लिए अपनी बैश स्क्रिप्ट के अंत में थोड़ी देर का लूप डाल सकता हूं, लेकिन इसे बाहर निकालने के लिए सही तरीका क्या है?


1
क्या आप सेवाओं के बंदरगाहों को बाहर (-p विकल्प को चलाने के लिए) उजागर कर रहे हैं? (बेशक यह उन्हें बाहर निकलने से नहीं रोकेगा)
रिबमार

1
मैं अपने Dockerfile में ENTRYPOINT का उपयोग कर रहा था, और ENTRYPOINT (मेरी init स्क्रिप्ट) में परिभाषित स्क्रिप्ट चलने के बाद, यह लॉग में दिखाई दी, लेकिन मेरा कंटेनर बाहर निकलता हुआ लग रहा था। इसलिए, ENTRYPOINT के बजाय, मैंने स्क्रिप्ट को चलाने के लिए RUN कमांड का उपयोग किया और कंटेनर अभी भी पृष्ठभूमि में चल रहा है।
यपालहजानी

जवाबों:


50

यह वास्तव में नहीं है कि आपको अपने डॉकर कंटेनरों को कैसे डिज़ाइन करना चाहिए।

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

जब कंटेनर खुद बाहर निकल जाएगा "प्रक्रिया" (आपके मामले में, वह प्रक्रिया आपकी बैश स्क्रिप्ट है)।


हालांकि, अगर आप वास्तव में , जरूरत है (या चाहते हैं) अपने डोकर कंटेनर में एक से अधिक सेवा चलाने के लिए से शुरू करने पर विचार "डोकर बेस छवि" है, जो का उपयोग करता है runitएक छद्म init प्रक्रिया के रूप में ( runitहै, जो रहेगी ऑनलाइन जबकि Nginx और पर्यवेक्षक रन रहना होगा) अग्रभूमि में जबकि आपकी अन्य प्रक्रियाएं अपनी बात करती हैं।

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


1
क्या आप बता सकते हैं कि मुझे केवल एक ही सेवा क्यों चाहिए? यदि आवश्यक हो तो मैं पर्यवेक्षक के लिए nginx जोड़ सकता हूं, लेकिन यह सुनिश्चित नहीं करना चाहिए कि यह क्यों आवश्यक होना चाहिए।
एली

3
@Eli संक्षिप्त उत्तर यह है कि इस तरह से डॉकर काम करता है। डॉकटर प्रति कंटेनर केवल एक प्रक्रिया (और उसके बच्चों) को चलाएगा। यह अनुशंसा की जाती है कि यह प्रक्रिया एक वास्तविक अनुप्रयोग प्रक्रिया हो (ताकि यदि यह बाहर निकल जाए, तो डॉकर को पता चले), लेकिन आप वास्तव में उस प्रक्रिया के रूप में पर्यवेक्षक का उपयोग कर सकते हैं। ध्यान दें कि आपको पर्यवेक्षक को अग्रभूमि में चलाने के लिए कॉन्फ़िगर करना होगा (अर्थात डैमोनीज़ नहीं), जो --nodaemonविकल्प के माध्यम से किया जाता है ।
थॉमस ओरोज्को

1
@ यह डॉकटर ब्लॉग पोस्ट ऐसा मामला बनाती है जो कई प्रक्रियाओं को चलाती है (और, मोटे तौर पर, एक "छोटे VPS" के रूप में एक कंटेनर को देखने वाला) सबोप्टीमल है। आपके मामले में, टिप्पणी धागा वास्तविक ब्लॉग पोस्ट की तुलना में संभवतः अधिक प्रासंगिक होगा।
थॉमस ओरोज्को

1
डॉकर आधार छवि उद्यम की बहुत सारी समस्याओं के लिए एक भयानक समाधान है क्योंकि कुछ गंभीर कंपनियां आरयूईएल / सेंटोस पेड़ के बजाय ubuntu का उपयोग करती हैं।
सॉफ्टवेयर इंजीनियर

9
"कुछ गंभीर कंपनियां" अनिश्चित लगती हैं। OS का चुनाव पूरी तरह से उपयोग के मामले पर आधारित होगा। किसी भी दी गई कंपनी में आंतरिक डेवलपर उपयोग, आंतरिक कर्मचारी उपयोग, बिक्री समर्थन, स्टेजिंग, POCs और अंत में उत्पादन (और यहां तक ​​कि एक अस्पष्ट शब्द है) सहित विभिन्न वातावरण हैं। मुझे विश्वास नहीं है कि ओपी ने उनके उपयोग के मामले का उल्लेख किया है, (क्षमा करने के लिए नाइटपिकी) लेकिन इस प्रकार की टिप्पणी से ऐसा लगता है कि यह बिना किसी तर्क के साथ अत्यधिक राय वाली जानकारी प्रसारित करता है।
जॉन कैरेल

155

यदि आप डॉकरफाइल का उपयोग कर रहे हैं, तो प्रयास करें:

ENTRYPOINT ["tail", "-f", "/dev/null"]

(जाहिर है कि यह केवल देव उद्देश्यों के लिए है, आपको एक कंटेनर को जीवित रखने की आवश्यकता नहीं होनी चाहिए जब तक कि यह एक प्रक्रिया जैसे उदासीन चल रहा हो। nginx ...)


5
मैं उपयोग कर रहा था, CMD["sleep", "1d"]लेकिन आपका समाधान बेहतर है
जॉर्ज प्लिगोरोपोलोस

@GeorgiosPligoropoulos यह उस लाइन में फंस जाएगा; शायद पृष्ठभूमि में चल रहा है काम करेगा
प्रशांत सम्स

5
का भी उपयोग कर सकते हैं CMD["sleep", "infinity"]
रोमेन

5
या 'बिल्ली' लेकिन लोग कह सकते हैं कि यह पशु दुर्व्यवहार है। xD
Lawphotog

आप अपनी प्रविष्टि की स्क्रिप्ट को समाप्त कर सकते हैं exec tail -f /dev/nullलेकिन tailप्रविष्टि बिंदु के रूप में उपयोग करना गलत उत्तर है।
टॉर्स्टन ब्रॉन्जर

86

मुझे बस यही समस्या थी और मुझे पता चला कि यदि आप अपने कंटेनर को ध्वज -tऔर -dध्वज के साथ चला रहे हैं , तो यह चलता रहता है।

docker run -td <image>

यहाँ है कि झंडे क्या करते हैं (अनुसार docker run --help):

-d, --detach=false         Run container in background and print container ID
-t, --tty=false            Allocate a pseudo-TTY

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


3
मैं इसे पुन: पेश नहीं कर सकता। क्या आप कृपया एक उदाहरण प्रदान करेंगे? क्या डॉकरफाइल के बारे में कुछ विशिष्ट (जैसे: सीएमडी) है जो हमें काम करने के लिए चाहिए?
मैथ्यूस संताना

2
इसने मेरे लिए काम नहीं किया। मैंने docker logs <image>यह सुनिश्चित करने के लिए कमांड का उपयोग किया कि यह एक त्रुटि थी जो मेरे डॉकटर कंटेनर से बाहर निकलने का कारण बनती है। बाहर निकलने की स्थिति है 0और अंतिम आउटपुट की पुष्टि है कि मेरा lighttpdसर्वर चल रहा है:[ ok ] Starting web server: lighttpd.
ob1

मैं अभी कुछ समय के लिए डॉकर के साथ काम नहीं कर रहा हूं। इसलिए यह संभव है कि कमांड लाइन इंटरफ़ेस बदल गया और यह कमांड अब काम नहीं करता है।
arne.z

4
मैं पुष्टि कर सकता हूं कि यह वास्तव में नवीनतम डॉक संस्करण के साथ काम कर रहा है। यदि आप बाद में इस सत्र में संलग्न होना चाहते हैं, तो -dit का उपयोग करना भी काम करेगा।
जॉन हैमिल्टन

1
@ लिपि एक tty को स्वीकार नहीं करेगी, प्रारंभ exec bashया exec shअंत तक bash स्थापित नहीं है, तो जोड़ें । तब आप -t ध्वज का उपयोग कर सकते हैं
123

43

बाहर निकलने का कारण यह है क्योंकि शेल स्क्रिप्ट को पहले PID 1 के रूप में चलाया जाता है और जब यह पूरा हो जाता है, तो PID 1 चला जाता है, और docker केवल चलता है जबकि PID 1 है।

आप सब कुछ करने के लिए पर्यवेक्षक का उपयोग कर सकते हैं, अगर "-n" ध्वज के साथ चलाया जाता है, तो इसे बताया नहीं जाता है, इसलिए यह पहली प्रक्रिया के रूप में रहेगा:

CMD ["/usr/bin/supervisord", "-n"]

और आपके पर्यवेक्षक .conf:

[supervisord]
nodaemon=true

[program:startup]
priority=1
command=/root/credentialize_and_run.sh
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=false
startsecs=0

[program:nginx]
priority=10
command=nginx -g "daemon off;"
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.log
autorestart=true

फिर आपके पास जितनी चाहें उतनी अन्य प्रक्रियाएं हो सकती हैं और यदि आवश्यक हो तो पर्यवेक्षक उन्हें पुनः आरंभ करने का काम संभालेंगे।

इस तरह से आप उन मामलों में पर्यवेक्षक का उपयोग कर सकते हैं जहाँ आपको nginx और php5-fpm की आवश्यकता हो सकती है और इससे उन्हें अलग होने का कोई मतलब नहीं है।


डॉक्स में यह कहां कहा गया है कि यदि पीआईडी ​​1 समाप्त होता है तो डॉकटर कंटेनर चलना बंद हो जाता है?
8oh8

@ @ ९; यह अनिवार्य रूप से प्रक्रिया नामस्थान कैसे काम करता है; यह डॉकर-विशिष्ट नहीं है, क्योंकि "सभी कंटेनरों में अंतर्निहित चीज"। से man7.org/linux/man-pages/man7/pid_namespaces.7.html :If the "init" process of a PID namespace terminates, the kernel terminates all of the processes in the namespace via a SIGKILL signal. This behavior reflects the fact that the "init" process is essential for the correct operation of a PID namespace.
dannysauer

40

आप catबिना किसी तर्क के सादा चल सकते हैं, जैसा कि भाई @ सा'द द्वारा बताए गए कंटेनर को बस काम में रखने के लिए [वास्तव में उपयोगकर्ता इनपुट के लिए इंतजार करने के अलावा कुछ भी नहीं कर रहा है] (जेनकींस का डॉकर प्लगइन यही काम करता है)


मेरे उत्तर के अलावा: लेकिन यह समझें कि docker-compose (daemonized नहीं) का उपयोग आपको आपके कंटेनर के वर्कफ़्लो को दिखाने के लिए किया जाता है, इसलिए हो सकता है कि यह आपकी शुरू की गई सेवाओं की लॉग फ़ाइलों को पूँछने में सहायक हो। चीयर्स
सर्ज वेलिकानोव 12

1
या cat। जेनकिन का डॉकटर प्लगइन ऐसा करता है।
सा'द

12

सुनिश्चित करें कि आप अपने लिए daemon off;nginx.conf को जोड़ते हैं या इसे CMD ["nginx", "-g", "daemon off;"]आधिकारिक nginx छवि के अनुसार चलाते हैं

फिर दोनों सुपरवाइज़र को सेवा और नेग्नेक्स को अग्रभूमि प्रक्रिया के रूप में चलाने के लिए उपयोग करें जो कंटेनर को बाहर निकलने से रोक देगा

service supervisor start && nginx

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

इसलिए आपको ट्रेड-ऑफ को समझने और उसके अनुसार अपना निर्णय लेने की आवश्यकता है।


7

प्रेरणा:

वहाँ है एक डोकर कंटेनर के अंदर कई प्रक्रियाओं को चलाने में कुछ भी नहीं गलत । यदि कोई एक हल्का वजन वीएम के रूप में डॉक का उपयोग करना पसंद करता है - तो ऐसा ही हो। अन्य लोग अपने अनुप्रयोगों को सूक्ष्म सेवाओं में विभाजित करना पसंद करते हैं। मुझे लगता है: एक कंटेनर में एक दीपक ढेर? सिर्फ महान।

उत्तर:

छड़ी की तरह एक अच्छा आधार छवि के साथफ़्यूज़न बेस इमेज की । और भी हो सकते हैं। कृपया टिप्पणी करें।

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

यदि आप इस बेसिक डॉक रन स्टेटमेंट को जारी करते हैं, तो फ़्यूज़न इमेज ही शुरू हो जाएगी और चलती रहेगी:

moin@stretchDEV:~$ docker run -d phusion/baseimage
521e8a12f6ff844fb142d0e2587ed33cdc82b70aa64cce07ed6c0226d857b367
moin@stretchDEV:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS
521e8a12f6ff        phusion/baseimage   "/sbin/my_init"     12 seconds ago      Up 11 seconds

या मृत सरल:

यदि एक आधार छवि आपके लिए नहीं है ... त्वरित सीएमडी के लिए इसे चालू रखने के लिए मैं कुछ इस तरह के प्रतिबंध के लिए मानूंगा:

CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait"

या यह बिजीबॉक्स के लिए:

CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait"

यह अच्छा है, क्योंकि यह एक पर तुरंत बाहर निकल जाएगा docker stop। बस सादे sleepया catकंटेनर रास्ते से पहले कुछ सेकंड का समय लगेगा।


मैंने PostgreSQL 11. लोड करने के लिए सेंटोस 7 बेस इमेज को कस्टमाइज़ किया। आप शुरू करते हैं कि / usr / pgsql-11 / bin / pg_ctl पर कॉल करें, लेकिन pg_ctl सर्वर के चलने के बाद बाहर निकलता है। जाल का उपयोग करने का आपका सुझाव बहुत काम आया; यह मेरी स्क्रिप्ट की अंतिम पंक्ति है pgstartwait.sh
अल्केमिस्टमैट

6

एक चर में ngnix प्रक्रिया के PID पर कब्जा (उदाहरण के लिए $ NGNIX_PID) और प्रविष्टि फ़ाइल के अंत में

wait $NGNIX_PID 

इस तरह से, आपके कंटेनर को तब तक चलना चाहिए जब तक कि नग्नेक्स जीवित न हो जाए, जब नगनीक्स बंद हो जाता है, तो कंटेनर भी रुक जाता है


0

यदि उपलब्ध हो तो सेवा के पर्यवेक्षण रूप का उपयोग कैसे करें?

Your_SERVICE पर्यवेक्षण की सेवा करें

एक बार पर्यवेक्षण सफलतापूर्वक चल रहा है, यह तब तक बाहर नहीं निकलेगा जब तक कि इसे मार न दिया जाए या विशेष रूप से बाहर निकलने के लिए न कहा जाए।

बचाता है एक बनाने के लिए supervisord.conf

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