هسته سیستم‌عامل، Namespaces و cgroups در لینوکس

درک عمیق ساختار درونی کانتینرها در لینوکس از طریق بررسی مفاهیم بنیادین Namespaces جهت ایزوله‌سازی دیداری و cgroups برای کنترل منابع سخت‌افزاری.

برای تسلط بر Docker و Kubernetes و عبور از خطاهای پیچیده در محیط‌های عملیاتی (Production)، باید از دیدگاه "کانتینر به عنوان یک جعبه جادویی" فاصله گرفت. در این درس، آناتومی واقعی کانتینرها در سطح سیستم‌عامل شکافته می‌شود. درک عمیق این مفاهیم، توانایی مهندسی شما را در مواجهه با چالش‌های آزمون CKA و سناریوهای واقعی تضمین می‌کند.

۱. تاریخچه و چالش‌ها (The History & The Pain)

در درس پیشین آموختیم که ماشین‌های مجازی (VM) دارای سربار و وزن بالایی هستند. برای رفع این مشکل، مهندسان تصمیم گرفتند نرم‌افزارها را به صورت مستقیم و سبک بر روی یک سرور لینوکسی واحد اجرا کنند. اما این رویکرد به سرعت به چالشی بزرگ تبدیل شد: هرج و مرج و تداخل منابع!

تصور کنید دو برنامه متمایز روی یک سرور نصب شده‌اند. چنانچه برنامه اول به دلیل یک باگ نرم‌افزاری تمامی حافظه (RAM) سرور را اشغال کند، کل سیستم دچار فروپاشی (Crash) شده و برنامه دوم نیز از کار می‌افتد. یا در سناریویی دیگر، هر دو برنامه تلاش کنند تا از درگاه شبکه شماره ۸۰ (Port 80) استفاده نمایند. تداخل (Conflict) در تخصیص پورت باعث می‌شود یکی از برنامه‌ها هرگز راه‌اندازی نشود.

نیاز مبرم به راهکاری بود که بتوان برنامه‌ها را روی یک سرور واحد اجرا کرد، اما آن‌ها را در محیط‌هایی کاملاً ایزوله قرار داد تا نه یکدیگر را ببینند و نه توانایی تصاحب منابع یکدیگر را داشته باشند. در پاسخ به این نیاز، دو قابلیت بنیادین و معجزه‌آسا در هسته لینوکس توسعه یافت: Namespaces و cgroups.

۲. لغت‌نامه تخصصی (Micro-Dictionary)

  • OS Kernel (کرنل / هسته سیستم‌عامل): مغز متفکر و لایه مرکزی سیستم‌عامل (نظیر لینوکس یا ویندوز) که وظیفه مدیریت ارتباط میان نرم‌افزارها و قطعات سخت‌افزاری (مانند CPU و RAM) را بر عهده دارد.
  • Process (پروسس / فرآیند): هر برنامه‌ای که در سیستم‌عامل در حال اجرا است. (به عنوان مثال، باز کردن یک تب در مرورگر، منجر به ایجاد یک Process جدید در سطح سیستم‌عامل می‌شود).
  • Namespaces (فضاهای نام): یک قابلیت امنیتی در کرنل لینوکس که برای یک Process، مرز و توهمی مجازی ایجاد می‌کند تا نتواند سایر Processهای موجود روی سرور را مشاهده کند. این ویژگی مسئول ایزوله‌سازی دیداری و منطقی است.
  • cgroups / Control Groups (گروه‌های کنترلی): قابلیت دیگری در کرنل لینوکس که میزان مصرف منابع سخت‌افزاری (مانند RAM و CPU) را برای یک Process محدود و مدیریت می‌کند. این ویژگی مسئول ایزوله‌سازی فیزیکی منابع است.

۳. مفهوم اصلی و مدل ذهنی (Core Concept & Mental Model)

برای درک نحوه عملکرد سیستم‌عامل، می‌توان سرور لینوکس را به یک هتل بزرگ و برنامه‌های در حال اجرا را به مسافران آن هتل تشبیه کرد:

  • OS Kernel (مدیر هتل): او کنترل کامل بر تمامی اجزا دارد؛ تمامی اتاق‌ها، سیستم‌های برق، لوله‌کشی و تاسیسات را می‌شناسد و مدیریت می‌کند.
  • Namespaces (دیوارهای اتاق): هنگامی که یک مسافر (برنامه) وارد اتاق ۱۰۱ می‌شود، مدیر هتل دیوارهایی پیرامون او بنا کرده و پرده‌ها را می‌بندد. مسافر توانایی دیدن فضای بیرون از اتاق را ندارد و تصور می‌کند که تنها فرد حاضر در کل هتل است! او سیستم‌فایل (File System) و شبکه (Network) کاملاً اختصاصی خود را دارد. Namespaces این توهم را برای برنامه‌ها خلق می‌کنند که کل سرور منحصراً در اختیار آن‌هاست.
  • cgroups (کنتور هوشمند تاسیسات): حال فرض کنید مسافر اتاق ۱۰۱ تصمیم می‌گیرد ۱۰ دستگاه پرمصرف صنعتی را همزمان روشن کند. در یک معماری غیرایزوله، این کار باعث قطع برق کل هتل (Crash کردن سرور) می‌شود. اما مدیر هتل (Kernel) روی مدار اتاق ۱۰۱ یک کنتور هوشمند (cgroup) نصب کرده است. به محض اینکه میزان مصرف مسافر از سقف مجاز فراتر رود، تنها فیوز همان اتاق قطع می‌شود و بقیه بخش‌های هتل بدون مشکل به کار خود ادامه می‌دهند.

راز معماران ابری: چیزی به نام «کانتینر» در ساختار لینوکس وجود خارجی ندارد! کانتینر در حقیقت صرفاً یک Process معمولی لینوکس است که چشمانش توسط Namespaces بسته شده و دستانش توسط cgroups به زنجیر کشیده شده است.

۴. محیط واقعی در برابر آزمون (Exam vs. Reality/GitOps)

  • در آزمون CKA: شما هرگز نیازی به اجرای دستورات پیچیده لینوکس برای ساخت دستی Namespaces یا cgroups نخواهید داشت. موتورهای اجرای کانتینر نظیر containerd یا Docker، تمامی این عملیات را به صورت خودکار در پس‌زمینه (Background) مدیریت می‌کنند.
  • در دنیای واقعی (SRE): در سناریوهای بحرانی و هنگ کردن سرور در محیط Production، شما به عنوان مهندس SRE باید مستقیماً به کرنل لینوکس مراجعه کرده و پیکربندی فایل‌های cgroups را تحلیل کنید تا تشخیص دهید کدام کانتینر در حال تصاحب CPU و ایجاد گلوگاه در سیستم است.

۵. ترفندهای حرفه‌ای و میان‌برها (CKA Time-Saver & Shortcuts)

برای افزایش سرعت و دقت در عیب‌یابی (Troubleshooting)، این قانون طلایی را به خاطر بسپارید:

  • خطاهای مرتبط با شبکه و درگاه‌ها (Ports) عموماً ریشه در Namespaces دارند (کانتینر قادر به دیدن شبکه خارج از ایزوله خود نیست).
  • خطاهای مرتبط با Crash کردن و توقف ناگهانی (به دلیل کمبود حافظه)، همواره ریشه در cgroups دارند (کرنل برای جلوگیری از فروپاشی سرور، کانتینر پرمصرف را متوقف کرده است).

تفکیک این دو مکانیزم در ذهن، سرعت شما را در یافتن ریشه مشکلات (Root Cause) به طرز چشمگیری افزایش می‌دهد.

۶. آزمایشگاه عملی (Hands-on Lab - Micro-Stepped)

برای مشاهده جادوی Namespaces با چشمان خود، این سناریوی ترمینالی را بررسی می‌کنیم:

مرحله اول: روی سرور اصلی (بیرون از کانتینر) لیست تمامی پردازش‌های در حال اجرا را با دستور ps aux دریافت می‌کنیم:

root@server:~# ps aux

خروجی مورد انتظار ترمینال (شامل صدها خط پردازش سیستم):

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 168924 13580 ?        Ss   10:00   0:05 /sbin/init
root       543  0.0  0.0  12345  4567 ?        S    10:01   0:00 /usr/sbin/sshd
mysql      899  2.1  4.5 456789 54321 ?        Sl   10:05   1:23 /usr/sbin/mysqld
... (و صدها پروسس دیگر که در حال اجرا هستند)

مرحله دوم: درون محیط ایزوله کانتینر یک کانتینر اجرا کرده و وارد آن می‌شویم. مجدداً همان دستور ps aux را اجرا می‌کنیم:

root@container:~# ps aux

خروجی مورد انتظار ترمینال (جادوی Namespaces):

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   4520  1200 ?        Ss   11:00   0:00 /bin/sh
root         8  0.0  0.0   2340   800 ?        R+   11:05   0:00 ps aux

تحلیل: داخل کانتینر، برنامه تصور می‌کند که اولین و تنها پردازش موجود در کل سیستم است (با شناسه PID 1). این محیط کاملاً کور است؛ نه سیستم‌عامل سرور اصلی را می‌بیند و نه نرم‌افزارهای دیگری مانند MySQL را. این دقیقاً تجلی قدرت ایزوله‌سازی دیداری توسط Namespaces است.

۷. پرسش‌های متداول و رفع ابهام (Beginner FAQ & Myth-busting)

  • پرسش ۱: آیا کانتینر یک نوع ماشین مجازی (VM) بسیار کوچک و فشرده است؟

    پاسخ: به هیچ وجه! این یکی از بزرگترین تصورات اشتباه در دنیای زیرساخت است. ماشین‌های مجازی یک لایه کامل از سخت‌افزار مجازی (Hypervisor) ایجاد می‌کنند. اما کانتینر صرفاً یک Process معمولی در سطح سیستم‌عامل است که کرنل لینوکس (توسط Namespaces) به آن دروغ گفته و محیط را برای آن ایزوله کرده است.

  • پرسش ۲: اگر کانتینرها از هسته سیستم‌عامل (Kernel) سرور اصلی استفاده می‌کنند، آیا می‌توان یک کانتینر ویندوزی را روی سرور لینوکسی اجرا کرد؟

    پاسخ: هرگز! (این دقیقاً منطق کارآگاهی پاسخ چالش درس قبل بود). از آنجا که کانتینر فاقد سیستم‌عامل داخلی است، برای ترجمه دستورات سخت‌افزاری باید مستقیماً با هسته سرور میزبان مکالمه کند. یک نرم‌افزار توسعه‌یافته برای معماری ویندوز، زبان کرنل لینوکس را نمی‌فهمد. قانون کلی: کانتینرهای لینوکسی منحصراً روی سرور لینوکس، و کانتینرهای ویندوزی روی سرور ویندوز قابل اجرا هستند.

۸. هشدارهای سطح عملیاتی (Production Warning - SRE Perspective)

بمب ساعتی منابع نامحدود (No Limits Risk): در محیط‌های Kubernetes و Docker، چنانچه یک کانتینر را مستقر کنید و برای آن محدودیت‌های cgroups (نظیر سقف مصرف RAM و CPU) تعریف ننمایید، آن کانتینر به صورت پیش‌فرض مجاز است تا ۱۰۰٪ منابع کل سرور را مصرف کند. به عنوان یک مهندس SRE، هرگز اجازه ندهید کانتینری بدون پیکربندی پارامترهای Requests و Limits وارد محیط عملیاتی (Production) شود. یک برنامه دارای نشست حافظه (Memory Leak) می‌تواند به سرعت منجر به خطای بحرانی Kernel Panic و خاموشی فاجعه‌بار کل نودهای دیتاسنتر گردد.

۹. چالش آشوب (The "Chaos" Challenge)

سناریوی بحران: در ساعت ۳ بامداد، سیستم مانیتورینگ سازمان آلارم قطعی سرور حیاتی فروشگاه را ارسال می‌کند. با ورود به سرور، متوجه می‌شوید که کانتینر مربوط به برنامه Java به طور ناگهانی متوقف و بسته شده است.

با بررسی مستقیم لاگ‌های هسته سیستم‌عامل (دستور dmesg)، با خطوط زیر مواجه می‌شوید:

[ 15432.123456] java invoked oom-killer: gfp_mask=0x100cca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=999
[ 15432.123490] Task in /docker/9a3b...c4f killed as a result of limit of /docker/9a3b...c4f
[ 15432.123505] memory: usage 512000kB, limit 512000kB, failcnt 320
[ 15432.123610] Memory cgroup out of memory: Killed process 18742 (java) total-vm:2048560kB, anon-rss:511996kB

❓ ماموریت شما: با توجه به لاگ کرنل فوق و مفاهیم آموخته شده در این درس، تحقیق کنید که دقیقاً چه مکانیزمی در هسته لینوکس مسئول متوقف کردن (Kill) این کانتینر بوده است و علت ریشه‌ای این رویداد را به زبان ساده تحلیل نمایید.