قلق الانفصال: برنامج تعليمي لعزل نظامك باستخدام مساحات أسماء Linux

نشرت: 2022-03-11

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

تعتمد هذه الأدوات على عدد من ميزات ومكونات Linux kernel. تم تقديم بعض هذه الميزات مؤخرًا إلى حد ما ، بينما لا يزال البعض الآخر يتطلب منك تصحيح النواة نفسها. لكن أحد المكونات الرئيسية ، باستخدام مساحات أسماء Linux ، كان إحدى ميزات Linux منذ إصدار الإصدار 2.6.24 في عام 2008.

أي شخص على دراية بـ chroot لديه بالفعل فكرة أساسية عما يمكن أن تفعله مساحات أسماء Linux وكيفية استخدام مساحة الاسم بشكل عام. تمامًا كما يسمح chroot للعمليات برؤية أي دليل عشوائي باعتباره جذر النظام (بغض النظر عن بقية العمليات) ، فإن مساحات أسماء Linux تسمح أيضًا بتعديل جوانب أخرى من نظام التشغيل بشكل مستقل. يتضمن ذلك شجرة العملية وواجهات الشبكات ونقاط التحميل وموارد الاتصال بين العمليات والمزيد.

لماذا استخدام مساحات الأسماء لعزل العملية؟

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

على سبيل المثال ، باستخدام مسافة الأسماء ، من الممكن تنفيذ برامج عشوائية أو غير معروفة بأمان على الخادم الخاص بك. في الآونة الأخيرة ، كان هناك عدد متزايد من مسابقات البرمجة ومنصات "hackathon" ، مثل HackerRank و TopCoder و Codeforces وغيرها الكثير. يستخدم الكثير منهم خطوط الأنابيب الآلية لتشغيل والتحقق من صحة البرامج التي يقدمها المتسابقون. غالبًا ما يكون من المستحيل معرفة الطبيعة الحقيقية لبرامج المتسابقين مسبقًا ، وقد يحتوي بعضها على عناصر خبيثة. من خلال تشغيل هذه البرامج في عزلة تامة عن باقي النظام ، يمكن اختبار البرنامج والتحقق من صحته دون تعريض بقية الجهاز للخطر. وبالمثل ، فإن خدمات التكامل المستمر عبر الإنترنت ، مثل Drone.io ، تجلب تلقائيًا مستودع الأكواد الخاص بك وتقوم بتنفيذ البرامج النصية للاختبار على الخوادم الخاصة بها. مرة أخرى ، عزل مساحة الاسم هو ما يجعل من الممكن تقديم هذه الخدمات بأمان.

تتيح أدوات تباعد الأسماء مثل Docker أيضًا تحكمًا أفضل في استخدام العمليات لموارد النظام ، مما يجعل هذه الأدوات شائعة الاستخدام من قِبل موفري PaaS. تستخدم خدمات مثل Heroku و Google App Engine مثل هذه الأدوات لعزل وتشغيل تطبيقات خادم ويب متعددة على نفس الجهاز الحقيقي. تسمح لهم هذه الأدوات بتشغيل كل تطبيق (والذي ربما تم نشره من قبل أي عدد من المستخدمين المختلفين) دون القلق بشأن استخدام أحدهم لموارد النظام الكثيرة للغاية ، أو التدخل و / أو التعارض مع الخدمات المنشورة الأخرى على نفس الجهاز. مع عزل العملية هذا ، من الممكن أن يكون لديك أكوام مختلفة تمامًا من برامج التبعية (والإصدارات) لكل بيئة معزولة!

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

مساحة اسم العملية

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

مع إدخال مساحات أسماء Linux ، أصبح من الممكن وجود العديد من أشجار العمليات "المتداخلة". يمكن أن تحتوي كل شجرة عملية على مجموعة عمليات منفصلة تمامًا. يمكن أن يضمن ذلك أن العمليات التي تنتمي إلى شجرة معالجة واحدة لا يمكنها فحص أو قتل - في الواقع لا يمكن حتى معرفة وجود - العمليات في الأخوة الأخرى أو أشجار المعالجة الأم.

في كل مرة يتم فيها تمهيد الكمبيوتر الذي يعمل بنظام Linux ، يبدأ بعملية واحدة فقط ، مع معرف العملية (PID) 1. هذه العملية هي جذر شجرة العملية ، وهي تبدأ بقية النظام عن طريق إجراء أعمال الصيانة المناسبة والبدء الشياطين / الخدمات الصحيحة. تبدأ جميع العمليات الأخرى أسفل هذه العملية في الشجرة. تسمح مساحة الاسم PID للفرد بالانفصال عن شجرة جديدة ، مع عملية PID 1 الخاصة بها. تظل العملية التي تقوم بذلك في مساحة الاسم الأصل ، في الشجرة الأصلية ، ولكنها تجعل الطفل جذر شجرة العملية الخاصة به.

مع عزل مساحة الاسم PID ، فإن العمليات في مساحة الاسم الفرعية ليس لديها طريقة لمعرفة وجود العملية الأصل. ومع ذلك ، فإن العمليات في مساحة الاسم الأصل لديها عرض كامل للعمليات في مساحة الاسم الفرعية ، كما لو كانت أي عملية أخرى في مساحة الاسم الأصل.

يوضح هذا البرنامج التعليمي لمساحة الاسم الفصل بين العديد من أشجار العمليات باستخدام أنظمة مساحة الاسم في Linux.

من الممكن إنشاء مجموعة متداخلة من مساحات الأسماء الفرعية: تبدأ إحدى العمليات عملية فرعية في مساحة اسم PID جديدة ، وتولد هذه العملية الفرعية عملية أخرى في مساحة اسم PID جديدة ، وهكذا.

مع إدخال مساحات أسماء PID ، يمكن أن يكون لعملية واحدة الآن عدة معرفات PID مرتبطة بها ، واحدة لكل مساحة اسم تندرج تحتها. في كود مصدر Linux ، يمكننا أن نرى أن البنية المسماة pid ، والتي تستخدم لتتبع PID واحد فقط ، تتعقب الآن PIDs متعددة من خلال استخدام بنية تسمى upid :

 struct upid { int nr; // the PID value struct pid_namespace *ns; // namespace where this PID is relevant // ... }; struct pid { // ... int level; // number of upids struct upid numbers[0]; // array of upids };

لإنشاء مساحة اسم PID جديدة ، يجب على المرء استدعاء استدعاء نظام clone() بعلامة خاصة CLONE_NEWPID . (يوفر C غلافًا لفضح استدعاء النظام هذا ، وكذلك يفعل العديد من اللغات الشائعة الأخرى.) في حين يمكن أيضًا إنشاء مساحات الأسماء الأخرى التي تمت مناقشتها أدناه باستخدام استدعاء نظام unshare() ، لا يمكن إنشاء مساحة اسم PID إلا في وقت جديد يتم إنتاج العملية باستخدام clone() . بمجرد استدعاء clone() بهذه العلامة ، تبدأ العملية الجديدة على الفور في مساحة اسم PID جديدة ، ضمن شجرة عملية جديدة. يمكن إثبات ذلك باستخدام برنامج C بسيط:

 #define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <unistd.h> static char child_stack[1048576]; static int child_fn() { printf("PID: %ld\n", (long)getpid()); return 0; } int main() { pid_t child_pid = clone(child_fn, child_stack+1048576, CLONE_NEWPID | SIGCHLD, NULL); printf("clone() = %ld\n", (long)child_pid); waitpid(child_pid, NULL, 0); return 0; }

قم بترجمة وتشغيل هذا البرنامج بامتيازات الجذر وستلاحظ ناتجًا مشابهًا لهذا:

 clone() = 5304 PID: 1

سيكون PID ، كما طُبع من داخل child_fn ، هو 1 .

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

حاول استبدال وظيفة static int child_fn() بما يلي ، لطباعة PID الأصل من منظور العملية المعزولة:

 static int child_fn() { printf("Parent PID: %ld\n", (long)getppid()); return 0; }

ينتج عن تشغيل البرنامج هذه المرة المخرجات التالية:

 clone() = 11449 Parent PID: 0

لاحظ كيف أن PID الأصل من منظور العملية المعزولة هو 0 ، مما يشير إلى عدم وجود أصل. حاول تشغيل نفس البرنامج مرة أخرى ، ولكن هذه المرة ، قم بإزالة علامة CLONE_NEWPID من داخل استدعاء وظيفة clone() :

 pid_t child_pid = clone(child_fn, child_stack+1048576, SIGCHLD, NULL);

هذه المرة ، ستلاحظ أن معرف المريض الرئيسي لم يعد 0:

 clone() = 11561 Parent PID: 11560

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

مساحة اسم شبكة Linux

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

يتضمن عزل عملية في مساحة اسم الشبكة الخاصة بها تقديم إشارة أخرى إلى استدعاء دالة clone() : CLONE_NEWNET ؛

 #define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <unistd.h> static char child_stack[1048576]; static int child_fn() { printf("New `net` Namespace:\n"); system("ip link"); printf("\n\n"); return 0; } int main() { printf("Original `net` Namespace:\n"); system("ip link"); printf("\n\n"); pid_t child_pid = clone(child_fn, child_stack+1048576, CLONE_NEWPID | CLONE_NEWNET | SIGCHLD, NULL); waitpid(child_pid, NULL, 0); return 0; }

انتاج:

 Original `net` Namespace: 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:24:8c:a1:ac:e7 brd ff:ff:ff:ff:ff:ff New `net` Namespace: 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

ماذا يجري هنا؟ ينتمي جهاز ethernet المادي enp4s0 إلى مساحة اسم الشبكة العالمية ، كما هو موضح بواسطة أداة "ip" التي يتم تشغيلها من مساحة الاسم هذه. ومع ذلك ، لا تتوفر الواجهة الفعلية في مساحة اسم الشبكة الجديدة. علاوة على ذلك ، يكون جهاز الاسترجاع نشطًا في مساحة اسم الشبكة الأصلية ، ولكنه "معطل" في مساحة اسم الشبكة الفرعية.

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

تتكون مساحة اسم شبكة Linux من عملية توجيه إلى مساحات أسماء شبكات فرعية متعددة.

للقيام بذلك يدويًا ، يمكنك إنشاء زوج من اتصالات Ethernet الافتراضية بين أحد الوالدين ومساحة الاسم الفرعية عن طريق تشغيل أمر واحد من مساحة الاسم الأصل:

 ip link add name veth0 type veth peer name veth1 netns <pid>

هنا ، يجب استبدال <pid> بمعرف العملية للعملية في مساحة الاسم الفرعية كما لاحظها الأصل. يؤدي تشغيل هذا الأمر إلى إنشاء اتصال يشبه توجيه الإخراج بين مساحتي الأسماء هذين. تحتفظ مساحة الاسم الأصل بجهاز veth0 ، وتمرر جهاز veth1 إلى مساحة الاسم الفرعية. أي شيء يدخل في إحدى النهايات ، يخرج من الطرف الآخر ، تمامًا كما تتوقع من اتصال Ethernet حقيقي بين عقدتين حقيقيتين. وفقًا لذلك ، يجب تعيين عناوين IP لكلا جانبي اتصال Ethernet الظاهري.

جبل Namespace

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

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

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

علامة clone() المطلوبة لتحقيق ذلك هي CLONE_NEWNS :

 clone(child_fn, child_stack+1048576, CLONE_NEWPID | CLONE_NEWNET | CLONE_NEWNS | SIGCHLD, NULL)

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

ومن المثير للاهتمام أن هذا في الواقع يجعل إنتاج العملية الفرعية المستهدفة مباشرة باستخدام علامة CLONE_NEWNS فكرة سيئة. تتمثل الطريقة الأفضل في بدء عملية "init" خاصة CLONE_NEWNS ، اجعل عملية "init" تغير "/" أو "/ proc" أو "/ dev" أو نقاط تحميل أخرى حسب الرغبة ، ثم ابدأ العملية المستهدفة . تمت مناقشة هذا بمزيد من التفاصيل بالقرب من نهاية البرنامج التعليمي لمساحة الاسم هذا.

مساحات الأسماء الأخرى

هناك مساحات أسماء أخرى يمكن عزل هذه العمليات فيها ، مثل المستخدم و IPC و UTS. تسمح مساحة اسم المستخدم للعملية بالحصول على امتيازات الجذر داخل مساحة الاسم ، دون منحها هذا الوصول إلى العمليات خارج مساحة الاسم. يمنح عزل عملية بواسطة مساحة اسم IPC موارد الاتصال بين العمليات الخاصة بها ، على سبيل المثال ، رسائل System V IPC و POSIX. تعزل مساحة الاسم UTS معرّفين محددين للنظام: nodename و domainname .

فيما يلي مثال سريع يوضح كيفية عزل مساحة اسم UTS:

 #define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <sys/utsname.h> #include <sys/wait.h> #include <unistd.h> static char child_stack[1048576]; static void print_nodename() { struct utsname utsname; uname(&utsname); printf("%s\n", utsname.nodename); } static int child_fn() { printf("New UTS namespace nodename: "); print_nodename(); printf("Changing nodename inside new UTS namespace\n"); sethostname("GLaDOS", 6); printf("New UTS namespace nodename: "); print_nodename(); return 0; } int main() { printf("Original UTS namespace nodename: "); print_nodename(); pid_t child_pid = clone(child_fn, child_stack+1048576, CLONE_NEWUTS | SIGCHLD, NULL); sleep(1); printf("Original UTS namespace nodename: "); print_nodename(); waitpid(child_pid, NULL, 0); return 0; }

ينتج عن هذا البرنامج المخرجات التالية:

 Original UTS namespace nodename: XT New UTS namespace nodename: XT Changing nodename inside new UTS namespace New UTS namespace nodename: GLaDOS Original UTS namespace nodename: XT

هنا ، child_fn() بطباعة اسم nodename وتغييره إلى شيء آخر ثم طباعته مرة أخرى. بطبيعة الحال ، يحدث التغيير فقط داخل مساحة اسم UTS الجديدة.

يمكن العثور على مزيد من المعلومات حول ما توفره جميع مساحات الأسماء وعزلها في البرنامج التعليمي هنا

الاتصال عبر مساحة الأسماء

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

يمكن لعملية "init" إنشاء قناة اتصال بين مساحة الاسم الأصل ومساحة الاسم الفرعية. يمكن أن تستند هذه القناة على مآخذ UNIX أو حتى يمكن استخدام TCP. لإنشاء مقبس UNIX يمتد على مساحتي تحميل مختلفتين ، تحتاج أولاً إلى إنشاء العملية الفرعية ، ثم إنشاء مقبس UNIX ، ثم عزل الطفل في مساحة اسم تحميل منفصلة. ولكن كيف يمكننا إنشاء العملية أولاً ، ثم عزلها لاحقًا؟ يوفر Linux unshare() . يسمح استدعاء النظام الخاص هذا لعملية عزل نفسها عن مساحة الاسم الأصلية ، بدلاً من جعل الوالد يعزل الطفل في المقام الأول. على سبيل المثال ، الكود التالي له نفس التأثير تمامًا مثل الكود المذكور سابقًا في قسم مساحة اسم الشبكة:

 #define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <unistd.h> static char child_stack[1048576]; static int child_fn() { // calling unshare() from inside the init process lets you create a new namespace after a new process has been spawned unshare(CLONE_NEWNET); printf("New `net` Namespace:\n"); system("ip link"); printf("\n\n"); return 0; } int main() { printf("Original `net` Namespace:\n"); system("ip link"); printf("\n\n"); pid_t child_pid = clone(child_fn, child_stack+1048576, CLONE_NEWPID | SIGCHLD, NULL); waitpid(child_pid, NULL, 0); return 0; }

ونظرًا لأن عملية "init" شيء ابتكرته ، يمكنك جعلها تقوم بكل الأعمال الضرورية أولاً ، ثم عزل نفسها عن بقية النظام قبل تنفيذ الطفل المستهدف.

خاتمة

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

هناك الكثير مما يجري تحت غطاء المحرك أكثر مما غطيته في هذه المقالة ، وهناك المزيد من الطرق التي قد ترغب في تقييد العمليات المستهدفة بها لمزيد من الأمان والعزلة. ولكن ، نأمل أن يكون هذا بمثابة نقطة انطلاق مفيدة لشخص مهتم بمعرفة المزيد حول كيفية عمل عزل مساحة الاسم مع Linux حقًا.