ساخت کانتینر داکری از صفر با ابزارهای لینوکس
خلاصهٔ کاملتر
وقتی دستور docker run nginx میزنی، Nginx توی یه محیط Debian اجرا میشه، حتی اگه هاست لینوکس دیگهای داشته باشه. این جادو چطور کار میکنه؟ جواب کوتاهه: mount namespace. این مقاله با ابزارهای خالص لینوکس — بدون هیچ رانتایمی — یه کانتینر واقعی میسازه تا مکانیزم زیرش رو نشون بده.
mount namespace چی رو ایزوله میکنه؟ یه باور اشتباه رایجه که فکر میکنیم mount namespace کل فایلسیستم رو ایزوله میکنه. اما اینطور نیست؛ اون فقط جدول mount (mount table) رو ایزوله میکنه. یعنی فایلهای روی دیسک بین namespaceها مشترکان، ولی اینکه کدام فایلسیستم کجا mount شده، برای هر namespace جداگانهست. با دستور unshare --mount bash میشه یه shell توی namespace جدید باز کرد و دید که mount جدیدی که اونجا ایجاد میشه، روی هاست دیده نمیشه.
یه نکته مهم اینه که mount namespace بهتنهایی کافی نیست — باید mount propagation (نوع انتشار رویدادهای mount) رو هم مدیریت کرد. وقتی مستقیماً از system call پایه استفاده بشه، mount جدید ممکنه به namespace اصلی هم منتشر بشه. ابزار خطفرمان unshare این مشکل رو خودش حل میکنه؛ بعد از ساختن namespace جدید، یه system call اضافه میزنه:
unshare(CLONE_NEWNS) = 0
mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL) = 0
execve("/usr/bin/bash", ["bash"], ...) = 0
این دستور root mount و تمام sub-mountهاش رو به حالت private میبره؛ یعنی هیچ رویداد mountی بین namespace جدید و هاست رد و بدل نمیشه. سه حالت اصلی وجود داره: private (کاملاً ایزوله)، shared (رویدادها در هر دو طرف منتشر میشن)، و slave (رویدادها فقط از هاست به namespace جدید میرسن).
برای ساختن یه کانتینر واقعی، علاوه بر mount namespace، به یه rootfs هم نیاز داریم — یه پوشه روی هاست که فایلسیستم داخل کانتینر ازش ساخته میشه. میشه filesystem Alpine رو extract کرد و به عنوان rootfs استفاده کرد. بعد با pivot_root (جایگزین مدرن chroot) میشه root فایلسیستم پروسه رو به این پوشه تغییر داد و کانتینر رو واقعاً ایزوله کرد.
namespaceهای دیگه مثل PID، UTS، cgroup و network مکمل هستن، نه پایه. mount namespace اساس ایزولهسازی فایلسیستم کانتینره و بقیه روی همین پایه اضافه میشن. درک این معماری، مفاهیمی مثل bind mount، volume و persistence در داکر و کوبرنتیز رو خیلی ملموستر میکنه.
نکات کلیدی:
- mount namespace فقط جدول mount رو ایزوله میکنه، نه کل فایلسیستم را
- mount propagation تعیین میکنه رویدادهای mount بین namespaceها منتشر بشن یا نه
- ابزار unshare بعد از ساخت namespace جدید، root mount رو بهطور خودکار private میکنه
- pivot_root جایگزین مدرن chroot است و اکثر container runtimeها ازش استفاده میکنن
- namespaceهای PID، UTS، cgroup و network نقش مکملی دارن، نه بنیادی




