2015-10-14 21 views
23

में पर्यवेक्षक का उपयोग मैं पर्यवेक्षक के उपयोग के बारे में नहीं पूछ रहा हूं, लेकिन सिर्फ मेरी समझ को सत्यापित करना चाहता हूं।डॉकर

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

मैंने कई उदाहरण देखे हैं जहां आधार छवि से एक कंटेनर शुरू किया गया है और कई सेवा स्थापित की गई हैं और कंटेनर बिना किसी पर्यवेक्षक के एक नई छवि बनाने के लिए प्रतिबद्ध है।

तो, मेरा मूल संदेह था कि दोनों दृष्टिकोणों के बीच क्या अंतर है।

मेरी समझ यह है कि जब डॉकर कंटेनर बंद हो जाता है तो यह पीआईडी ​​1 के साथ प्रक्रिया में एक हत्या संकेत भेजता है, पीआईडी ​​1 बच्चे की प्रक्रिया का प्रबंधन करता है और पर्यवेक्षक द्वारा किया जाता है जो सभी बच्चे को रोकता है, जबकि हम एकाधिक प्रक्रिया स्थापित कर सकते हैं पर्यवेक्षक के बिना केवल एक प्रक्रिया को चलाया जा सकता है जब डॉकर रन जारी किया जाता है और जब कंटेनर रोका जाता है तो केवल पीआईडी ​​1 सिग्नल भेजे जाएंगे और अन्य चल रही प्रक्रिया को बंद नहीं किया जाएगा।

कृपया पुष्टि करें कि पर्यवेक्षक का उपयोग करने के बारे में मेरी समझ कितनी सही है।

धन्यवाद

+0

अद्यतन सितम्बर वर्ष 2016 काटते गया है ] (http://stackoverflow.com/a/39593409/6309) नीचे: डॉकर डिमन आपके लिए डॉकर 1.12 में उन ज़ोंबी प्रक्रियाओं का ख्याल रख सकता है। – VonC

उत्तर

38

हम पर्यवेक्षक बिना एकाधिक प्रक्रिया स्थापित कर सकते हैं, जबकि, जब डोकर रन जारी किया जाता है और जब कंटेनर केवल पीआईडी ​​1 संकेतों और अन्य चल प्रक्रिया भेजा जाएगा रोक दिया जाता है केवल एक ही प्रक्रिया चलाया जा सकता है नहीं होगा कृपा से रोका जा सकता है।

हां, हालांकि यह इस बात पर निर्भर करता है कि आपकी मुख्य प्रक्रिया कैसे चलती है (अग्रभूमि या पृष्ठभूमि), और यह बाल प्रक्रियाओं को कैसे एकत्र करती है।

है यही कारण है कि "Trapping signals in Docker containers"

docker stop में विस्तृत है यह SIGTERM संकेत भेजने के द्वारा एक चल कंटेनर बंद हो जाता है, मुख्य प्रक्रिया प्रक्रिया करते हैं यह, और एक अनुग्रह अवधि के बाद SIGKILL का उपयोग करता है आवेदन समाप्त करने के लिए।

कंटेनर को भेजे गए सिग्नल को चलने वाली मुख्य प्रक्रिया (पीआईडी ​​1) द्वारा नियंत्रित किया जाता है।

यदि आवेदन अग्रभूमि में है, जिसका अर्थ है कि एप्लिकेशन एक कंटेनर (पीआईडी ​​1) में मुख्य प्रक्रिया है, तो यह सिग्नल को सीधे संभाल सकता है।

लेकिन:

प्रक्रिया पृष्ठभूमि एक हो सकता है और आप किसी भी संकेत सीधे नहीं भेज सकते हैं संकेत किया जाना है। इस मामले में एक समाधान एक स्क्रिप्ट-स्क्रिप्ट को एंट्रीपॉइंट के रूप में स्थापित करना है और उस स्क्रिप्ट में सभी सिग्नल प्रोसेसिंग को ऑर्केस्ट्रेट करना है।

मुद्दा "Docker and the PID 1 zombie reaping problem"

यूनिक्स इस तरह से कि माता-पिता की प्रक्रिया को स्पष्ट रूप से बच्चे प्रक्रिया समाप्ति के लिए "प्रतीक्षा" चाहिए, ताकि इसकी बाहर निकलें स्थिति को इकट्ठा करने में में बनाया गया है में आगे विस्तृत है।जब तक सिस्टम कॉल के waitpid() परिवार का उपयोग करके पैरेंट प्रक्रिया ने इस क्रिया को निष्पादित नहीं किया है, तब तक ज़ोंबी प्रक्रिया मौजूद है।

अपनी ज़ोंबी को खत्म करने के लिए एक बाल प्रक्रिया पर प्रतीक्षापिप() को कॉल करने की क्रिया को "काटने" कहा जाता है।

init प्रक्रिया - पीआईडी ​​1 - एक विशेष कार्य है। इसका कार्य अनाथाश्रम बाल प्रक्रियाओं को "अपनाना" है।

https://blog.phusion.nl/wp-content/uploads/2015/01/adoption.png

ऑपरेटिंग सिस्टम init प्रक्रिया बच्चों को गोद लिया भी काटते करने की उम्मीद है। डोकर साथ

समस्या:

हम बहुत से लोगों को उनके कंटेनर में केवल एक ही प्रक्रिया को चलाने कि देखते हैं, और उन्हें लगता है कि जब वे इस एकल प्रक्रिया चलाने के लिए, वे काम हो गया।
लेकिन सबसे अधिक संभावना है, यह प्रक्रिया एक उचित init प्रक्रिया की तरह व्यवहार करने के लिए नहीं लिखा है।
यह है कि, गोद लेने वाली प्रक्रियाओं को सही तरीके से प्राप्त करने के बजाय, यह शायद उस काम को करने के लिए init प्रक्रिया की अपेक्षा कर रहा है, और ठीक है।

phusion/baseimage-docker जैसी छवि का उपयोग करना एक मुख्य प्रक्रिया init-compliant रखते हुए एक (या कई) प्रक्रिया (एसएस) को प्रबंधित करने में मदद करता है।

यह runit instead of supervisord का उपयोग करता है, बहु प्रक्रिया प्रबंधन के लिए:

Runit वहाँ उठा समस्या को हल करने के लिए नहीं है। इसके बजाय, यह कई प्रक्रियाओं का समर्थन करना है। सुरक्षा के लिए कई प्रक्रियाओं को प्रोत्साहित किया जाता है (प्रक्रिया और उपयोगकर्ता अलगाव के माध्यम से)।
रनिट Supervisord से कम मेमोरी का उपयोग करता है क्योंकि रनिट पाइथन में सी और सुपरवाइज़र्ड में लिखा गया है।
और कुछ उपयोग मामलों में, कंटेनर में प्रक्रिया पुनरारंभ पूरे कंटेनर पुनरारंभ पर बेहतर है।

उस छवि में my_init script शामिल है जो "काटने" मुद्दे का ख्याल रखता है।

बेसिमेज-डॉकर में, हम एक ही कंटेनर में एकाधिक प्रक्रियाओं को चलाने के लिए प्रोत्साहित करते हैं। हालांकि जरूरी नहीं कि कई सेवाएं।
एक लॉजिकल सेवा में कई ओएस प्रक्रियाएं हो सकती हैं, और हम आसानी से ऐसा करने के लिए सुविधाएं प्रदान करते हैं।

+0

आपके विस्तृत उत्तर के लिए धन्यवाद। मैं फ़्यूज़न छवि की कोशिश कर रहा हूं और जैसा कि मैं समझता हूं कि जब भी कंटेनर शुरू होता है तो यह /etc/init.d में जो कुछ भी चलता है। लेकिन, मेरे पास init.d में एक सेवा है जो कंटेनर बूट पर शुरू नहीं हो रही है। क्या आप कृपया मदद कर सकते हैं। – user3275095

+0

निश्चित: क्या आप अपने नए सेटअप के विवरण के साथ एक नया प्रश्न पूछ सकते हैं? इस तरह, मैं (और संभावित रूप से अन्य) एक नज़र देख सकते हैं। – VonC

+0

ओह .. मेरी गलती इसकी /etc/my_init.d – user3275095

10

अद्यतन डोकर 1.12 (Q4 वर्ष 2016/Q1 2017) के लिए Sept 2016

Arnaud Porterie सिर्फ twitted:

[] बस विलय कर दिया: docker run --init साथ, Rick Grimes अपने सभी लाश की देखभाल करेंगे।

(commit eabae09)

PR 26061 देखें: "ज़ोंबी लड़ाई और संकेत से निपटने के लिए init प्रक्रिया जोड़ें" (और PR 26736)

यह लाश से लड़ने के लिए एक छोटी सी सी बाइनरी कहते हैं। इसे /dev/init के तहत रखा गया है और उपयोगकर्ता द्वारा निर्दिष्ट तर्कों के लिए तैयार किया गया है। आप इसे डेमॉन ध्वज, डॉकर्ड --init के माध्यम से सक्षम करते हैं, क्योंकि यह पीछे की ओर compat के लिए डिफ़ॉल्ट द्वारा अक्षम है।

तुम भी डेमॉन विकल्प को ओवरराइड या docker run --init=true|false के साथ प्रति कंटेनर के आधार एक पर इस निर्दिष्ट कर सकते हैं।

आप एक कंटेनर में पीआईडी ​​1 के रूप में इस तरह की एक प्रक्रिया चल करके इसकी जांच और अतिरिक्त ज़ोंबी कि कंटेनर में प्रकट होता है के रूप में यह चल रहा है देख सकते हैं। देखें [मेरी नई जवाब:

int main(int argc, char ** argv) { 
    pid_t pid = fork(); 
    if (pid == 0) { 
     pid = fork(); 
     if (pid == 0) { 
      exit(0); 
     } 
     sleep(3); 
     exit(0); 
    } 
    printf("got pid %d and exited\n", pid); 
    sleep(20); 
} 

docker daemon अब विकल्प

--init 

भागो कंटेनर के अंदर एक init संकेत आगे और प्रक्रियाओं

+0

अपडेट के लिए धन्यवाद। – user3275095