تشغيل systemd في الحاوية

لقد تابعنا موضوع استخدام systemd في حاويات لفترة طويلة. مرة أخرى في عام 2014 ، كتب مهندس الأمن لدينا دانيال والش مقالًا بعنوان Running systemd داخل Docker Container ، وبعد ذلك بعدة أعوام مقال آخر يدعى Running systemd في حاوية غير مميّزة ، ذكر فيها أن الوضع لم يكن تحسنت كثيرا. على وجه الخصوص ، كتب أنه "لسوء الحظ ، وبعد عامين ، إذا كنت google نظام Docker ، فإن أول شيء ينبثق هو نفس المادة القديمة من كتابه. لذلك حان الوقت لتغيير شيء ما. " بالإضافة إلى ذلك ، تحدثنا بالفعل عن الصراع بين مطوري Docker و systemd .



في هذه المقالة سوف نعرض ما الذي تغير على مدار الفترة الماضية وكيف يمكن لبودمان مساعدتنا في هذا الأمر.

هناك العديد من الأسباب لتشغيل systemd داخل الحاوية ، مثل:

  1. حاويات متعددة الخدمات - يريد الكثير من الناس الحصول على تطبيقات متعددة الخدمات من الأجهزة الظاهرية وتشغيلها في حاويات. سيكون من الأفضل ، بالطبع ، تقسيم هذه التطبيقات إلى خدمات ميكروية ، ولكن لا يمكن لأي شخص القيام بذلك حتى الآن أو ببساطة لا يوجد وقت. لذلك ، فإن إطلاق مثل هذه التطبيقات في شكل خدمات يتم تشغيلها بواسطة systemd من ملفات الوحدات أمر منطقي تمامًا.
  2. ملفات وحدة Systemd - يتم تجميع معظم التطبيقات التي تعمل داخل حاويات من تعليمات برمجية سبق تشغيلها على الأجهزة الظاهرية أو الفعلية. تحتوي هذه التطبيقات على ملف وحدة تمت كتابته لهذه التطبيقات ويفهم كيفية تشغيلها. لذلك من الأفضل أن تبدأ الخدمات باستخدام الطرق المدعومة ، بدلاً من اختراق خدمة init الخاصة بك.
  3. Systemd هو مدير العملية. يدير الخدمات (إيقاف التشغيل أو إعادة تشغيل الخدمات أو الزحف إلى عمليات zombie) أفضل من أي أداة أخرى.

هناك العديد من الأسباب لعدم تشغيل systemd في الحاويات. العنصر الرئيسي هو أن systemd / journald يتحكم في إخراج الحاويات ، وتتوقع أدوات مثل Kubernetes أو OpenShift أن تقوم الحاويات بكتابة السجل مباشرة إلى stdout و stderr. لذلك ، إذا كنت تنوي إدارة الحاويات من خلال أدوات تزامن مثل تلك المذكورة أعلاه ، فأنت بحاجة إلى التفكير بجدية في استخدام الحاويات على أساس systemd. بالإضافة إلى ذلك ، عارض مطورو Docker و Moby بشدة استخدام systemd في الحاويات.

القادمة بودمان


يسرنا أن نعلن أن الوضع قد تحرك أخيرًا. قرر الفريق المسؤول عن إطلاق الحاويات في ريد هات تطوير محرك الحاويات الخاص بهم . حصل على اسم Podman ويقدم نفس واجهة سطر الأوامر (CLI) مثل Docker. وتقريبا جميع أوامر Docker يمكن استخدامها بنفس الطريقة في Podman. غالبًا ما نعقد حلقات دراسية ، تسمى الآن Change Docker إلى Podman ، وتشجعك الشريحة الأولى على التسجيل: alias docker = podman.

كثير يفعلون ذلك.

أنا و Podman في أي حال من الأحوال ضد الحاويات القائمة على systemd. بعد كل شيء ، يتم استخدام Systemd غالبًا كنظام فرعي Linux ، وعدم تركه يعمل بشكل طبيعي في حاويات يعني تجاهل الطريقة التي اعتاد الآلاف من الأشخاص تشغيل الحاويات.

يعرف Podman ما يجب القيام به للحصول على systemd يعمل بشكل صحيح في الحاوية. إنها تحتاج إلى أشياء مثل تثبيت tmpfs على / تشغيل و / tmp. تحب عندما يتم تمكين بيئة "الحاوية" ، وهي تنتظر أذونات الكتابة لجزءها من دليل المجموعة cgroup وإلى مجلد / var / log / journald.

عند بدء تشغيل حاوية يكون فيها init أو systemd هو الأمر الأول ، يقوم Podman تلقائيًا بتكوين tmpfs و Cgroups بحيث يبدأ systemd دون مشاكل. لحظر وضع البدء التلقائي هذا ، استخدم الخيار --systemd = false. يرجى ملاحظة أن Podman يستخدم وضع systemd فقط عندما يرى أنه من الضروري تنفيذ الأمر systemd أو init.

هنا مقتطف من الدليل:

رجل بودمان المدى
...

- النظام = صحيح | خطأ

تشغيل الحاوية في وضع systemd. تمكين افتراضيا.

إذا تم تنفيذ أمر systemd أو init داخل الحاوية ، فسيقوم Podman بتكوين نقاط تحميل tmpfs في الدلائل التالية:

/ run ، / run / lock ، / tmp ، / sys / fs / cgroup / systemd ، / var / lib / journal

أيضًا ، سيتم استخدام SIGRTMIN + 3 كإشارة توقف افتراضيًا.

كل هذا يسمح systemd للعمل في حاوية مغلقة دون أي تعديلات.

ملاحظة: يحاول systemd الكتابة إلى نظام ملفات cgroup. ومع ذلك ، SELinux بشكل افتراضي يمنع الحاويات من القيام بذلك. لتمكين الكتابة ، قم بتمكين المعلمة الدفعية container_manage_cgroup:

setsebool -P container_manage_cgroup true

انظر الآن إلى ما يبدو عليه Dockerfile لتشغيل systemd في الحاوية عند استخدام Podman:

# cat Dockerfile FROM fedora RUN dnf -y install httpd; dnf clean all; systemctl enable httpd EXPOSE 80 CMD [ "/sbin/init" ] 

هذا كل شيء.

الآن جمع الحاوية:

 # podman build -t systemd . 

نقول SELinux للسماح systemd لتعديل تكوين Cgroups:

 # setsebool -P container_manage_cgroup true 

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

الآن فقط قم بتشغيل الحاوية:

 # podman run -ti -p 80:80 systemd systemd 239 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid) Detected virtualization container-other. Detected architecture x86-64. Welcome to Fedora 29 (Container Image)! Set hostname to <1b51b684bc99>. Failed to install release agent, ignoring: Read-only file system File /usr/lib/systemd/system/systemd-journald.service:26 configures an IP firewall (IPAddressDeny=any), but the local system does not support BPF/cgroup based firewalling. Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.) [ OK ] Listening on initctl Compatibility Named Pipe. [ OK ] Listening on Journal Socket (/dev/log). [ OK ] Started Forward Password Requests to Wall Directory Watch. [ OK ] Started Dispatch Password Requests to Console Directory Watch. [ OK ] Reached target Slices. … [ OK ] Started The Apache HTTP Server. 

كل شيء ، بدأت الخدمة وتعمل:

 $ curl localhost <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> … </html> 

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

زوجان أكثر الأشياء الرائعة حول Podman و systemd


Podman يعمل بشكل أفضل من عامل ميناء في ملفات وحدة systemd


إذا كانت الحاويات في حاجة لبدء التشغيل ، فيمكنك ببساطة إدخال أوامر Podman المناسبة في ملف وحدة النظام ، والتي ستقوم بتشغيل الخدمة ومراقبتها. يستخدم Podman نموذج شوكة exec القياسي. بمعنى آخر ، عمليات الحاوية مرتبطة بعملية Podman ، لذلك يمكن لـ systemd مراقبتها بسهولة.

يستخدم Docker طراز الخادم - العميل ، ويمكن أيضًا وضع أوامر Docker CLI مباشرة في ملف الوحدة. ومع ذلك ، بعد اتصال عميل Docker بـ البرنامج الخفي Docker ، يصبح (العميل) مجرد عملية أخرى تعالج stdin و stdout. بدوره ، ليس لدى systemd أي فكرة حول الاتصال بين عميل Docker والحاوية التي تقوم بتشغيل البرنامج الخفي Docker ، وبالتالي ، بموجب هذا النموذج ، يتعذر على systemd مراقبة الخدمة بشكل أساسي.

تفعيل SYSTEMD عبر المقبس


Podman يفي التنشيط بشكل صحيح من خلال مأخذ. نظرًا لأن Podman يستخدم طراز fork-exec ، فيمكنه توجيه مأخذ توصيل إلى عمليات الحاوية التابعة. عامل الميناء لا يعرف كيف ، لأنه يستخدم نموذج خادم العميل.

يتم بالفعل تنشيط خدمة varlink التي يستخدمها Podman للتفاعل مع العملاء عن بعد مع الحاويات من خلال المقبس. تسمح حزمة cockpit-podman المكتوبة في Node.js وجزء من مشروع قمرة القيادة للأشخاص بالتفاعل مع حاويات Podman من خلال واجهة ويب. يرسل البرنامج الخفي الذي تقوم بتشغيله cockpit-podman رسائل إلى مأخذ varlink الذي يستمع إليه systemd. بعد ذلك ، يقوم systemd بتنشيط برنامج Podman لتلقي الرسائل والبدء في إدارة الحاويات. يتيح لك تنشيط systemd عبر مأخذ التوصيل الاستغناء عن العمل الخفي باستمرار عند تنفيذ واجهات برمجة التطبيقات البعيدة.

بالإضافة إلى ذلك ، نحن نعمل على تطوير عميل آخر لـ Podman ، يسمى podman-remote ، والذي يقوم بتنفيذ نفس Podman CLI ، ولكننا ندعو varlink لإطلاق الحاويات. يعمل Podman-remote على جلسات SSH ، التي تتيح لك التفاعل بأمان مع الحاويات على أجهزة مختلفة. مع مرور الوقت ، نخطط لاستخدام podman-remote لدعم MacOS و Windows إلى جانب Linux ، بحيث يمكن للمطورين على هذه المنصات تشغيل جهاز Linux الظاهري مع تشغيل Podman varlink ولديهم شعور كامل بأن الحاويات تعمل على الجهاز المحلي.

SD_NOTIFY


يتيح لك Systemd تأخير تشغيل الخدمات المساعدة حتى تبدأ الخدمة المطلوبة في حاويات. يمكن لـ Podman توجيه مأخذ توصيل SD_NOTIFY إلى الخدمة التي يتم نقلها في حاويات بحيث تخطر الخدمة systemd باستعدادها للعمل. ومرة أخرى ، Docker ، باستخدام نموذج خادم العميل ، لا يعرف كيف.

في الخطط


نحن نخطط لإضافة الأمر podman لتوليد systemd CONTAINERID ، والذي سيُنشئ ملف وحدة systemd لإدارة حاوية محددة. يجب أن يعمل هذا في كلا الوضعين الجذر وغير الجذر للحاويات unrivileged. رأينا حتى طلبًا لإنشاء وقت تشغيل متوافق مع نظام OCI.

استنتاج


تشغيل systemd في حاوية هو حاجة مفهومة. وبفضل Podman ، لدينا أخيرًا بيئة قاذفة حاويات ليست معادية لنظام ، ولكنها تجعلها سهلة الاستخدام.

Source: https://habr.com/ru/post/ar468931/


All Articles