كيفية تشغيل خدمات متعددة في حاوية Docker واحدة

نشرت: 2022-06-30

رسم توضيحي يظهر شعار Docker

Docker هي تقنية لتعبئة مكونات مكدسك كحاويات معزولة. من الشائع تشغيل كل عملية من عملياتك في حاويتها الخاصة ، مما يؤدي إلى إنشاء فجوة واضحة بين المكونات. يعمل هذا على تحسين النمطية ويسمح لك بالوصول إلى مزايا قابلية التوسع للحاوية.

لا يزال من الممكن أن تكون هناك مواقف تريد فيها تشغيل خدمات متعددة داخل حاوية واحدة. على الرغم من أن هذا لا يأتي بشكل طبيعي في نظام Docker البيئي ، فسوف نعرض بعض الأساليب المختلفة التي يمكنك استخدامها لإنشاء حاويات بأكثر من عملية واحدة طويلة العمر.

تحديد المشكلة

تقوم حاويات Docker بتشغيل عملية مقدمة واحدة. يتم تحديد ذلك من خلال تعليمات ENTRYPOINT و CMD الخاصة بالصورة. يتم تعيين نقطة الدخول داخل ENTRYPOINT Dockerfile بينما يمكن تجاوز CMD عند إنشاء الحاويات. تتوقف الحاويات تلقائيًا عند انتهاء عملية المقدمة.

يمكنك تشغيل عمليات أخرى من CMD لكن الحاوية ستظل قيد التشغيل فقط بينما تكون عملية المقدمة الأصلية حية. إن الحفاظ على تشغيل الحاوية خلال العمر الافتراضي المشترك لخدمتين مستقلتين ليس ممكنًا بشكل مباشر باستخدام آلية ENTRYPOINT/CMD .

التفاف عمليات متعددة في نقطة دخول واحدة

سكربتات الغلاف هي أبسط حل للمشكلة. يمكنك كتابة برنامج نصي يبدأ جميع عملياتك وينتظر انتهاءها. سيؤدي تعيين البرنامج النصي على أنه Docker ENTRYPOINT إلى تشغيله كعملية مقدمة للحاوية ، مع الحفاظ على تشغيل الحاوية حتى خروج أحد البرامج النصية المغلفة.

 #! / بن / باش

/ opt / العملية الأولى &

/ opt / second-process &

انتظر -n

الخروج $؟

يبدأ هذا البرنامج النصي ثنائيات /opt/first-process و /opt/second-process داخل الحاوية. يسمح استخدام & للبرنامج النصي بالاستمرار دون انتظار إنهاء كل عملية. wait يستخدم لتعليق البرنامج النصي حتى تنتهي إحدى العمليات. ثم يخرج البرنامج النصي برمز الحالة الصادر عن البرنامج النصي النهائي.

ينتج عن هذا النموذج تشغيل الحاوية كلاً first-process second-process حتى يخرج أحدهما. عند هذه النقطة ، ستتوقف الحاوية ، على الرغم من أن العملية الأخرى ربما لا تزال قيد التشغيل.

لاستخدام هذا البرنامج النصي ، قم بتعديل ENTRYPOINT و CMD لصورة Docker لجعلها العملية الأمامية للحاوية:

 ENTRYPOINT ["/ bin / sh"]
CMD ["./path/to/script.sh"]

خيار الحاوية --init

يتمثل أحد التحديات التي تواجه إدارة عمليات الحاويات في التنظيف الفعال عند خروجها. يقوم Docker بتشغيل CMD العملية 1 ، مما يجعله مسؤولاً عن التعامل مع الإشارات والقضاء على الزومبي. إذا كان البرنامج النصي الخاص بك لا يحتوي على هذه القدرات ، فقد ينتهي بك الأمر مع استمرار العمليات الفرعية المعزولة داخل الحاوية الخاصة بك.

يحتوي أمر --init docker run علامة --init التي تعدل نقطة الدخول لاستخدام tini كـ PID 1. هذا هو الحد الأدنى من تنفيذ عملية init الذي يدير CMD الخاص بك ، ويتعامل مع إعادة توجيه الإشارة ، ويحصد الزومبي باستمرار.

من المفيد استخدام --init إذا كنت تتوقع أن تفرخ العديد من العمليات ولا تريد معالجة التنظيف يدويًا. تيني هي نكهة خفيفة الوزن مصممة للحاويات. إنه أصغر بكثير من البدائل الكاملة مثل systemd و upstart .

باستخدام مدير عمليات مخصص

تصبح البرمجة النصية اليدوية بسرعة دون المستوى الأمثل عندما يكون لديك الكثير من العمليات لإدارتها. يعد اعتماد مدير العمليات طريقة أخرى لتشغيل العديد من الخدمات داخل حاويات Docker الخاصة بك. يصبح مدير العملية نقطة الدخول الخاصة بك ENTRYPOINT مسؤولية بدء عمليات العاملين لديك وصيانتها وتنظيفها.

هناك العديد من الخيارات المتاحة عند تنفيذ هذا النهج. supervisord هو خيار شائع يمكن تهيئته بسهولة عبر ملف /etc/supervisor/conf.d/supervisord.conf :

 [البرنامج: apache2]
الأمر = / usr / sbin / apache2 -DFOREGROUND

[البرنامج: mysqld]
الأمر = / usr / sbin / mysqld_safe

يقوم ملف التكوين هذا بتكوين supervisord لبدء Apache و MySQL. لاستخدامه في حاوية Docker ، أضف جميع الحزم المطلوبة إلى صورتك ، ثم انسخ ملف تكوين supervisord الخاص بك إلى الموقع الصحيح. قم بتعيين supervisord باعتباره CMD للصورة لتشغيله تلقائيًا عند بدء الحاويات.

 من أوبونتو: الأحدث
قم بتشغيل apt-get install -y apache2 mysql-server
COPY Supervisord.conf /etc/supervisor/conf.d/supervisord.conf
ENTRYPOINT ["/ bin / sh"]
CMD ["/ usr / bin / supervisord"]

نظرًا لأن supervisord يعمل باستمرار ، فلا يمكن إيقاف الحاوية عند خروج إحدى العمليات التي تخضع للمراقبة. خيار بديل هو s6-overlay الذي لديه هذه الإمكانية. يستخدم نموذج خدمة تصريحي حيث تضع نصوص الخدمة مباشرة في /etc/services.d :

 # أضف s6-overlay إلى صورتك
أضف https://github.com/just-containers/s6-overlay/releases/download/v3.1.0.0/s6-overlay-noarch.tar.xz / tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz

تشغيل printf "#! / bin / shn / usr / sbin / apache2 -DFOREGROUND"> /etc/services.d/first-service/run
قم بتشغيل chmod + x /etc/services.d/first-service/run

# استخدم s6-overlay كنقطة دخول لصورتك
نقطة دخول ["/ init"]

يمكنك إضافة نص finish قابل للتنفيذ داخل أدلة الخدمة الخاصة بك للتعامل مع إيقاف الحاوية مع docker stop . سيقوم s6-overlay تلقائيًا بتشغيل هذه البرامج النصية عندما تتلقى العملية إشارة TERM بسبب أمر stop .

تتلقى البرامج النصية للإنهاء رمز الخروج لخدمتهم كوسيطة أولى. يتم تعيين الكود على 256 عند توقف الخدمة بسبب إشارة غير معلومة. يحتاج البرنامج النصي إلى كتابة كود الخروج النهائي إلى /run/s6-linux-init-container-results/exitcode ؛ يقرأ s6-overlay هذا الملف ويخرج بالقيمة الموجودة فيه ، مما يتسبب في استخدام هذا الرمز كرمز إيقاف للحاوية الخاصة بك.

 #! / بن / ش
صدى "$ 1"> / run / s6-linux-init-container-results / exitcode

متى يجب تشغيل عمليات متعددة في حاوية؟

تُستخدم هذه التقنية بشكل أفضل مع العمليات المقترنة بإحكام والتي لا يمكنك فصلها لتشغيلها كحاويات مستقلة. قد يكون لديك برنامج يعتمد على أداة مساعدة في الخلفية أو تطبيق مترابط ينفذ إدارته الخاصة للعمليات الفردية. يمكن أن تساعدك الأساليب الموضحة أعلاه في تجميع هذه الأنواع من البرامج.

يجب تجنب تشغيل عمليات متعددة في حاوية قدر الإمكان. يؤدي التمسك بعملية مقدمة واحدة إلى زيادة العزل إلى أقصى حد ، ومنع المكونات من التداخل مع بعضها البعض ، وتحسين قدرتك على تصحيح الأخطاء واختبار قطع معينة. يمكنك قياس المكونات بشكل فردي باستخدام منظمي الحاوية ، مما يمنحك المرونة لتشغيل المزيد من مثيلات عملياتك الأكثر كثافة في استخدام الموارد.

استنتاج

تحتوي الحاويات عادةً على عملية مقدمة واحدة وتعمل طالما أنها على قيد الحياة. يتوافق هذا النموذج مع أفضل ممارسات النقل بالحاويات ويتيح لك استخلاص أكبر قدر من الفوائد من التكنولوجيا.

في بعض الحالات ، قد تحتاج إلى عمليات متعددة للتشغيل في حاوية. نظرًا لأن جميع الصور تحتوي في النهاية على نقطة إدخال واحدة ، يجب عليك كتابة برنامج نصي مجمّع أو إضافة مدير عملية يتولى مسؤولية بدء الثنائيات المستهدفة.

يمنحك مديرو العمليات كل ما تحتاجه ولكن ينفخون صورك بحزم وتكوينات إضافية. نصوص التغليف أبسط ولكن قد تحتاج إلى إقرانها بعلامة Docker --init لمنع تكاثر عمليات الزومبي.