डॉकर परतों को समझना


27

हमारे पास निम्नलिखित ब्लॉक हैं Dockerfile:

RUN yum -y update
RUN yum -y install epel-release
RUN yum -y groupinstall "Development Tools"
RUN yum -y install python-pip git mysql-devel libxml2-devel libxslt-devel python-devel openldap-devel libffi-devel openssl-devel

मुझे बताया गया है कि हमें RUNनिर्मित कमांड लेयर्स में कटौती करने के लिए इन कमांडों को एकजुट करना चाहिए :

RUN yum -y update \
    && yum -y install epel-release \
    && yum -y groupinstall "Development Tools" \
    && yum -y install python-pip git mysql-devel libxml2-devel libxslt-devel python-devel openldap-devel libffi-devel openssl-devel

मैं डॉकटर के लिए बहुत नया हूं और यकीन नहीं है कि मैं कई RUN कमांड को निर्दिष्ट करने के इन दो संस्करणों के बीच के अंतरों को पूरी तरह से समझता हूं। जब RUNकोई एक एकल में कमांड को एकजुट करेगा और जब यह कई RUNकमांड के लिए समझ में आता है ?


जवाबों:


35

डॉकटर छवि वास्तव में फाइलसिस्टम परतों की एक लिंक की गई सूची है। Dockerfile में प्रत्येक निर्देश एक फाइल सिस्टम लेयर बनाता है जो संबंधित निर्देश के निष्पादन से पहले और बाद में फाइल सिस्टम में अंतर का वर्णन करता है। docker inspectSubcommand फाइल सिस्टम परतों के एक लिंक्ड सूची होने के अपने स्वभाव प्रकट करने के लिए एक डोकर छवि पर इस्तेमाल किया जा सकता।

एक छवि में उपयोग की जाने वाली परतों की संख्या महत्वपूर्ण है

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

यह कैसे छवियों का निर्माण किया जाना चाहिए के लिए कई परिणाम हैं। पहली और सबसे महत्वपूर्ण सलाह जो मैं दे सकता हूं वह है:

सलाह # 1 सुनिश्चित करें कि आपके स्रोत कोड में शामिल निर्माण चरण डॉकफाइल में जितनी देर हो सके उतनी देर से आए और एक &&या एक का उपयोग करके पिछले कमांड से बंधे न हों ;

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

मेरी दूसरी सलाह कम महत्वपूर्ण है लेकिन मैं इसे रखरखाव के दृष्टिकोण से बहुत उपयोगी मानता हूं:

सलाह # 2 डॉकरफाइल में जटिल कमांड न लिखें , बल्कि उन स्क्रिप्ट का उपयोग करें जिन्हें कॉपी और निष्पादित किया जाना है।

इस सलाह का पालन करने वाला डॉकरफाइल जैसा लगेगा

COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
COPY install_pacakges.sh /root/
RUN sh -x /root/install_packages.sh

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

प्री-प्रोसेसर से दिलचस्पी रखने वाले लोग COPYऔर कदमों के कारण होने वाले छोटे ओवरहेड से बचने के लिए तैयार रहते हैं और वास्तव में एक डॉकरफाइल को ऑन-द-फ्लाई करते हैं जहां

COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh

अनुक्रमों द्वारा प्रतिस्थापित किया जाता है

RUN base64 --decode … | sh -x

जहां का आधार 64-एन्कोडेड संस्करण है apt_setup.sh

मेरी तीसरी सलाह उन लोगों के लिए है जो आकार और परतों की संख्या को लंबे समय तक बनाए रखना चाहते हैं।

सलाह # 3with मध्यवर्ती परतों में मौजूद फाइलों से बचने के लिए -idiom का उपयोग करें लेकिन परिणामी फाइलसिस्टम में नहीं।

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

उदाहरण के लिए, मान लें कि हमें अस्थायी रूप से C कंपाइलर और कुछ छवि की आवश्यकता है और विचार करें

# !!! THIS DISPLAYS SOME PROBLEM --- DO NOT USE !!!
RUN apt-get install -y gcc
RUN gcc --version
RUN apt-get --purge autoremove -y gcc

(अधिक यथार्थवादी उदाहरण केवल --versionध्वज के साथ अपनी उपस्थिति का दावा करने के बजाय संकलक के साथ कुछ सॉफ़्टवेयर का निर्माण करेगा ।)

Dockerfile स्निपेट तीन परतें बनाता है, पहले वाले में पूर्ण gcc सूट होता है, भले ही वह अंतिम फाइल सिस्टम में मौजूद न हो, लेकिन संबंधित डेटा अभी भी उसी तरह से छवि का हिस्सा है और जब भी डाउनलोड, अपलोड और अनसुना करने की आवश्यकता होती है अंतिम छवि है

with-Idiom अलग संसाधन स्वामित्व और संसाधन इसे प्रयोग तर्क से रिहा करने के लिए कार्यात्मक प्रोग्रामिंग में एक आम रूप है। इस मुहावरे को शेल-स्क्रिप्टिंग में स्थानांतरित करना आसान है, और हम पिछली स्क्रिप्ट को निम्नलिखित स्क्रिप्ट के रूप में फिर से लागू कर सकते हैं, COPY & RUNजैसा कि सलाह # 2 में इस्तेमाल किया जा सकता है

# with_c_compiler SIMPLE-COMMAND
#  Execute SIMPLE-COMMAND in a sub-shell with gcc being available.

with_c_compiler()
(
    set -e
    apt-get install -y gcc
    "$@"
    trap 'apt-get --purge autoremove -y gcc' EXIT
)

with_c_compiler\
    gcc --version

कॉम्प्लेक्स कमांड को फ़ंक्शन में बदल दिया जा सकता है ताकि उन्हें खिलाया जा सके with_c_compiler। यह कई with_whateverकार्यों के कॉल की श्रृंखला के लिए भी संभव है , लेकिन शायद बहुत वांछनीय नहीं है। (शेल की अधिक गूढ़ विशेषताओं का उपयोग करके, निश्चित रूप से with_c_compilerजटिल कमांड को बनाना संभव है , लेकिन इन जटिल कमांड्स को फ़ंक्शन में लपेटने के लिए यह सभी पहलुओं में बेहतर है।)

अगर हम सलाह # 2 को नजरअंदाज करना चाहते हैं, तो परिणामस्वरूप डॉकरीफाइल स्निपेट होगा

RUN apt-get install -y gcc\
 && gcc --version\
 && apt-get --purge autoremove -y gcc

जो ओफिसकेशन के कारण पढ़ना और बनाए रखना इतना आसान नहीं है। देखें कि शेल-स्क्रिप्ट संस्करण किस प्रकार महत्वपूर्ण भाग पर जोर देता है gcc --versionजबकि जंजीर- &&संस्करण शोर के बीच में उस हिस्से को दबा देता है।


1
क्या आप स्क्रिप्ट का उपयोग करके और एक RUN स्टेटमेंट में कई कमांड्स का उपयोग करके बॉक्स के आकार का परिणाम शामिल कर सकते हैं?
030

1
यह मेरे लिए एक बुरा विचार है कि इमेज बेस (यानी ओएस सामान) के कॉन्फ़िगरेशन को मिलाएं और आपके द्वारा लिखे गए स्रोत के सेट के साथ भी लिबास। आप कहते हैं कि "सुनिश्चित करें कि जहां आपके स्रोत कोड शामिल हैं, वहां कदम संभव के रूप में देर से आता है"। क्या उस हिस्से को पूरी तरह से स्वतंत्र कलाकृति बनाने में कोई समस्या है?
जिमीजैम

1
@ 030 "बॉक्स" आकार के साथ आपका क्या मतलब है? मुझे नहीं पता कि आप किस बॉक्स का जिक्र कर रहे हैं।
माइकल ले बारबियर ग्रुएनवाल्ड

1
मैं मतलब डोकर छवि का आकार
030

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

13

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

मान लें कि आपके पास निम्नलिखित डॉकरीफाइल हैं:

FROM centos:6

RUN yum -y update 
RUN yum -y install epel-release

परिणामी छवि का आकार होगा

bigimage     latest        3c5cbfbb4116        2 minutes ago    407MB

इसके विपरीत, "समान" डॉकरफाइल के साथ:

FROM centos:6

RUN yum -y update  && yum -y install epel-release

परिणामी छवि का आकार होगा

smallimage     latest        7edeafc01ffe        3 minutes ago    384MB

यदि आप एकल RUN स्टेटमेंट में यम कैश को साफ करते हैं तो आपको और भी छोटे आकार मिलेंगे।

इसलिए आप पठनीयता / रखरखाव में आसान और परतों / छवि के आकार के बीच संतुलन रखना चाहते हैं।


4

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

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