تُعَد الحاويات Containers من التطبيقات الثورية المعاصرة، إذ أنك ستستخدمها بغضّ النظر عن البرنامج الذي تعمل عليه سواءً كان كوبيرنيتيس Kubernetes، أو دوكر Docker، أو نظام كور CoreOS، أو سيلفربلو Sliverblue، أو فلاتباك Flatpak؛ إذ تستخدم جميع البرامج المذكورة سابقًا الحاويات بصورةٍ أساسية بفضل سهولة التعامل معها وأمانها العالي وقابليّة توسعتها.
قد تكون الحاويات صعبة الفهم للبعض، فما الذي نعنيه عندما نقول أنّ النظام يعمل بداخل حاوية؟ وكيفَ لعمليّة محتواة داخل حاوية ما أن تتفاعل مع بقيّة أجزاء الجهاز المضيف الذي تعمل عليه؟ لا أحد يحبّ الغموض، لذا سنشرح في هذه المقالة تقنية عمل الحاويات.
مجالات الأسماء
تُعَد مجالات الاسماء Namespaces من أكثر المصطلحات شيوعًا في عالم البرمجة؛ وإذا كنتَ مبرمجًا، فعلى الأغلب أنك رأيت سطرًا برمجيًّا مشابهًا لهذا:
;using namespace std
أو لربّما رأيت هذا السطر ضمن ملف XML:
<book xmlns="http://docbook.org/ns/docbook" xml:lang="en">
يوفر هذا النوع من الأسطر البرمجية توصيفًا لسياق الأوامر الموجودة في ملف الشيفرة المصدرية التي تليه؛ فعلى سبيل المثال، السبب الوحيد في كون الكلمة المفتاحية cout
ذات معنى للغة ++C
، هو وجود مجال اسم يصف عملها.
إذا كان الشرح السابق يستخدم كثيرًا من المصطلحات التقنية ولم تفهمه، دعنا نسقط الأمر على الحياة الواقعية؛ فنحن نستخدم مجالات الاسم أيضًا في حياتنا اليومية، صحيح نحن لا ندعوها باسمها بالطبع، ولكننا نستخدم المفهوم طوال الوقت؛ فإذا قلت مثلًا، "أنا من أكبر معجبي هذه السلسلة"، فقد تقصد سلسلة شركات أو محال تجاريّة معيّنة في سياق مجال الأعمال، أو سلسلة أفلام شهيرة في سياق السينما؛ كما قد تعني الجملة "على أيّ محرك يعمل هذا الشيء؟" شيئًا ما بداخل ورشة الميكانيكي، وشيئًا آخر في مجال تطوير الويب. نحن بالطبع لا نحدّد السياق خلال محادثتنا مع بعضنا بعضًا، إذ إنّ أدمغتنا ذكيةً كفاية لمعرفة السياق لوحدها، بينما نحتاج لإعلان مجال الاسم وتحديده عندما نتعامل مع الحواسيب.
بالنسبة للحاويات، يصف مجال الاسم الحدود التي تستطيع الحاوية "رؤية" العمليات التي تجري بداخلها.
أمر lsns
لا يعي البعض هذا الأمر، ولكن يعمل نظام لينكس على إدارة العديد من مجالات الاسم المخصصة لإنجاز مختلف العمليات. وتستطيع الاطلاع على مجالات الاسم الموجودة على نظامك باستخدام آخر إصدارات حزمة util-linux
:
lsns $ NS TYPE NPROCS PID USER COMMAND 4026531835 cgroup 85 1571 seth /usr/lib/systemd/systemd --user 4026531836 pid 85 1571 seth /usr/lib/systemd/systemd --user 4026531837 user 80 1571 seth /usr/lib/systemd/systemd --user 4026532601 user 1 6266 seth /usr/lib64/firefox/firefox [...] 4026532928 net 1 7164 seth /usr/lib64/firefox/firefox [...] [...]
إذا لم يحتوي إصدار الحزمة util-linux
على أمر lsns
، فيمكنك رؤية سجل مجالات الاسم ضمن المسار proc/
:
ls /proc/*/ns $ 1571 6266 7164 [...] ls /proc/6266/ns $ [...] ipc net pid user uts
يجري عدُّ كل عملية Process في نظام لينكس برقمٍ تسلسلي يُدعى معرّف العملية process ID -أو اختصارًا PID-، ويرتبط كل PID بمجال اسمٍ معيّن. ويمكن لمعرّفات PIDs التي تحمل مجال الاسم نفسه الوصول لبعضها بعضًا، نظرًا لأنها مبرمجة ضمن مجال الاسم نفسه؛ بينما لا تستطيع العمليات التي تنتمي لمجالات أسماء مختلفة التفاعل والتواصل مع بعضها بعضًا بصورةٍ اعتيادية، لأنها تعمل ضمن سياقات مختلفة، أي مجالات اسم مختلفة؛ وهذا هو السبب في كون عمليات التي تعمل ضمن حاوية ما غير قادرةٍ على الوصول للمعلومات الموجودة خارج الحاوية، أو المعلومات الموجودة ضمن حاويةٍ أخرى مختلفة.
إنشاء مجال اسم جديد
تقدّم أي برمجيةٍ تتعامل مع الحاويات إدارةً تلقائية لمجالات الاسم في الحالة الاعتيادية؛ فعندما ينشئ المستخدم تطبيقًا أو بيئةً محتواةً بداخل حاويةٍ ما، عندها لا يلزم عليه استخدام الأمر lsns
لتفقّد مجالات الاسم الموجودة وإنشاء مجال جديد يدويًّا، إذ تتولّى هذه البرمجيات المهمّة المذكورة تلقائيًّا بالاعتماد على مجالات اسم كل عمليّة PID، وبمساعدة نواة لينكس؛ إلّا أنّه من الممكن محاكاة هذه المهمة يدويًّا للحصول على فهم أفضل لكيفية عملها، وما الذي يحصل خلف الكواليس.
أولًا، عليك تعريف عملية لا تعمل حاليًّا على جهازك، وفي هذا المثال، سنستخدم صدفة Z -أو اختصارًا Zsh-، لأنّ الجهاز الحالي الذي نعمل عليه يستخدم Bash
؛ فإذا كان جهازك يعمل على Zsh
، فبإمكانك استخدام Bash
، أو tcsh
، أو أيّ صدفة Shell غير فعالة حاليًّا.
يُعَد هدفنا هنا هو إثبات أنّ الصدفة المُختارة (العملية) غير فعالة، إذ يمكننا التحقق من ذلك عن طريق استخدام الأمر pidof
، الذي يطلب من النظام العثور على PID لأي تطبيق تكتبه بعد الأمر:
pidof zsh $
sudo pidof zsh $
إذا لم يُعِد هذا الأمر أيّ رقم PID بالنتيجة، فهذا يعني أن التطبيق المُدخل غير فعال.
أمر unshare
يشغّل الأمر unshare
أي تطبيق ضمن مجال اسم غير مشترك مع عمليات الأصل، وهناك الكثير من أنواع مجالات الاسم المختلفة التي يتيحها هذا الأمر. وبإمكانك الاطلاع على صفحة الدليل man
للتعرف على الخيارات المتاحة.
لإنشاء مجال اسم جديد خاص بالأمر الذي ستجرّبه:
sudo unshare --fork --pid --mount-proc zsh $ %
ستعمل صدفة Zsh
في مجال اسمها عند التشغيل تلقائيًا، وذلك بحكم أنها صدفةٌ تفاعلية. ولكن مع ذلك، لا ينطبق هذا الأمر على جميع العمليات؛ إذ تعمل بعضها في الخلفية تاركةً إياك في واجهة ضمن مجال اسمها الأصلي. يمكنك ملاحظة أنك تركت مجال الاسم المعتاد بالنظر إلى المعرّف PID الخاص بعمليتك الفرعية الجديدة، وذلك طالما بقيت في جلسة Zsh
نفسها:
pidof zsh % pid 1
إذا كنت تعرف ولو الشيء اليسير عن أرقام عمليات لينكس التعريفية، فأنت تعلم أن PID ذو القيمة 1 محجوزٌ دائمًا؛ وذلك بسبب طبيعة عملية بدء تشغيل النظام boot (تطبيق systemd
على معظم التوزيعات عدا سلاك وير Slackware وديفوان Devuan وبعض الحزم المخصّصة من توزيعة آرش Arch)، إذ من المستحيل أن تكون قيمة PID الخاصة بـ Zsh
أو أي تطبيق آخر لا ينتمي لمجموعة تطبيقات بدء تشغيل النظام مساويةً 1، فمن غير الممكن لحاسوبك أن يعمل ويشغل النظام دون وجود عمليّة إقلاع تبدأه، وعلى الرغم من ذلك، تعرض لك الصدفة Zsh
أن قيمة العملية بها تشغل القيمة 1.
بغض النظر عن المعلومة التي تخبرك بها الصدفة، فالقيمة 1 لم تُستبدل، وتستطيع التأكد من ذلك عن طريق فتح نافذة طرفية جديدة والبحث عن العملية ذات القيمة 1، على النحو التالي:
$ ps 1 init
تستطيع البحث عن قيمة PID الخاصة بالصدفة Zsh
عن طريق:
pidof zsh $ 7723
كما تلاحظ من الأوامر السابقة، يعي نظامك المضيف ما الذي يجري، ويعرف أن قيمة PID للصدفة Zsh
ليست 1 (لن تكون نتيجة الأمر 7723 إن جرّبتها، وإذا ساوتها فسيكون ذلك وليد الصُدفة). تعتقد الصدفة Zsh
أن رقم عمليّتها PID هو 1 بسبب نطاقها Scope المغلق أو المحتوى بداخل مجال الاسم، وبمجرّد إنشاء عملياتٍ فرعية في مجال الاسم هذا، فستبدأ أرقام عمليّاتها بدءًا من الواحد، ولكن في سياق مجال الاسم وحده.
تُعَد مجالات الاسم بالإضافة لتقنيات أخرى مثل cgroups
وغيرها، أساسًا لمفهوم الحاويات. يساعد فهم فكرة أن مجالات الاسم الفرعية موجودةً داخل سياق مجالات الاسم العامة ضمن بيئة المضيف (يُمثَّل المضيف بالحاسوب في أمثلتنا السابقة، ولكن في التطبيقات الواقعية قد يكون خادمًا أو سحابة هجينة Hybird cloud)، في فهم كيف ولماذا تعمل برامج الحاويات على النحو الذي تعمل به، إذ لا "تعلم" حاوية تشغِّل مدونة ووردبريس Wordpress مثلًا، أنها تعمل ضمن حاوية، بل تعلم أن لها وصولًا لنواة النظام Kernel وقِسمًا من الذاكرة العشوائيّة RAM، بالإضافة لأيٍّ من ملفات الإعدادات Configuration التي زوّدتها؛ لكنها لا تستطيع الوصول إلى المسار الرئيسي Home أو أي مسارات لم تعطها الإذن للوصول إليها. إضافةًً لذلك، لا يمكن للعمليات التي تعمل داخل سياق المدوّنة التأثير على أيٍّ من العمليات الأخرى الموجودة بداخل النظام، وذلك لعدم شمول مجموعة أرقام العمليات -على حدّ علمها- أي عملية قبل 1؛ و1 هي الحاوية التي تعمل بداخلها.
تُعَد الحاويات ميزةً قويةً في نظام لينكس، وتتزايد شهرةً يومًا بعد يوم. والآن بما أنك تعلمت كيف تعمل هذه التقنية، جرّب التعامل معها باستخدام بعض الأنظمة المخصصة، مثل كوبيرنيتيس Kubernetes، أو سيلفربلو Silverblue، أو فلاتباك Flatpak، واكتشف بعضًا من إمكانياتها. تعمل الحاويات في نهاية المطاف مثل نظام لينكس، لذا طبّق ما تعرفه عن لينكس وكيفية تثبيته باستخدامها.
ترجمة -وبتصرف- للمقال Demystifying namespaces and containers in Linux لصاحبه Seth Kenlon.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.