۱-۱ تعریف پروژه
این پروژه با هدف طراحی یک آزمایشگاه GPU دانشگاهی برای پشتیبانی از فعالیتهای آموزشی و پژوهشی در حوزه یادگیری ماشین و یادگیری عمیق تعریف شده است؛ بهگونهای که کاربران بتوانند بدون نیاز به درگیری مستقیم با لایه زیرساخت، به محیطهای محاسباتی تعاملی مجهز به GPU دسترسی پیدا کنند.
پلتفرمهای یادگیری ماشین و هوش مصنوعی طی سالهای اخیر به مؤلفهای حیاتی در زیرساختهای فناوری بدل شدهاند. این پلتفرمها محیطی یکپارچه برای توسعه، آزمون و استقرار مدلهای یادگیری ماشین فراهم میکنند، اما استقرار چنین سامانههایی معمولاً با چالشهای جدی در مدیریت منابع، امنیت و مقیاسپذیری همراه است.
پروژه حاضر به طراحی و پیادهسازی یک پلتفرم Cloud-Native مبتنی بر Kubernetes اختصاص دارد. هدف آن ایجاد محیطی ایزوله و ایمن برای تیمهای متعدد است تا بدون نیاز به دانش عمیق زیرساختی بتوانند روی پروژههای خود کار کنند. معماری پیشنهادی با اتکا به الگوهای Multi-Tenancy و GitOps، هم امنیت را تقویت میکند و هم فرآیندهای استقرار را بهصورت قابل اتکا خودکار میسازد.
ساختار سامانه بهصورت لایهای طراحی شده است: لایه مجازیسازی با Proxmox، لایه ارکستراسیون کانتینری با Kubernetes، لایه مدیریت هویت با Keycloak و لایه ارائه سرویس با JupyterHub. این تفکیک لایهای موجب جداسازی دغدغهها و کنترل بهتر پیچیدگی میشود. در حوزه پردازش گرافیکی نیز با بهرهگیری از GPU Passthrough و NVIDIA GPU Operator، دسترسی مستقیم و مدیریتشده به GPU برای بارهای کاری یادگیری عمیق فراهم شده است.
۱-۲ ریسکهای امنیتی و مدیریتی در مدل فعلی
در رویکردهای سنتی، زیرساخت یادگیری ماشین معمولاً بر پایه تخصیص ماشینهای مجازی مستقل به تیمها یا افراد بنا میشود. این مدل محدودیتهای جدی امنیتی و مدیریتی دارد و در نهایت بهرهوری را کاهش میدهد.
از منظر امنیت، فقدان جداسازی منطقی میان محیطها احتمال دسترسی غیرمجاز به دادهها و منابع را افزایش میدهد؛ بسته به سطح ایزولاسیون شبکه و Virtualization، به خطر افتادن یک VM میتواند سایر بخشهای زیرساخت را نیز تحت تأثیر قرار دهد. مدیریت هویت و دسترسی در سطح ماشینهای پراکنده نیز پیچیده، زمانبر و مستعد خطاست. نبود سازوکارهای مرکزی Authentication و Authorization به ایجاد حسابهای متعدد و ناهمگون میانجامد.
از حیث مدیریت، هزینههای عملیاتی این مدل بالاست. هر ماشین مجازی به پیکربندی، بهروزرسانی و نگهداری جداگانه نیاز دارد و بار کاری تیم زیرساخت را بهطور محسوس افزایش میدهد. ناهمگونی پیکربندیها میان تیمها، عیبیابی را دشوار و انتقال دانش را محدود میکند.
کارایی منابع نیز در این الگو مطلوب نیست. ماشینهای مجازی حتی در زمان بلااستفاده، منابع سختافزاری را اشغال میکنند؛ این مسئله در مورد GPU که هزینهبر است، پررنگتر میشود. نبود مکانیزمهای خودکار برای تخصیص و آزادسازی منابع، به اتلاف ظرفیت میانجامد.
۱-۳ اهداف پروژه و ترکیب SaaS/PaaS
هدف پروژه ارائه پلتفرمی یکپارچه است که قابلیتهای SaaS (نرمافزار بهعنوان سرویس) و PaaS (پلتفرم بهعنوان سرویس) را در چارچوبی Cloud-Native تلفیق میکند. این ترکیب امکان ارائه سرویسهای متن باز و آماده مصرف و در عین حال بستری انعطافپذیر برای توسعه اپلیکیشنهای دانشجویان را فراهم میآورد.
در لایه SaaS، JupyterHub بهعنوان محیط کاربری اصلی عرضه میشود. کاربران با بهرهگیری از SSO وارد شده، به Notebook اختصاصی دسترسی مییابند و بدون درگیری با پیکربندی زیرساخت، بر پروژههای خود متمرکز میشوند. این لایه شامل ابزارهای پیشنصبشده یادگیری ماشین، دسترسی مدیریتشده به GPU و اتصال به منابع داده است.
در سطح PaaS، امکان استقرار اپلیکیشنهای سفارشی فراهم میشود. تیمها با الگوهای GitOps میتوانند سرویسهای خود را بهصورت خودکار در Kubernetes مستقر کنند. ArgoCD نقش موتور Continuous Deployment را ایفا کرده و تغییرات را از مخزن Git دریافت و اعمال میکند؛ رویکردی که شفافیت را افزایش داده و بازگشت سریع به نسخههای پیشین را ممکن میسازد.
اهداف فرعی شامل پیادهسازی Multi-Tenancy برای جداسازی منطقی تیمها، مدیریت متمرکز هویت با Keycloak، بهینهسازی بهرهگیری از GPU با سازوکارهای اشتراکگذاری زمانی و استقرار پایش یکپارچه با Prometheus و Grafana است. تدوین مستندات کامل فرآیندها و راهنماهای عملیاتی نیز برای تسهیل نگهداری و توسعه آتی مدنظر قرار گرفته است.
۱-۴ دامنه پروژه، مفروضات و موارد خارج از محدوده
دامنه پروژه، طراحی، پیادهسازی و مستندسازی یک پلتفرم کامل یادگیری ماشین بر بستر زیرساخت On-Premise را دربر میگیرد. تمامی لایهها، از مجازیسازی تا ارائه سرویس به کاربر نهایی، پوشش داده میشوند.
مفروضات اصلی عبارتاند از: دسترسی به سرورهای فیزیکی دارای پشتیبانی IOMMU برای GPU Passthrough، وجود شبکه پایدار با پهنای باند کافی، فراهم بودن سامانههای ذخیرهسازی برای دادههای دائمی و تخصیص نیروی انسانی مسلط به Kubernetes و Linux برای نگهداری پلتفرم.
تمرکز پروژه بر محیط آزمایشگاهی است و استفاده در محیطهای تجاری مستلزم ارزیابیهای امنیتی و عملیاتی اضافی خواهد بود. مباحثی مانند Disaster Recovery، دسترسپذیری بالا در سطح دیتاسنتر و رعایت الزامات Compliance صنایع خاص، خارج از دامنه فعلی قرار دارند؛ بااینحال معماری بهگونهای طراحی شده است که افزودن این قابلیتها در آینده امکانپذیر باشد.
۱-۵ خروجیهای مورد انتظار
خروجی اصلی، پلتفرمی عملیاتی و قابل استفاده برای یادگیری ماشین است که اجزای ضروری را یکپارچه ارائه میکند و توان پشتیبانی از حداقل ۲۰ کاربر همزمان با دسترسی به GPU را دارد.
از منظر فنی، خروجیها شامل کلاستر چندنودی Kubernetes با قابلیت GPU Passthrough، پیکربندی کامل JupyterHub با احراز هویت SSO، مجموعه Helm Chartها و Manifestهای Kubernetes برای همه اجزا و سامانه پایش یکپارچه با داشبوردهای Grafana است. پیکربندی ArgoCD برای GitOps و مجموعه NetworkPolicyها جهت تأمین امنیت شبکه نیز در زمره خروجیهای فنی قرار میگیرند.
مستندات جامع یکی از ارکان کلیدی خروجی است: راهنمای معماری با نمودارهای فنی، دستورالعملهای نصب و پیکربندی گامبهگام، راهنمای کاربری برای پژوهشگران و توسعهدهندگان و راهنمای عملیاتی برای تیم زیرساخت. این مستندات باید بهگونهای تدوین شوند که افراد با دانش متوسط بتوانند پلتفرم را نگهداری و توسعه دهند.
در حوزه عملیاتی، مجموعه اسکریپتهای اتوماسیون برای وظایف تکراری، Templateهای استاندارد برای ایجاد Namespaceهای جدید تیمها و Dashboardهای پایش برای متریکهای کلیدی عملکرد تولید میشود. علاوه بر این، یک محیط Staging کامل برای آزمون تغییرات پیش از اعمال در Production راهاندازی خواهد شد.
در پایان، این گزارش بهعنوان مستند جامع پروژه، تصمیمات طراحی، چالشها و راهحلهای پیادهسازی را با جزئیات ثبت میکند و میتواند مرجع پروژههای مشابه باشد.
۱-۶ ساختار گزارش
۲-۱ اصول معماری Cloud-Native و Observability
رویکرد Cloud-Native پاسخی به نیاز سامانههای نوین برای مقیاسپذیری، پویایی عملیاتی، تحمل خطا و قابلیت بازتولید است. در این رویکرد، سامانه بهجای اتکا بر اجزای بزرگ، ایستا و وابسته به محیط اجرا، به مجموعهای از اجزای مستقل، قابلاستقرار و قابلمدیریت تقسیم میشود. کانتینرها در این معماری نقش واحد استاندارد استقرار را ایفا میکنند و امکان اجرای سازگار بارهای کاری را در محیطهای گوناگون فراهم میسازند. در کنار کانتینرها، ارکستراسیون نقش محوری دارد؛ زیرا اجرای تعداد زیادی سرویس و workload بدون سامانهای برای Scheduling، بازیابی خودکار، مدیریت منابع و اعمال وضعیت مطلوب، در عمل پیچیده و پرخطا خواهد بود.
Kubernetes بهعنوان سکوی ارکستراسیون کانتینرها، بسیاری از اصول معماری Cloud-Native را بهصورت عملیاتی پیادهسازی میکند. مدل اعلانی Kubernetes این امکان را فراهم میسازد که وضعیت مطلوب سامانه در قالب manifestهای ساختاریافته تعریف شود و خود پلتفرم با استفاده از controllerها برای نزدیککردن وضعیت واقعی کلاستر به وضعیت مطلوب اقدام کند. این ویژگی برای پروژه حاضر اهمیت زیادی دارد؛ زیرا زیرساخت GPU Lab باید نهتنها قابلراهاندازی، بلکه قابلبازتولید، قابلممیزی و قابلتوسعه باشد. در چنین محیطی، ایجاد دستی سرویسها، تنظیمات شبکه، policyها و منابع ذخیرهسازی میتواند منجر به ناهمگونی، خطای انسانی و دشواری در نگهداری شود. به همین دلیل، استفاده از Kubernetes در کنار الگوی GitOps، بنیان مناسبی برای مدیریت اعلانی و نسخهپذیر زیرساخت فراهم میکند.
از منظر معماری، Cloud-Native تنها به استقرار کانتینری محدود نمیشود، بلکه مجموعهای از اصول عملیاتی را نیز دربرمیگیرد. مقیاسپذیری افقی، خودترمیمی، جداسازی مسئولیتها، کاهش وابستگی به محیط اجرا، اتوماسیون چرخه استقرار و امکان rollback کنترلشده از جمله ویژگیهایی هستند که در این پروژه مورد توجه قرار گرفتهاند. در GPU Lab دانشگاهی، این ویژگیها اهمیت دوچندان دارند؛ زیرا کاربران مختلف، با سطح دانش و نیازهای متفاوت، باید بتوانند از منابع گرانقیمت GPU به شکلی ایمن، کنترلشده و منصفانه استفاده کنند. بنابراین معماری انتخابشده باید هم از منظر زیرساخت قابل مدیریت باشد و هم در سطح تجربه کاربر، پیچیدگیهای فنی را پنهان کند.
در این پروژه، معماری Cloud-Native در سه سطح اصلی نمود پیدا میکند. در سطح زیرساخت، ماشینهای مجازی روی Proxmox VE ایجاد میشوند و منابع سختافزاری، از جمله GPU، بهشکل کنترلشده در اختیار نودهای Kubernetes قرار میگیرد. در سطح پلتفرم، Kubernetes وظیفه ارکستراسیون workloadها، زمانبندی Podها، اعمال سیاستهای شبکه، مدیریت منابع و اتصال به ذخیرهسازی را بر عهده دارد. در سطح سرویس، ابزارهایی مانند JupyterHub، Keycloak، Harbor، Prometheus، Grafana و ArgoCD بهعنوان اجزای قابلاستقرار روی کلاستر عمل میکنند و تجربه نهایی کاربر و تیم عملیاتی را شکل میدهند. این تفکیک لایهای باعث میشود تغییر یا توسعه در یک بخش، تا حد امکان اثر مستقیم و کنترلنشده بر سایر بخشها نداشته باشد.
یکی از الزامات مهم در معماری Cloud-Native، قابلیت رصد یا Observability است. در سامانههای سنتی، پایش معمولاً به بررسی وضعیت روشن یا خاموش بودن سرویسها و مصرف منابع پایه محدود میشد؛ اما در سامانههای توزیعشده و چندلایه، چنین سطحی از پایش کافی نیست. Observability به معنای توانایی درک وضعیت درونی سامانه از طریق دادههایی است که سامانه تولید میکند. این دادهها معمولاً در سه دسته اصلی قرار میگیرند: متریکها، لاگها و trace درخواستها. متریکها وضعیت کمی سامانه را نشان میدهند، لاگها رویدادها و خطاها را ثبت میکنند، و traceها مسیر و زمانبندی درخواستها را در اجزای توزیعشده آشکار میسازند.
در بستر Kubernetes، متریکها نقش پایهای در پایش سلامت کلاستر و تصمیمگیری عملیاتی دارند. اجزای مختلف کلاستر، از جمله kubelet، API Server و سایر مؤلفهها، دادههای قابلاندازهگیری تولید میکنند که میتواند توسط سامانههایی مانند Prometheus گردآوری شود. این دادهها امکان ساخت داشبوردهای عملیاتی، تعریف alert، تحلیل روند مصرف منابع و شناسایی گلوگاهها را فراهم میسازند. در پروژه حاضر، اهمیت متریکها تنها به CPU و RAM محدود نیست؛ بلکه مصرف GPU، حافظه GPU، دمای کارت، توان مصرفی و وضعیت خطاهای سختافزاری نیز باید در کنار متریکهای عمومی کلاستر پایش شوند. به همین دلیل، ترکیب Prometheus، Grafana و DCGM Exporter برای ایجاد دید عملیاتی نسبت به وضعیت GPUها اهمیت محوری دارد.
لاگها لایه دوم Observability را تشکیل میدهند. در محیطی که سرویسها در قالب Pod اجرا میشوند و ممکن است بهصورت پویا ایجاد، حذف یا جابهجا شوند، اتکا به لاگ محلی نودها کافی نیست. لاگها باید از کانتینرها جمعآوری، با metadataهای Kubernetes غنیسازی، و در یک سامانه مرکزی ذخیره شوند تا پس از حذف Pod یا تغییر محل اجرای آن نیز قابل بررسی باشند. این مسئله بهویژه در محیط دانشگاهی چندکاربره اهمیت دارد؛ زیرا خطاهای notebookها، jobهای آموزشی، سرویسهای احراز هویت، registry داخلی و اجزای زیرساختی باید قابل تفکیک و جستجو باشند. بنابراین logging متمرکز بخشی از الزامات نگهداری، عیبیابی و audit محسوب میشود.
Traceها سومین مؤلفه Observability هستند و برای تحلیل مسیر درخواستها در معماریهای توزیعشده به کار میروند. با این حال، در پروژه حاضر تمرکز پیادهسازی عملیاتی در مرحله فعلی بر متریکها، لاگها و مشاهدهپذیری شبکهای قرار گرفته است. به بیان دقیقتر، distributed tracing در سطح سرویسهای اپلیکیشنی بهعنوان مسیر توسعه آینده در نظر گرفته میشود و در نسخه فعلی، نیازهای اصلی رصد از طریق Prometheus، Grafana، DCGM Exporter، logging متمرکز و قابلیتهای مشاهدهپذیری شبکه Cilium/Hubble پوشش داده میشود. این تفکیک باعث میشود گزارش میان قابلیتهای نظری Observability و اجزای واقعاً پیادهسازیشده تمایز روشنی برقرار کند.
در GPU Lab چندکاربره، Observability تنها برای تیم زیرساخت کاربرد ندارد، بلکه بخشی از مدل بهرهبرداری منصفانه از منابع نیز محسوب میشود. منابع GPU محدود، گرانقیمت و حساس به الگوی مصرف هستند؛ بنابراین مدیر سامانه باید بتواند مصرف هر Namespace، هر کاربر یا هر workload را مشاهده کند و در صورت نیاز، policyهای تخصیص منابع را اصلاح نماید. برای مثال، اگر یک notebook مقدار زیادی حافظه GPU را برای مدت طولانی اشغال کند، یا یک job باعث افزایش غیرعادی دمای GPU شود، سامانه پایش باید امکان تشخیص سریع و واکنش مناسب را فراهم کند. از این منظر، Observability بخشی از مکانیزم کنترل کیفیت سرویس و مدیریت ظرفیت در پلتفرم است.
افزون بر این، انتخاب Cilium بهعنوان CNI کلاستر، بعد شبکهای Observability را تقویت میکند. Hubble بهعنوان لایه مشاهدهپذیری Cilium امکان مشاهده جریانهای ارتباطی میان Podها، Serviceها و Namespaceها را فراهم میسازد و برای عیبیابی ارتباطات داخلی، تحلیل policyها و بررسی رخدادهای مشکوک شبکهای مفید است [R-03]. این قابلیت برای پلتفرمی که شامل JupyterHub، سرویسهای احراز هویت، registry داخلی، سرویسهای ذخیرهسازی، jobهای پردازشی و ابزارهای پایش است، اهمیت زیادی دارد؛ زیرا بسیاری از خطاهای عملیاتی در چنین محیطی از جنس ارتباطات شبکه، policy اشتباه، DNS، یا محدودیت دسترسی میان Namespaceها هستند.
بنابراین، در معماری هدف این پروژه، Cloud-Native و Observability دو مفهوم جدا از هم نیستند؛ بلکه مکمل یکدیگرند. Cloud-Native امکان استقرار اعلانی، مقیاسپذیر و قابلبازتولید را فراهم میکند، و Observability امکان مشاهده، تحلیل و کنترل این محیط پویا را بهوجود میآورد. بدون Observability، افزایش پویایی و اتوماسیون میتواند به کاهش شفافیت عملیاتی منجر شود؛ و بدون معماری Cloud-Native، گردآوری دادههای عملیاتی بهتنهایی نمیتواند مسئله مدیریت منابع، توسعهپذیری و تکرارپذیری را حل کند. بر همین اساس، این پروژه تلاش میکند با ترکیب Kubernetes، GitOps، پایش GPU، logging متمرکز و مشاهدهپذیری شبکه، بستری فراهم کند که هم برای کاربران نهایی ساده و قابل استفاده باشد و هم برای تیم عملیاتی قابل مدیریت، قابل عیبیابی و قابل توسعه باقی بماند.
۲-۲ معماری کلان لایههای IaaS + PaaS + SaaS
معماری پلتفرم بر مدل سهلایه IaaS، PaaS و SaaS استوار است. جداسازی این لایهها ضمن افزایش انعطافپذیری، مدیریت و نگهداشت را سادهتر میکند.
در لایه Infrastructure as a Service، منابع فیزیکی و مجازیسازی مدیریت میشوند. Proxmox VE سکوی اصلی مجازیسازی است و ماشینهای مجازی را با پیکربندیهای متنوع در اختیار قرار میدهد. بهکارگیری PCI Passthrough برای اختصاص مستقیم GPU به ماشینها، بهرهوری سختافزار را افزایش میدهد. شبکه در این لایه با تعریف VLAN، پیکربندی Bridge و مدیریت ترافیک بین نودهای فیزیکی ساماندهی میشود. برای ذخیرهسازی محلی پرسرعت، TopoLVM لایهای با تاخیر پایین و پرفورمنس بالا فراهم میکند، هرچند High Availability ابزارهای مبتنی بر روش دسترسی از طریق Network مانند Longhorn را ندارد اما این نیاز از طریق کلاسترینگ در لایه سرویسها قابل دستیابی است.
لایه Platform as a Service با Kubernetes پیادهسازی شده و ارکستراسیون کانتینرها، شبکه با Cilium و مدیریت ذخیرهسازی را پوشش میدهد. NVIDIA GPU Operator چرخهعمر GPU را از نصب درایور تا پایش و بهروزرسانی مدیریت میکند. GitOps مبتنی بر ArgoCD کنترل اعلانی و خودکار پیکربندیها را امکانپذیر میسازد.
در لایه Software as a Service، سرویسهای کاربر نهایی ارائه میشود. JupyterHub محیطهای Notebook اختصاصی با دسترسی به GPU فراهم میکند و ورود یکپارچه از طریق SSO مدیریت هویت را ساده میسازد. داشبوردهای پایش نیز در این لایه قرار دارند.
۲-۳ انتخاب روش نصب Kubernetes و توجیه فنی
برای استقرار Kubernetes، از Kubespray بر بستر ماشینهای مجازی مبتنی بر Proxmox VE استفاده شد. انتخاب Kubespray بهدلیل تکرارپذیری، قابلیت سفارشیسازی، پشتیبانی از مقیاسهای بزرگ و امکان کنترل دقیق اجزای کلاستر انجام گرفت. اگرچه زیرساخت فیزیکی بهصورت on-premise فراهم شده است، اجرای Kubernetes در این پروژه روی ماشینهای مجازی انجام میشود تا مدیریت منابع، توسعهپذیری و بازتولید محیط سادهتر باشد.
مزیت کلیدی Kubespray انعطافپذیری آن در سفارشیسازی جزئیات نصب است. در مقایسه با توزیعهای آماده مانند OpenShift، کنترل دقیقتری بر پیکربندی شبکه، GPU و اجزای زیرساختی فراهم میکند. پشتیبانی از Container Runtimeهای مختلف، بهویژه containerd، برای بارهای کاری مبتنی بر GPU مناسب است.
نسبت به kubeadm، Kubespray نهتنها فرآیند نصب را به طور کامل خودکار میکند، بلکه پیکربندیهای امنیتی، راهاندازی CNI و استقرار etcd با دسترسپذیری بالا را نیز پوشش میدهد. Playbookهای Ansible امکان بهروزرسانی و مقیاسدهی بدون اختلال را فراهم میسازند.
از منظر عملیاتی، Idempotency اجرای مکرر Playbookها را قابل اتکا میکند و برای مدیریت تغییرات و رفع اشکال مفید است. جامعه فعال و پشتیبانی از نسخههای مختلف Kubernetes، بهروز بودن و امنیت کلاستر را تضمین میکند. قابلیت Offline Deployment نیز در محیطهای با محدودیت دسترسی اینترنتی یک مزیت جدی است.
۲-۴ انتخاب Stack GPU: درایور، CUDA، Device Plugin و Runtime
در پلتفرمهای یادگیری ماشین، GPU یکی از مهمترین و در عین حال پرهزینهترین منابع زیرساختی است. برخلاف CPU و RAM که در بیشتر سامانههای مجازیسازی و ارکستراسیون بهصورت عمومی و بالغ مدیریت میشوند، استفاده مؤثر از GPU در محیط Kubernetes نیازمند مجموعهای از اجزای تخصصی است. این اجزا باید بتوانند GPU فیزیکی را به کلاستر معرفی کنند، امکان تخصیص آن به Podها را فراهم سازند، کتابخانهها و runtimeهای لازم را در اختیار کانتینر قرار دهند و وضعیت سلامت و مصرف GPU را پایش کنند. به همین دلیل، طراحی Stack GPU در این پروژه بهعنوان یکی از تصمیمهای اصلی معماری در نظر گرفته شده است.
در سطح زیرساخت، GPUهای NVIDIA ابتدا از طریق قابلیت PCI Passthrough در Proxmox VE به ماشینهای مجازی منتخب تخصیص داده میشوند. این روش باعث میشود ماشین مجازیِ نقش Worker بتواند به GPU فیزیکی با کمترین سربار ممکن دسترسی داشته باشد. انتخاب PCI Passthrough در این پروژه با هدف نزدیککردن کارایی محیط مجازیسازیشده به حالت native انجام شده است. البته این روش نیازمند پیشنیازهایی مانند فعالسازی IOMMU در BIOS، پیکربندی صحیح VFIO در میزبان، جداسازی کارت گرافیک از host driver و اطمینان از سازگاری سختافزار با passthrough است. بنابراین، GPU Stack پروژه تنها به Kubernetes محدود نمیشود و از لایه سختافزار و Hypervisor آغاز میگردد.
پس از ارائه GPU به نودهای Worker، Kubernetes باید بتواند این منابع را شناسایی و به workloadها تخصیص دهد. بهصورت پیشفرض، Kubernetes منابعی مانند CPU و memory را میشناسد، اما برای مدیریت GPU به افزونهها و مؤلفههای تکمیلی نیاز دارد. در این پروژه، NVIDIA GPU Operator بهعنوان راهکار اصلی مدیریت GPU در کلاستر انتخاب شده است. GPU Operator با استفاده از الگوی Operator در Kubernetes، نصب و مدیریت بسیاری از اجزای نرمافزاری لازم برای استفاده از GPU را خودکار میکند. مستندات NVIDIA نیز GPU Operator را ابزاری برای خودکارسازی مدیریت مؤلفههایی مانند NVIDIA Driver، Kubernetes Device Plugin، NVIDIA Container Toolkit، GPU Feature Discovery و DCGM Exporter معرفی میکند.
یکی از وظایف کلیدی GPU Operator، مدیریت درایور NVIDIA روی نودهای GPU است. در معماری سنتی، نصب و بهروزرسانی درایور روی هر نود بهصورت دستی انجام میشود و این مسئله در بلندمدت باعث ناهمگونی نسخهها، دشواری نگهداری و افزایش احتمال خطای عملیاتی میگردد. در مقابل، GPU Operator میتواند با استفاده از DaemonSetهای اختصاصی، اجزای لازم را روی نودهای واجد شرایط مستقر کند و چرخه نگهداری آنها را تا حد زیادی یکپارچه سازد. این رویکرد بهویژه در محیطی که ممکن است تعداد نودهای GPU در آینده افزایش یابد، ارزش عملیاتی بالایی دارد.
در کنار درایور، CUDA و کتابخانههای وابسته نقش مهمی در اجرای workloadهای یادگیری ماشین دارند. پروژههای مختلف ممکن است به نسخههای متفاوت CUDA، cuDNN، TensorFlow یا PyTorch نیاز داشته باشند. اگر این وابستگیها بهصورت مستقیم روی سیستمعامل نود نصب شوند، نگهداری آنها پیچیده و مستعد تداخل نسخهها خواهد بود. در این پروژه، وابستگیهای سطح کاربر مانند CUDA toolkit و frameworkهای یادگیری ماشین تا حد امکان درون Container Imageها مدیریت میشوند. این رویکرد باعث میشود هر notebook یا job بتواند image متناسب با نیاز خود را داشته باشد، بدون آنکه نسخه کتابخانههای موردنیاز یک پروژه با پروژه دیگر تداخل ایجاد کند.
NVIDIA Device Plugin یکی دیگر از اجزای محوری GPU Stack است. این مؤلفه GPUهای موجود روی نود را کشف کرده و آنها را بهعنوان extended resource در Kubernetes ثبت میکند. پس از آن، Podها میتوانند در بخش resource requests یا limits، درخواست GPU را با کلیدی مانند nvidia.com/gpu اعلام کنند. Scheduler نیز بر اساس موجودی منابع، Pod را روی نودی قرار میدهد که GPU کافی داشته باشد. نتیجه این سازوکار آن است که تخصیص GPU از حالت دستی خارج شده و در قالب مدل استاندارد زمانبندی Kubernetes انجام میشود.
Container Runtime نیز در بهرهبرداری از GPU نقش حیاتی دارد. در این پروژه، containerd بهعنوان runtime اصلی انتخاب شده است، زیرا با CRI سازگار است و نسبت به Docker وابستگی کمتری به لایههای اضافی دارد. برای آنکه کانتینر بتواند به GPU و کتابخانههای لازم دسترسی داشته باشد، NVIDIA Container Toolkit یا سازوکارهای جدیدتر مانند Container Device Interface مورد استفاده قرار میگیرند. در نسخههای جدید GPU Operator، CDI بهعنوان مسیر مهمی برای تزریق دستگاههای GPU به کانتینرها مطرح شده است و استفاده از آن میتواند وابستگی به تنظیمات runtime سنتی را کاهش دهد. با این حال، فعالسازی و نحوه استفاده از CDI باید با نسخه containerd، نسخه GPU Operator و سیاست عملیاتی کلاستر هماهنگ باشد.
در پیادهسازی فعلی پروژه، تمرکز اصلی بر چهار قابلیت عملیاتی بوده است: نخست، شناسایی GPU در سطح نودهای Kubernetes؛ دوم، تخصیص GPU به Podها از طریق Device Plugin؛ سوم، اجرای Container Imageهای مجهز به CUDA و frameworkهای یادگیری ماشین؛ و چهارم، پایش GPU با استفاده از DCGM Exporter. DCGM Exporter امکان استخراج متریکهای مرتبط با GPU و ارائه آنها در قالب قابلاستفاده برای Prometheus را فراهم میکند. این متریکها شامل شاخصهایی مانند utilization، مصرف حافظه، دما، توان مصرفی و برخی وضعیتهای خطا هستند و برای مدیریت ظرفیت، تشخیص گلوگاه و حفاظت از سختافزار اهمیت دارند.
پایش GPU در این پروژه صرفاً یک قابلیت جانبی نیست، بلکه بخشی از مدل عملیاتی سامانه محسوب میشود. از آنجا که GPU منابعی محدود و پرهزینه هستند، تیم عملیاتی باید بتواند میزان استفاده از آنها را در سطح نود، Namespace و workload تحلیل کند. برای نمونه، پایینبودن utilization در زمان اشغالبودن GPU میتواند نشانه تخصیص غیربهینه منابع باشد؛ در مقابل، استفاده طولانیمدت از تمام حافظه GPU یا افزایش دما میتواند نشاندهنده workloadهای سنگین یا نیاز به بهینهسازی cooling و scheduling باشد. بنابراین، DCGM Exporter و داشبوردهای Grafana برای تصمیمگیری درباره ظرفیت، quota و policyهای استفاده از GPU ضروریاند.
قابلیتهایی مانند GPU Sharing، Time-Slicing و Multi-Instance GPU نیز در طراحی آینده پلتفرم اهمیت دارند، اما باید میان قابلیتهای پیادهسازیشده و قابلیتهای قابلتوسعه تمایز گذاشت. Time-Slicing میتواند امکان اشتراکگذاری یک GPU میان چند workload را فراهم کند، اما سطح ایزولاسیون آن با MIG یکسان نیست. مستندات NVIDIA تصریح میکند که Time-Slicing در مقایسه با MIG، ایزولاسیون حافظه و fault isolation مشابه ارائه نمیدهد، اما میتواند برای اشتراکگذاری GPU میان تعداد بیشتری کاربر یا برای GPUهای قدیمیتر که MIG را پشتیبانی نمیکنند مفید باشد. بنابراین، فعالسازی Time-Slicing باید بر اساس سیاست استفاده، نوع workload و سطح ایزولاسیون موردنیاز انجام شود.
MIG یا Multi-Instance GPU نیز برای برخی نسلهای GPU مانند NVIDIA A100 و نسلهای جدیدتر قابل استفاده است و امکان تقسیم یک GPU فیزیکی به چند instance مستقلتر را فراهم میکند. این قابلیت برای محیطهای چندکاربره جذاب است، زیرا میتواند تفکیک منابع GPU را دقیقتر کند و density کاربران را افزایش دهد. با این حال، استفاده از MIG وابسته به مدل کارت گرافیک، نسخه درایور، تنظیمات GPU Operator و سیاست تخصیص منابع است. در نتیجه، در این پروژه MIG بهعنوان قابلیت توسعه آینده در نظر گرفته میشود.
از منظر تجربه کاربر، هدف GPU Stack این است که پیچیدگیهای مربوط به درایور، runtime و تخصیص سختافزار از دید پژوهشگر پنهان شود. کاربر نهایی نباید نیاز داشته باشد بداند GPU چگونه به ماشین مجازی متصل شده، کدام DaemonSet درایور را مدیریت میکند یا Device Plugin چگونه resource را در Kubernetes ثبت میکند. کاربر باید بتواند از طریق JupyterHub یا Job Template، پروفایل مناسب را انتخاب کند و محیطی آماده برای اجرای کدهای PyTorch، TensorFlow یا سایر frameworkها دریافت نماید. این جداسازی میان پیچیدگی زیرساخت و سادگی تجربه کاربری، یکی از اهداف اصلی معماری پلتفرم است.
در نهایت، انتخاب NVIDIA GPU Operator در کنار containerd، CUDA-based imageها، Device Plugin و DCGM Exporter باعث میشود GPU Stack پروژه با اصول Cloud-Native همراستا باشد. این انتخاب، مدیریت GPU را از مجموعهای از تنظیمات دستی و پراکنده به مدلی اعلانی، قابلاستقرار و قابلپایش نزدیک میکند. با این حال، برای دقت علمی گزارش، لازم است قابلیتهای فعالشده در نسخه فعلی از قابلیتهای آینده تفکیک شوند. در نسخه فعلی، هسته پیادهسازی شامل GPU Passthrough، شناسایی GPU در Kubernetes، تخصیص GPU به Podها، اجرای imageهای مجهز به CUDA و پایش GPU است؛ در حالی که قابلیتهایی مانند MIG، Time-Slicing، CDI پیشرفته و سیاستهای پیچیده GPU sharing باید بر اساس سختافزار، نیاز کاربران و نتایج آزمون، در مراحل بعدی فعال و ارزیابی شوند.
۲-۵ طراحی سیستم ذخیرهسازی
در پلتفرمهای یادگیری ماشین، الگوهای دسترسی به داده متنوع و پراکنده است: Notebookهای کاربران، مجموعهدادههای آموزشی و مدلهای یادگیری عمیق هر یک نیازهای متفاوتی از نظر throughput، latency و اشتراکپذیری دارند.
طرح ذخیرهسازی بر مبنای TopoLVM بهعنوان یک CSI driver شکل گرفته است؛ راهکاری که مدیریت Local Volume را با آگاهی از توپولوژی کلاستر ترکیب میکند. برخلاف ذخیرهسازی توزیعشده که سربار شبکهای دارد، استفاده از دیسکهای محلی نودها تأخیر کم و توان عملیاتی بالا را تضمین میکند و برای بارهای GPU-intensive مناسب است.
در هر نود Worker، دیسکهای محلی در قالب Volume Groupهای اختصاصی پیکربندی شدهاند. هنگام درخواست ذخیرهسازی، TopoLVM بهصورت پویا Logical Volume ایجاد و آن را بهعنوان PV در اختیار Pod قرار میدهد. زمانبند Kubernetes با توجه به ظرفیت موجود، Pod را در نودی قرار میدهد که فضای کافی برای PVC فراهم باشد.
برای مدیریت چرخهعمر داده، سه StorageClass تعریف شده است: `local-ssd-retain` برای دادههای حیاتی با سیاست نگهداشت، `local-ssd-delete` برای فضاهای کاری موقت، و `local-ssd-snapshot` با امکان تهیه نسخههای پشتیبان دورهای. این تفکیک امکان انتخاب آگاهانه بر اساس اهمیت داده را فراهم میسازد.
در این پروژه، با توجه به اینکه پیادهسازی فعلی شامل یک نود GPU است، نیاز عملیاتی به ذخیرهسازی مشترک میان چند نود GPU وجود ندارد. ازاینرو، TopoLVM بهعنوان لایه اصلی ذخیرهسازی برای ارائه PersistentVolumeهای محلی و کمتأخیر انتخاب شده است. این انتخاب برای محیطهای آموزشی و پژوهشی که workloadهای GPU روی نود مشخص اجرا میشوند، ساده، قابلکنترل و از نظر کارایی مناسب است.
TopoLVM با استفاده از دیسکهای محلی نود Worker، امکان ایجاد PVCهای پویا را فراهم میکند و برای workspace کاربران، فایلهای موقت آموزش مدل، خروجی آزمایشها و checkpointهای محلی مناسب است. در این مدل، Podهای نیازمند GPU با استفاده از nodeSelector، taint/toleration یا سیاستهای زمانبندی مشابه روی نود GPU اجرا میشوند و PVCهای مرتبط نیز روی همان نود در دسترس قرار میگیرند.
با این حال، TopoLVM ذاتاً جایگزین سامانههای ذخیرهسازی مشترک و توزیعشده نیست. در صورتی که کلاستر در آینده به چند نود GPU توسعه یابد یا نیاز باشد datasetها، مدلهای پایه یا home directory کاربران بهصورت مشترک میان چند نود در دسترس باشند، استفاده از یک لایه ذخیرهسازی مجزا مانند NFS، CephFS یا Object Storage قابل بررسی خواهد بود. بنابراین، در معماری فعلی، NFS جزء الزامی پیادهسازی نیست و صرفاً بهعنوان گزینه توسعه آینده برای سناریوهای چندنودی مطرح میشود.
۲-۶ شبکه، Ingress و DNS
در معماری Kubernetes، شبکه یکی از مؤلفههای بنیادین کلاستر محسوب میشود؛ زیرا تمام ارتباطات میان Podها، Serviceها، Ingress Controller، سرویسهای پایش، و اجزای سطح کاربر از طریق لایه شبکه انجام میگیرد. Kubernetes بهصورت ذاتی تنها مدل شبکه را تعریف میکند و پیادهسازی عملی این مدل بر عهده افزونههای سازگار با Container Network Interface یا CNI است. بنابراین انتخاب CNI مناسب، بهویژه در پلتفرمی چندکاربره و مبتنی بر GPU، تأثیر مستقیم بر امنیت، کارایی، قابلیت مشاهدهپذیری و توسعهپذیری سامانه دارد. مستندات Kubernetes نیز تصریح میکند که استفاده از یک افزونه CNI سازگار برای پیادهسازی مدل شبکه Kubernetes ضروری است.
در این پروژه، پس از بررسی گزینههای مختلف، Cilium بهعنوان CNI اصلی کلاستر انتخاب شد. دلیل اصلی این انتخاب، اتکای Cilium به فناوری eBPF در هسته Linux است که امکان پیادهسازی سیاستهای شبکه، load balancing، مشاهدهپذیری و کنترل ترافیک را با سربار کمتر و انعطافپذیری بیشتر نسبت به روشهای سنتی مبتنی بر iptables فراهم میکند. از آنجا که پلتفرم طراحیشده برای ارائه سرویس به کاربران متعدد، اجرای workloadهای تعاملی و پردازشهای GPUمحور در محیط دانشگاهی در نظر گرفته شده است، نیاز به شبکهای وجود داشت که علاوه بر اتصال ساده Podها، قابلیت اعمال policy دقیق، مشاهده جریانهای ارتباطی، و توسعه در مراحل بعدی را نیز فراهم کند.
یکی از معیارهای اصلی انتخاب Cilium، پشتیبانی قوی آن از NetworkPolicy و مدلهای پیشرفتهتر سیاستگذاری بود. در یک GPU Lab چندکاربره، هر کاربر یا گروه پژوهشی باید در محیطی ایزوله فعالیت کند و دسترسی میان Namespaceها، سرویسهای زیرساختی، رجیستری داخلی، سرویس احراز هویت و محیطهای JupyterHub باید کنترلشده باشد. Kubernetes خود مفهوم NetworkPolicy را تعریف میکند، اما اعمال واقعی آن وابسته به CNI است؛ یعنی بدون CNI پشتیبان NetworkPolicy، تعریف این سیاستها اثر عملی نخواهد داشت.
Cilium در این زمینه علاوه بر NetworkPolicy استاندارد Kubernetes، امکان استفاده از سیاستهای توسعهیافتهتر مبتنی بر identity، DNS و لایه ۷ را نیز فراهم میکند و به همین دلیل برای سناریوهای چندمستأجره مناسبتر از گزینههای سادهتر ارزیابی شد.
در مقایسه با Flannel، مزیت Cilium کاملاً روشن است. Flannel بیشتر برای ایجاد یک overlay network ساده میان نودهای Kubernetes طراحی شده و گزینهای سبک و قابلفهم برای کلاسترهای کوچک یا محیطهای آموزشی ساده است. با این حال، Flannel بهتنهایی قابلیتهای امنیتی و policy enforcement کافی برای یک محیط چندکاربره جدی را فراهم نمیکند. در پروژه حاضر، صرفاً اتصال Podها به یکدیگر کافی نبود؛ بلکه نیاز به جداسازی کاربران، کنترل دسترسی میان Namespaceها، مشاهده جریانهای شبکه و امکان توسعه سیاستهای امنیتی وجود داشت. به همین دلیل، Flannel با وجود سادگی، پاسخگوی نیازهای امنیتی و عملیاتی این پروژه نبود.
در مقایسه با Calico، انتخاب پیچیدهتر بود؛ زیرا Calico نیز یکی از گزینههای بالغ و رایج در Kubernetes است و از NetworkPolicy و سناریوهای متنوع شبکه پشتیبانی میکند. Calico در بسیاری از محیطهای production انتخاب مناسبی محسوب میشود، اما در این پروژه Cilium بهدلیل یکپارچگی عمیقتر با eBPF، قابلیتهای مشاهدهپذیری داخلی از طریق Hubble، و امکان حرکت به سمت معماریهای پیشرفتهتر مانند kube-proxy replacement، گزینه مناسبتری ارزیابی شد. به بیان دیگر، Calico میتوانست نیازهای پایه شبکه و policy را پوشش دهد، اما Cilium علاوه بر این نیازها، ظرفیت بهتری برای observability، عیبیابی، و توسعه آینده پلتفرم فراهم میکند.
یکی از مزیتهای کلیدی Cilium در این پروژه، وجود Hubble بهعنوان لایه مشاهدهپذیری شبکه است. Hubble امکان مشاهده ارتباطات میان سرویسها، Podها و Namespaceها را در سطح کلاستر فراهم میکند و به تیم عملیاتی اجازه میدهد جریانهای ترافیکی را بدون نیاز به ابزارهای جانبی پیچیده تحلیل کند. این قابلیت برای GPU Lab اهمیت زیادی دارد؛ زیرا در چنین محیطی ممکن است کاربران مختلف، notebookها، jobها، registry داخلی، سرویسهای احراز هویت و سرویسهای ذخیرهسازی بهصورت همزمان با یکدیگر در ارتباط باشند. مشاهده این ارتباطات برای عیبیابی، تحلیل رخدادهای امنیتی و بهبود سیاستهای NetworkPolicy ضروری است. مستندات Cilium، Hubble را بهعنوان لایه observability برای ارائه دید عمیق نسبت به رفتار سرویسها و زیرساخت شبکه معرفی میکند.
مزیت دیگر Cilium، امکان استفاده از kube-proxy replacement مبتنی بر eBPF است. در معماری سنتی Kubernetes، kube-proxy معمولاً با استفاده از iptables یا IPVS، وظیفه پیادهسازی Service load balancing را بر عهده دارد. در کلاسترهای پرترافیک، افزایش تعداد Serviceها و Endpointها میتواند مدیریت ruleها را پیچیدهتر کند. Cilium این امکان را فراهم میکند که بخشی از این منطق با استفاده از eBPF پیادهسازی شود و وابستگی به kube-proxy کاهش یابد یا حذف شود. اگرچه فعالسازی این قابلیت نیازمند بررسی دقیق نسخه Kernel، تنظیمات کلاستر و سناریوی عملیاتی است، اما وجود آن برای توسعه آینده پلتفرم یک مزیت معماری مهم محسوب میشود. مستندات رسمی Cilium، حالت Kubernetes بدون kube-proxy را بهعنوان یکی از قابلیتهای شبکهای Cilium توضیح داده است. از منظر عملکردی، Cilium برای workloadهای تعاملی و GPUمحور نیز انتخاب مناسبی است. در GPU Lab، کاربران معمولاً با محیطهایی مانند JupyterHub، notebookهای تعاملی، jobهای آموزشی، pull/push imageها و دسترسی به datasetها سروکار دارند. چنین محیطی به شبکهای نیاز دارد که هم latency قابلقبول داشته باشد و هم ابزارهای مناسبی برای کنترل و مشاهده ترافیک فراهم کند. Cilium علاوه بر مسیر داده مبتنی بر eBPF، قابلیتهایی مانند Bandwidth Manager را نیز ارائه میدهد که میتواند در سناریوهای کنترل نرخ ترافیک Podها و بهینهسازی بارهای TCP/UDP مورد استفاده قرار گیرد.
این قابلیت برای مراحل آینده پروژه، بهویژه در صورت افزایش تعداد کاربران همزمان یا نیاز به محدودسازی مصرف شبکه کاربران، ارزشمند خواهد بود.
در مقایسه با گزینههایی مانند Canal یا ترکیبهای مبتنی بر چند افزونه، Cilium از نظر سادگی معماری نهایی مزیت دارد. استفاده از چند مؤلفه برای پوشش همزمان networking و policy ممکن است در ظاهر انعطافپذیر باشد، اما در عمل باعث افزایش پیچیدگی نصب، عیبیابی و نگهداشت میشود. در این پروژه، یکی از اهداف اصلی، ایجاد بستری قابلتکرار و قابلمدیریت برای محیط دانشگاهی بود؛ بنابراین انتخاب CNI باید به کاهش پیچیدگی عملیاتی کمک میکرد. Cilium با ارائه networking، policy enforcement، observability و قابلیتهای پیشرفته شبکه در قالب یک stack منسجم، از این منظر با اهداف پروژه سازگارتر بود.
با وجود مزایای یادشده، انتخاب Cilium بدون هزینه نیست. Cilium نسبت به گزینههای سادهتری مانند Flannel پیچیدگی بیشتری دارد و برای بهرهبرداری صحیح از قابلیتهای پیشرفته آن، تیم عملیاتی باید با مفاهیمی مانند eBPF، Hubble، identity-based policy، و تنظیمات kube-proxy replacement آشنا باشد. همچنین برخی قابلیتهای پیشرفته آن به نسخه Kernel، تنظیمات سیستمعامل و پیکربندی دقیق Helm وابستهاند. با این حال، با توجه به ماهیت پروژه و نیاز آن به امنیت، مشاهدهپذیری و توسعهپذیری، این پیچیدگی قابلقبول ارزیابی شد؛ زیرا مزایای عملیاتی و امنیتی Cilium در بلندمدت بیش از هزینه یادگیری و نگهداشت آن است.
بر این اساس، Cilium بهعنوان CNI نهایی پروژه انتخاب شد. این انتخاب با اهداف اصلی پلتفرم، یعنی ارائه محیط چندکاربره، ایزوله، قابل پایش و قابل توسعه برای پردازشهای هوش مصنوعی، همراستا است. در معماری نهایی، Cilium مسئول اتصال شبکهای Podها، اعمال NetworkPolicyها، فراهمسازی قابلیتهای مشاهدهپذیری از طریق Hubble و آمادهسازی بستر برای توسعه قابلیتهای پیشرفتهتر شبکه در مراحل بعدی خواهد بود.
۲-۷ مدیریت هویت و دسترسی با SSO/OIDC
در پلتفرمهای چندکاربره با منابع محاسباتی گرانقیمت، احراز هویت و مجوزدهی باید همزمان امنیت و تجربه کاربری مناسب را تضمین کند. روشهای متکی بر رمزهای محلی در هر سرویس، از نظر امنیت و کارآمدی مطلوب نیستند.
معماری هویت بر پایه SSO با پروتکل OIDC اجرا شده و Keycloak بهعنوان Identity Provider مرکزی انتخاب شده است. Keycloak با پشتیبانی از استانداردهای OIDC و OAuth2 و قابلیت federation با سامانههای هویتی موجود (مانند LDAP یا Active Directory)، یکپارچگی و مدیریت متمرکز را فراهم میکند.
هیچ سرویسی بهطور مستقیم اعتبارسنجی کاربر را انجام نمیدهد. کاربر برای دسترسی به JupyterHub یا سایر سرویسها به صفحه ورود Keycloak هدایت میشود و پس از احراز هویت موفق، یک ID Token (JWT) حاوی شناسه و نقشهای کاربر صادر میشود. سرویس مقصد با اعتبارسنجی token و تفسیر claimها، سیاستهای دسترسی را اعمال میکند.
برای مجوزدهی از Role-Based Access Control در Keycloak استفاده شده است. سه نقش اصلی تعریف شدهاند: `student` با دسترسی محدود، `researcher` با سهمیه GPU بیشتر، و `admin` با اختیار کامل در پنلهای مدیریتی. نقشها در ID Token درج میشوند و سرویسهای downstream بر همان اساس عمل میکنند.
در مورد سرویسهایی که بهصورت بومی از OIDC پشتیبانی ندارند، OAuth2 Proxy بهعنوان reverse proxy در جلوی سرویس قرار میگیرد و پیش از رسیدن درخواست به backend، احراز هویت را انجام میدهد.
۲-۸ جمعبندی انتخابها
معماری نهایی حاصل مجموعهای از تصمیمها با مقایسههای روشن است:
۳-۱ وضعیت پایه Proxmox و راهبرد سایزبندی VMها
در این پروژه، Proxmox VE بهعنوان لایه مجازیسازی اصلی انتخاب شده است تا مدیریت ماشینهای مجازی و تخصیص منابع سختافزاری در قالب یک بستر یکپارچه انجام شود. هر سرور فیزیکی بهصورت مستقل با Proxmox VE راهاندازی میشود و مدیریت آن از طریق رابط وب متمرکز در دسترس است. نتیجه این انتخاب، بهرهبرداری کارآمدتر از منابع و حفظ انعطاف لازم برای توسعه آتی کلاستر است.
سایزبندی ماشینهای مجازی بر مبنای نقش هر Node در کلاستر Kubernetes انجام شده است. برای نودهای Master که وظیفه اجرای Control Plane را بر عهده دارند، پیکربندی میانیِ ۴ هسته پردازنده و ۸ گیگابایت حافظه در نظر گرفته شده است. این سطح از منابع برای اجرای کامپوننتهای etcd، kube-apiserver، kube-controller-manager و kube-scheduler کفایت میکند. در مقابل، نودهای Worker که بار کاری اصلی اپلیکیشنها و Podها را میزبانی میکنند، به منابع بیشتری نیاز دارند.
نودهای Worker در دو گروه تعریف شدهاند:
1) نودهای استاندارد با ۸ هسته و ۱۶ گیگابایت RAM برای اپلیکیشنهای عمومی؛
2) نودهای GPU-enabled با ۱۶ هسته و ۳۲ گیگابایت RAM که با استفاده از PCI Passthrough امکان تخصیص مستقیم کارتهای گرافیک NVIDIA به ماشین مجازی را فراهم میکنند. این تفکیک، هم از منظر هزینه و هم از حیث کارایی، توزیع منابع را هدفمند میکند و مانع مصرف غیرضروری GPU در بارهای کاری غیرمرتبط میشود.
برای ساخت ماشینهای مجازی، از Templateهای استاندارد Ubuntu 22.04 LTS استفاده شده که پیشاپیش با Cloud-Init پیکربندی شدهاند. چنین رویکردی، علاوه بر افزایش سرعت استقرار، یکنواختی تنظیمات پایه میان نودها را نیز تضمین میکند.
۳-۲ توپولوژی شبکه
طراحی شبکه پلتفرم با هدف جداسازی منطقی جریانهای ترافیکی و ارتقای همزمان امنیت، کارایی و قابلیت مدیریت انجام شده و سه لایه اصلی را شامل میشود. لایه نخست، شبکه مدیریتی (Management Network) با زیرشبکه `192.168.100.0/24` است که صرفاً برای دسترسی SSH به سرورها و استفاده از رابط وب Proxmox در نظر گرفته شده. دسترسی به این شبکه با قوانین Firewall محدود شده و تنها از IPهای مشخص امکانپذیر است.
لایه دوم، شبکه داخلی Kubernetes با زیرشبکه `10.10.0.0/16`، بستر ارتباطات اصلی میان نودهای کلاستر را شکل میدهد. این شبکه از طریق یک Bridge مجازی در Proxmox پیادهسازی شده و ترافیک Control Plane، ارتباطات Pod-to-Pod و دسترسی به APIServer از همین مسیر عبور میکند. در سطح لایه شبکه کلاستر نیز، بهکارگیری CNI مانند Calico امکان اعمال NetworkPolicy و کنترل دقیقتر ترافیک را فراهم میسازد.
لایه سوم به شبکه ذخیرهسازی (Storage Network) با زیرشبکه `10.20.0.0/24` اختصاص دارد تا ترافیک مربوط به دسترسی به سیستمهای ذخیرهسازی توزیعشده از ترافیک اپلیکیشن تفکیک شود. این جداسازی برای کارکرد صحیح TopoLVM و دسترسی به Volumeهای محلی اهمیت دارد؛ زیرا با کاهش تداخل ترافیک I/O و ترافیک سرویسها، تأخیر (latency) پایدارتر و قابل پیشبینیتری حاصل میشود.
برای ارائه سرویس به بیرون، یک شبکه Public با IPهای عمومی در نظر گرفته شده که از طریق Ingress Controller و Load Balancer به سرویسهای داخلی کلاستر متصل میشود. در مجموع، این معماری چندلایه امکان اجرای اصول Zero Trust و Defense in Depth را در سطح شبکه فراهم میکند.
## ۳.۳ تنظیمات IP، DNS و همگامسازی زمان NTP
پایداری کلاستر Kubernetes تا حد زیادی به صحت آدرسدهی و سرویسهای زیرساختی وابسته است. به همین دلیل، در این طراحی از آدرسدهی استاتیک برای تمام نودها استفاده میشود تا تغییرات ناخواسته IP و اختلال در Service Discovery رخ ندهد. نودهای Master از بازه `10.10.1.1` تا `10.10.1.3` و نودهای Worker از محدوده `10.10.2.x` استفاده میکنند.
بهمنظور سادهسازی مدیریت و افزایش شفافیت نامگذاری، یک DNS داخلی با dnsmasq یا CoreDNS راهاندازی شده است. این سرویس رکوردهای A و PTR همه نودها را نگهداری میکند و همزمان بهعنوان Upstream DNS نیز عمل میکند؛ بهطوری که درخواستهای بیرونی را به DNSهای عمومی مانند `8.8.8.8` forward میکند. الگوی نامگذاری `k8s-master-01.cluster.local` و `k8s-worker-gpu-01.cluster.local` نیز بهگونهای انتخاب شده که نقش هر نود در همان نام قابل تشخیص باشد.
همگامسازی زمان با NTP برای Kubernetes ضروری است؛ زیرا اختلاف زمانی میان نودها میتواند به بروز اشکال در احراز هویت، اعتبارسنجی گواهیهای TLS و حتی رفتار etcd منجر شود. در این معماری، یکی از سرورهای Master بهعنوان NTP Server داخلی پیکربندی میشود و خود با NTPهای عمومی همگام است. سایر نودها بهعنوان NTP Client به همین سرور داخلی متصل میشوند. استفاده از chrony بهجای ntpd با توجه به سرعت همگامسازی بالاتر و سربار کمتر، گزینه مناسبتری ارزیابی شده است.
تمام این تنظیمات در Template اولیه و از طریق Cloud-Init قرار داده شده و هنگام ایجاد هر ماشین مجازی بهطور خودکار اعمال میشود؛ بنابراین هم سرعت استقرار بالا میرود و هم احتمال خطای انسانی کاهش مییابد.
## ۳.۴ ساخت Templateها، Cloud-Init و اتوماسیون
بهکارگیری Templateهای از پیش آماده در Proxmox VE، استقرار نودهای Kubernetes را سریعتر کرده و همسانی پیکربندی را در کل کلاستر حفظ میکند. در این پروژه، Template مبتنی بر Ubuntu 22.04 LTS تهیه شده که بستههای پایه، تنظیمات بهینهسازی سیستمعامل و پیشنیازهای Kubernetes را در خود دارد.
فرآیند ساخت Template از ایجاد یک ماشین مجازی پایه با مشخصات استاندارد آغاز شد. در ادامه، کرنل Linux به نسخهای با پشتیبانی کامل از قابلیتهای کانتینری ارتقا یافت؛ ماژولهای لازم برای CNI و CSI فعال شد و پارامترهای sysctl مورد نیاز Kubernetes تنظیم گردید. سپس با نصب ابزارهای پایه از جمله containerd و اعمال تنظیمات شبکه و امنیت، تصویر نهایی ماشین بهصورت Template ذخیره شد.
Cloud-Init نقش اصلی را در پیکربندی خودکار ماشینهای تازه ایجادشده بر عهده دارد. مواردی مانند hostname، آدرس IP ثابت، کلیدهای SSH و اسکریپتهای راهاندازی اولیه از این مسیر اعمال میشود. بدین ترتیب، هم استقرار نودهای جدید تسهیل میشود و هم ناسازگاریهای ناشی از تنظیمات دستی به حداقل میرسد.
برای تکمیل چرخه استقرار، اسکریپتهایی مبتنی بر Proxmox API توسعه داده شد که عملیات کلونکردن Template، تزریق پیکربندی Cloud-Init و روشنکردن ماشین مجازی را بهصورت یکپارچه انجام میدهند. این مکانیزم در مقیاسسازی افقی کلاستر تعیینکننده است و زمان افزودن نود جدید را از سطح ساعتی به چند دقیقه کاهش میدهد.
## ۳.۵ طراحی ذخیرهسازی در سطح Proxmox
طراحی ذخیرهسازی در Proxmox VE باید دو نیاز متفاوت را پوشش دهد: نخست، ذخیره دیسکهای ماشینهای مجازی؛ دوم، فراهمکردن ظرفیت مناسب برای بارهای کاری Kubernetes. بر همین اساس، یک رویکرد لایهای انتخاب شده تا توازن میان هزینه و عملکرد حفظ شود.
برای دیسک سیستمعامل نودهای Kubernetes، استوریج محلی مبتنی بر NVMe در نظر گرفته شد؛ انتخابی که با هدف دستیابی به تأخیر پایین و توان عملیاتی بالاتر در I/O انجام شده است. این دیسکها در Proxmox بهصورت LVM-Thin پیکربندی شدهاند تا قابلیت Thin Provisioning و Snapshot فراهم شود. LVM-Thin بهویژه در ساخت Template و کلون سریع ماشینهای مجازی مزیت عملیاتی قابل توجهی ایجاد میکند.
در لایه Kubernetes و برای Persistent Storage، مسیر دیگری اتخاذ شد. دیسکهای NVMe اضافی از طریق PCI Passthrough بهصورت مستقیم به نودهای Worker ارائه شدند تا سربار لایههای مجازیسازی حذف و عملکرد نزدیک به Native حاصل شود. پیامد این تصمیم آن است که TopoLVM بتواند دیسکها را بدون واسطه مدیریت کند و PVهای کمتأخیر برای Podها بسازد.
در کنار ذخیرهسازی عملیاتی، یک استوریج شبکهای مبتنی بر NFS نیز برای پشتیبانگیری و آرشیو پیکربندی شده و به Proxmox متصل است. این فضا برای ذخیره Snapshotهای دورهای و Backupهای خودکار ماشینهای مجازی به کار میرود و در سناریوهای Disaster Recovery نقش کلیدی دارد.
## ۳.۶ پیادهسازی Baseline امنیتی
استقرار Kubernetes روی Proxmox VE نیازمند کنترلهای امنیتی چندلایه است؛ از Hypervisor آغاز میشود و تا سیستمعامل نودها ادامه مییابد. بر این اساس، یک Baseline امنیتی تعریف شده که رعایت آن برای تمام نودهای کلاستر الزامی است.
در سطح Proxmox، دسترسی به رابط مدیریتی محدود شده است. احراز هویت دو مرحلهای (Two-Factor Authentication) برای همه حسابها فعال است و دسترسی به API صرفاً از شبکههای مدیریتی مجاز انجام میشود. همچنین جداسازی شبکهای میان شبکه مدیریت Proxmox و شبکههای کاری Kubernetes اعمال شده تا در صورت رخداد امنیتی در یک لایه، اثر آن به سایر لایهها سرایت نکند.
در سطح سیستمعامل نودها نیز سختگیریهای متناسب اعمال شده است: UFW بهصورت پیشفرض فعال بوده و تنها پورتهای ضروری Kubernetes باز گذاشته شدهاند. سرویسهای غیرضروری غیرفعال شده و دسترسی SSH به استفاده از کلید عمومی محدود است. افزون بر این، پارامترهای کرنل طوری تنظیم شدهاند که ریسک حملات متداول شبکهای نظیر IP Spoofing و SYN Flood کاهش یابد.
بهعنوان اقدام مکمل، AppArmor برای containerd فعال و پروفایلهای امنیتی مناسب تعریف شدهاند تا دسترسی کانتینرها به منابع سیستم محدود شود. هدف این است که در صورت وجود آسیبپذیری در یک کانتینر، امکان گسترش حمله به میزبان کاهش یابد. Audit Logging در سطح کرنل نیز فعال شده تا رخدادهای حساس ثبت و قابلیت پیگیری فراهم شود.
## ۳.۷ چکلیست پیشنیازها قبل از نصب Kubernetes
پیش از شروع نصب Kubernetes، لازم است وضعیت زیرساخت بهصورت مرحلهای کنترل شود تا خطاهای ناشی از پیکربندی ناقص در ادامه کار بروز نکند. چکلیست زیر بهعنوان کنترل نهایی برای تأیید آمادگی محیط به کار میرود.
### بررسی زیرساخت سختافزاری و مجازیسازی
ابتدا باید اطمینان حاصل شود که همه ماشینهای مجازی مطابق مشخصات تعریفشده در Proxmox ایجاد شدهاند و هر Node حداقل منابع لازم را متناسب با نقش خود (Master یا Worker) دارد. برای نودهای Master حداقل ۴ هسته CPU و ۸GB RAM توصیه میشود؛ نودهای Worker بسته به بار کاری، معمولاً به منابع بیشتری نیاز خواهند داشت. اگر GPU Passthrough استفاده میشود، صحت پیکربندی IOMMU و تخصیص کارت گرافیک به ماشین مجازی متناظر باید کنترل شود.
Templateهای Cloud-Init نیز باید آماده و قابل استفاده باشند و تنظیمات پایه سیستمعامل، کاربران، کلیدهای SSH و شبکه اولیه را در خود داشته باشند. تهیه Snapshot اولیه از ماشینهای مجازی قبل از نصب، امکان بازگشت سریع در صورت بروز خطا را فراهم میکند و نباید نادیده گرفته شود.
### تأیید پیکربندی شبکه
ارتباط شبکه میان نودها باید عملیاتی و آزموده شده باشد. این مرحله شامل بررسی ارتباط میان همه Master و Worker Nodeها، کنترل صحت DNS داخلی و اطمینان از دسترسی به سرویسهای NTP برای همگامسازی زمان است. تأخیر شبکه (latency) بین نودها نیز باید در محدوده قابل قبول باشد؛ برای کلاستر داخلی معمولاً کمتر از ۱۰ میلیثانیه در نظر گرفته میشود.
در ادامه، پیکربندی فایروال همه نودها بازبینی میشود. پورتهای ضروری Kubernetes شامل 6443 برای API Server، بازه 2379-2380 برای etcd، پورت 10250 برای Kubelet و پورتهای 10251-10252 برای Controller Manager و Scheduler باید باز باشند. همچنین دسترسی به محدوده پورتهای 30000-32767 برای NodePort Services لازم است.
### آمادهسازی سیستمعامل
روی همه نودها، Ubuntu 20.04 LTS باید بهروز باشد و بستههای امنیتی نصب شده باشند. تنظیمات کرنل مورد نیاز Kubernetes نیز باید اعمال شود؛ از جمله غیرفعالسازی swap، فعالسازی IP forwarding و بارگذاری ماژولهای overlay و br_netfilter. این موارد برای عملکرد صحیح CNI و networking کانتینرها ضروریاند.
Container runtime انتخابشده در این پروژه containerd است و باید نصب و بهدرستی پیکربندی شود. نسخه containerd باید با نسخه Kubernetes سازگار باشد و با systemd بهعنوان cgroup driver تنظیم شود. همچنین kubeadm، kubelet و kubectl باید با نسخه یکسان روی همه نودها نصب شده باشند.
### بررسی دسترسیها و احراز هویت
دسترسی SSH بدون رمز عبور (SSH key-based authentication) میان نود مدیریت و سایر نودها باید پیکربندی و آزمایش شود؛ زیرا ابزارهایی مانند Kubespray به چنین پیشنیازی متکی هستند. وجود یک کاربر مدیریتی با دسترسی sudo در همه نودها نیز باید تأیید گردد.
چنانچه برای نگهداری Imageهای کانتینری از Private Registry استفاده میشود، دسترسی به Registry و اعتبارنامههای مربوطه باید از قبل تنظیم و آزمون شود. علاوه بر آن، باید اطمینان حاصل شود که نودها به مخازن رسمی بستههای Kubernetes و container runtime دسترسی دارند.
### تأیید زیرساخت ذخیرهسازی
اگر ذخیرهسازی خارجی مانند NFS یا Ceph مورد استفاده است، اتصال و سطح دسترسی نودها به این سرویسها باید کنترل شود. در سناریوی TopoLVM نیز دیسکهای NVMe لازم است بهدرستی شناسایی شوند و آمادگی پیکربندی بهعنوان Volume Group را داشته باشند. در نهایت، ظرفیت کافی برای ذخیره Imageهای کانتینری و logها روی هر نود باید لحاظ شده باشد.
اجرای این چکلیست، آمادگی زیرساخت برای نصب Kubernetes را با اطمینان بیشتری تثبیت میکند و احتمال بروز خطا در فرآیند استقرار را کاهش میدهد.
فصل ۴: ساخت کلاستر Kubernetes
۴.۱ توپولوژی کلاستر
معماری کلاستر Kubernetes این پروژه با رویکرد **High Availability** طراحی شده تا در برابر خرابیهای محتمل، از حیث **تحمل خطا** و پایداری عملیاتی دچار اختلال نشود. در سطح کلان، کلاستر از دو بخش اصلی تشکیل شده است: صفحه کنترل (Control Plane) و نودهای کاری (Worker Nodes).
صفحه کنترل شامل سه نود Master است که بهصورت توزیعشده مدیریت وضعیت کلاستر را انجام میدهند. این چینش سهنودی، الزامات Quorum در etcd را پوشش میدهد و بنابراین با از دسترس خارج شدن یک نود Master، تداوم سرویسدهی کلاستر حفظ میشود. هر نود Master اجزای کلیدی نظیر kube-apiserver، kube-controller-manager، kube-scheduler و etcd را میزبانی میکند. برای توزیع یکنواخت درخواستهای API نیز یک Load Balancer در لایه ورودی در نظر گرفته شده است تا ترافیک بین نودهای Master متعادل شود.
نودهای Worker محل استقرار بارهای کاری (Workloads) هستند و تعداد آنها متناسب با نیاز محاسباتی پروژه قابل افزایش است. روی هر Worker مؤلفههایی مانند kubelet (برای مدیریت Pod)، kube-proxy (برای وظایف شبکه) و Container Runtime (برای اجرای کانتینرها) فعال است. از منظر نقش عملیاتی، Workerها به دو گروه تقسیم شدهاند: نودهای عمومی برای سرویسهای پلتفرم و نودهای مجهز به GPU که اجرای Notebookهای یادگیری ماشین را بر عهده دارند.
شبکه کلاستر از CNI پشتیبانی میکند و ارتباطهای Pod-to-Pod، Pod-to-Service و دسترسی خارجی را ممکن میسازد. برای جداسازی منطقی منابع و کنترل بهتر امنیت، Namespaceهای مختلف تعریف شدهاند. در نهایت، این توپولوژی ضمن پاسخگویی به نیازهای فنی فعلی، امکان توسعه افقی (Horizontal Scaling) را برای رشد آتی پلتفرم نیز حفظ میکند.
۴.۲ آمادهسازی سیستمعامل: Kernel Params، Runtime، Sysctl
پیش از استقرار Kubernetes، سیستمعامل Ubuntu 20.04 LTS نیازمند پیکربندیهای مشخصی است تا هم از منظر کارایی و هم از حیث ملاحظات امنیتی، بستر اجرای کلاستر پایدار باشد. این آمادهسازی در سه محور انجام میشود: تنظیمات Kernel، نصب و پیکربندی Container Runtime و اعمال پارامترهای Sysctl.
در گام نخست، ماژولهای Kernel مورد نیاز فعال میشوند. برای شبکه کانتینری، بارگذاری ماژولهای `overlay` و `br_netfilter` ضروری است؛ این ماژولها با تعریف در مسیر `/etc/modules-load.d/` بهصورت پایدار پس از هر بوت در دسترس خواهند بود. از سوی دیگر، Swap باید غیرفعال شود؛ زیرا Kubernetes برای مدیریت منابع حافظه به کنترل مستقیم RAM وابسته است و فعال بودن Swap میتواند رفتار زمانبندی و تخصیص منابع را مختل کند.
پیکربندی Sysctl بهمنظور امکانپذیر کردن پردازش صحیح ترافیک بین Podها انجام میشود. بهطور مشخص، پارامترهای `net.bridge.bridge-nf-call-iptables` و `net.bridge.bridge-nf-call-ip6tables` روی مقدار ۱ قرار میگیرند تا Iptables قادر به پردازش ترافیک bridged باشد. همچنین `net.ipv4.ip_forward` برای مسیریابی بستهها میان کانتینرها فعال میشود. این تنظیمات در `/etc/sysctl.d/99-kubernetes.conf` ثبت میشوند تا پس از راهاندازی مجدد نیز حفظ شوند.
در انتخاب Container Runtime، معیار اصلی همراستایی با CRI و سبکبودن سرویس اجرایی بوده است؛ از این رو، در این پروژه از containerd استفاده شده است. پس از نصب، فایل پیکربندی `/etc/containerd/config.toml` بهگونهای تنظیم میشود که systemd بهعنوان Cgroup driver بهکار گرفته شود. این همگرایی با systemd، مدیریت منابع را منسجمتر کرده و از ناسازگاریهای ناشی از تفاوت Cgroup drivers جلوگیری میکند.
همزمان، برخی تنظیمات امنیتی پایه نیز اعمال میشود: پیکربندی Firewall، غیرفعالسازی SELinux یا قرار دادن آن در وضعیت Permissive، و همگامسازی ساعت سیستم از طریق NTP بهمنظور یکسانسازی timestampها در سطح کلاستر.
۴.۳ مراحل نصب Kubernetes
استقرار Kubernetes با Kubespray انجام شده است؛ ابزاری مبتنی بر Ansible که فرآیند استقرار را اتوماتیک کرده و برای محیطهای Production-Ready مناسب است. استفاده از Kubespray در مقایسه با نصب دستی مبتنی بر kubeadm، امکان تکرارپذیری، کنترل بهتر پیکربندیها و کاهش خطای انسانی را فراهم میکند.
فرآیند با آمادهسازی Inventory در Ansible آغاز میشود؛ در این فایل، نودهای Master و Worker معرفی شده و متغیرهای پیکربندی کلاستر تعریف میگردند. پارامترهای اصلی شامل نسخه Kubernetes، انتخاب CNI Plugin (در این پروژه Calico)، محدودههای Pod و Service CIDR و تنظیمات etcd است. انتخاب Calico با توجه به پشتیبانی از NetworkPolicy و عملکرد مناسب در مقیاسهای بالاتر انجام شده است.
Kubespray وابستگیهای ضروری را نصب میکند (از جمله kubeadm، kubelet، kubectl و Container Runtime) و سپس از طریق Playbookهای Ansible، ابتدا کلاستر etcd را بهعنوان مخزن توزیعشده وضعیت کلاستر راهاندازی میکند. پس از آن، اجزای Control Plane روی نودهای Master مستقر میشوند و API Server بهعنوان نقطه ورودی مرکزی فعال میگردد.
در مرحله بعد، نودهای Worker به کلاستر ملحق میشوند. این بخش شامل ایجاد Tokenهای امنیتی، پیکربندی kubelet روی هر Worker و ثبت نودها در API Server است. مدیریت CA و گواهیهای TLS نیز توسط Kubespray انجام میشود تا ارتباط میان مؤلفهها با کانال امن برقرار بماند.
پس از تکمیل نصب، اعتبارسنجی کلاستر با دستورهایی مانند `kubectl get nodes` و `kubectl get pods --all-namespaces` انجام میشود. انتظار میرود همه نودها در وضعیت Ready و Podهای سیستمی مرتبط با CoreDNS، kube-proxy و CNI در حالت Running باشند. در نهایت، دسترسی به API Server از خارج کلاستر و ارتباط میان Podها نیز بررسی میشود تا آمادگی کلاستر برای استقرار Workloadهای تولیدی تأیید گردد.
۴.۴ استقرار CNI و خطمشیهای پایه NetworkPolicy
در کلاسترهای کانتینری، شبکه نقش زیرساختی تعیینکننده دارد؛ زیرا هر Pod باید IP مستقل داشته باشد و بتواند با سرویسها و سایر Podها ارتباط برقرار کند. این وظیفه در Kubernetes از طریق CNI پیادهسازی میشود. در این پروژه، پس از ارزیابی گزینههایی مانند Calico، Cilium و Flannel، با توجه به الزامات امنیتی و عملکردی، Calico انتخاب شد.
Calico در ابتدای راهاندازی کلاستر و پس از آمادهشدن نودهای Master مستقر شد. این افزونه با فراهمکردن یک Overlay Network مبتنی بر BGP، ارتباط میان Podهایی را که روی نودهای مختلف قرار دارند برقرار میکند. مزیت مهم Calico، قابلیتهای پیشرفته در NetworkPolicy است که امکان کنترل دقیق دسترسی شبکه در سطح Pod را فراهم میسازد.
پس از استقرار CNI، خطمشیهای پایه امنیت شبکه بهصورت Namespace-based اعمال شدند. سیاست پیشفرض در هر Namespace، مسدود بودن ترافیک ورودی است و تنها ارتباطاتی که بهطور صریح تعریف شوند مجاز خواهند بود (Default Deny Policy). این رویکرد همراستا با Zero-Trust، سطح حمله را در لایه شبکه کاهش میدهد.
بهعنوان نمونه، برای Namespace مربوط به JupyterHub، NetworkPolicy بهگونهای تعریف شد که فقط Ingress Controller مجاز به دسترسی به Podهای JupyterHub باشد؛ در مقابل، Podهای Notebook کاربران امکان دسترسی کنترلشده به سرویسهای مشترک مانند DNS و برخی سرویسهای داخلی را دارند. نگهداری این سیاستها بهشکل فایلهای YAML در مخزن GitOps انجام میشود و اعمال آنها نیز توسط ArgoCD صورت میگیرد؛ در نتیجه، نسخهبندی، بازبینی و ردیابی تغییرات سیاستهای امنیتی در یک چرخه متمرکز قابل انجام است.
۴.۵ راهاندازی Ingress Controller و TLS Strategy
ارائه سرویسهای مستقر روی Kubernetes به کاربران بیرونی، به لایهای برای مدیریت ترافیک HTTP/HTTPS نیاز دارد؛ این وظیفه بر عهده Ingress Controller است. در معماری این پلتفرم، NGINX Ingress Controller بهعنوان نقطه ورود اصلی انتخاب شده است؛ انتخابی که بر مبنای پایداری، کارایی و پشتیبانی مناسب از قابلیتهایی مانند SSL Termination و Path-based Routing انجام شد.
NGINX Ingress Controller در Namespace اختصاصی `ingress-nginx` مستقر شده است. برای تأمین دسترسپذیری بالا، تعداد Replicaها متناسب با ظرفیت نودهای Worker تنظیم شد و به کمک DaemonSet روی نودهای دارای Label مشخص اجرا گردید. مسیر ورود ترافیک نیز به این صورت است که درخواستها ابتدا به HAProxy در لایه بیرونی کلاستر میرسند و سپس به NodePort سرویس Ingress Controller توزیع میشوند.
در لایه امنیت انتقال، مدیریت گواهیهای TLS اهمیت ویژه دارد. در این پروژه، cert-manager برای صدور و تمدید خودکار گواهیها بهکار گرفته شده است. cert-manager با تکیه بر ACME و ارائهدهنده Let's Encrypt، گواهیهای معتبر را صادر کرده و تمدید آنها را نیز بدون مداخله دستی انجام میدهد.
برای هر سرویس قابل دسترس از بیرون، یک منبع Ingress تعریف میشود که قوانین مسیریابی و تنظیمات TLS را در بر میگیرد. برای مثال، سرویس JupyterHub از طریق دامنه اختصاصی و با گواهی معتبر در دسترس است. cert-manager پیش از انقضای گواهی، فرآیند تمدید را آغاز کرده و گواهی جدید را در Secret مرتبط ذخیره میکند. نتیجه این رویکرد، کاهش ریسک خطای عملیاتی و تثبیت سطح امنیت ارتباطات است.
۴.۶ اتصال Storage به Kubernetes با استفاده از CSI
در محیطهای Cloud-Native، بارهای کاری Stateful نیازمند ذخیرهسازی پایدار (Persistent Storage) هستند و مدیریت این نیاز، بدون یک استاندارد یکپارچه دشوار میشود. CSI این استاندارد را فراهم میکند تا سامانههای ذخیرهسازی گوناگون بتوانند بهصورت سازگار به Kubernetes متصل شوند. با توجه به نیاز پروژه به کارایی مناسب در سناریوهای AI/ML، TopoLVM بهعنوان CSI Driver انتخاب شد.
TopoLVM یک CSI مبتنی بر LVM (Logical Volume Manager) است که امکان استفاده مستقیم از دیسکهای محلی نودها را فراهم میکند. نسبت به راهکارهای شبکهای مانند NFS، استفاده از ذخیرهسازی محلی معمولاً تأخیر (Latency) کمتری در I/O ایجاد میکند؛ موضوعی که برای پردازش داده و آموزش مدلها اهمیت دارد. TopoLVM همچنین از Topology-Aware Scheduling پشتیبانی میکند؛ به این معنا که Podها بر اساس ظرفیت ذخیرهسازی موجود، روی نود مناسب زمانبندی میشوند.
استقرار TopoLVM شامل نصب کنترلر مرکزی و اجرای DaemonSet روی نودهای Worker است. در هر نود، ابتدا یک Volume Group اختصاصی از دیسکهای NVMe ایجاد شد و سپس TopoLVM Node Plugin بر مبنای آن پیکربندی گردید. پس از راهاندازی، چند StorageClass با سطوح عملکرد متفاوت تعریف شد: `topolvm-ssd` برای بارهای کاری با IOPS بالا و `topolvm-standard` برای استفاده عمومی.
Dynamic Provisioning نیز در این طراحی فعال است. کافی است برای هر سرویس، یک PersistentVolumeClaim (PVC) با StorageClass مناسب تعریف شود؛ TopoLVM بهصورت خودکار Logical Volume را روی نود مقصد ایجاد کرده و آن را به Pod متصل میکند. این شیوه، مدیریت فضای ذخیرهسازی را سادهتر کرده و رشد تدریجی کلاستر را بدون افزایش پیچیدگی عملیاتی پشتیبانی میکند.
۴.۷ فعالسازی GPU NVIDIA
برای پلتفرم یادگیری ماشین، دسترسی پایدار و نزدیک به توان واقعی سختافزار GPU یک الزام عملیاتی است. در این پروژه، PCI Passthrough در Proxmox VE بهکار گرفته شد تا کارتهای گرافیک فیزیکی بهصورت مستقیم به ماشینهای مجازی تخصیص داده شوند. این روش، در مقایسه با مجازیسازیهای متداول GPU، افت کارایی را به حداقل میرساند.
اجرای PCI Passthrough مستلزم فعالسازی IOMMU در BIOS سرورهای فیزیکی و اعمال پیکربندی ماژولهای VFIO در هسته لینوکس است. پس از اختصاص GPUهای NVIDIA به نودهای Worker منتخب، یکپارچهسازی GPU با Kubernetes انجام شد. برای این منظور، NVIDIA GPU Operator بهعنوان راهکار استاندارد و یکپارچه انتخاب گردید.
GPU Operator چرخه حیات مؤلفههای لازم برای بهرهبرداری از GPU در کانتینرها را مدیریت میکند؛ از جمله استقرار درایورهای NVIDIA، کتابخانههای CUDA و cuDNN، NVIDIA Container Toolkit و Device Plugin مورد نیاز برای شناسایی و زمانبندی منابع GPU. علاوه بر این، DCGM Exporter برای پایش شاخصهای عملکردی GPU نصب میشود.
استقرار GPU Operator از طریق Helm Chart انجام شد و تنظیمات متناسب با معماری کلاستر اعمال گردید. پس از تکمیل این مرحله، کلاستر قادر به شناسایی نوع و تعداد GPUهای هر نود شد و در نتیجه Podهایی که GPU را در resource requests مشخص میکنند، بهصورت خودکار روی نودهای دارای GPU زمانبندی میشوند. برای اعتبارسنجی نهایی، Podهای آزمایشی مبتنی بر CUDA اجرا شد و صحت یکپارچهسازی تأیید گردید.
فصل ۵: پیادهسازی لایه سرویسهای در سطح کاربر
۵.۱ مدل دسترسی چندکاربره
در معماری پلتفرم، لایه سرویسهای کاربر بر مبنای مدل چندکاربره (Multi-tenant) طراحی شده است؛ بهگونهای که هر محقق یا تیم تحقیقاتی در محیطی ایزوله از سایرین فعالیت میکند. این ایزولاسیون در چند سطح اعمال میشود: نخست در سطح Namespaceهای Kubernetes که برای هر کاربر یا پروژه فضای نام اختصاصی در نظر گرفته شده است؛ سپس در سطح شبکه با NetworkPolicyهای Calico برای کنترل ترافیک بین Namespaceها؛ و در نهایت در سطح منابع محاسباتی با اتکا به ResourceQuota و LimitRange.
احراز هویت کاربران با یکپارچهسازی با SSO سازمانی و پروتکل OIDC انجام میگیرد. مدیریت دسترسیها بهصورت متمرکز و از طریق تعریف Role و RoleBinding در Kubernetes پیش میرود؛ به این ترتیب، نقشهای متفاوتی برای کاربران عادی، سرپرستان پروژه و مدیران سیستم تعریف شده است. مطابق این سیاست، هر کاربر صرفاً به منابع Namespace خود دسترسی دارد و امکان ورود به محیط سایر کاربران یا اعمال تغییر در تنظیمات سطح کلاستر را ندارد.
برای تضمین تخصیص منصفانه منابع، سیاستهای سهمیهبندی پویا پیادهسازی شده است. سهمیه هر کاربر متناسب با نیاز پروژه و اولویت آن تعیین میشود و شامل CPU، حافظه و GPU است. این سهمیهها قابلیت تنظیم دارند و در صورت بلااستفادهماندن، منابع آزادشده در اختیار صف انتظار سایر کاربران قرار میگیرد. افزون بر این، از Priority Class در Kubernetes برای اولویتبندی بارهای کاری استفاده شده است.
۵.۲ پلتفرم JupyterHub و پروفایلهای GPU/CPU
JupyterHub بهعنوان بستر اصلی تعامل کاربران با زیرساخت محاسباتی انتخاب شده است. این سامانه امکان ایجاد محیطهای Notebook اختصاصی را فراهم میکند؛ بهطوری که هر Notebook در قالب یک Pod مستقل روی Kubernetes اجرا میشود. استقرار JupyterHub با Helm Chart رسمی انجام شده و برای نیازهای محیط تحقیقاتی، پیکربندیهای سفارشی روی آن اعمال گردیده است.
در این پیادهسازی، «پروفایلهای محاسباتی» بهعنوان یکی از مؤلفههای اصلی در نظر گرفته شده است. کاربر هنگام راهاندازی Notebook میتواند از میان پروفایلهای از پیش تعریفشده انتخاب کند: پروفایل CPU-Only برای پردازش داده و تحلیلهای سبک، پروفایل GPU-Single برای آموزش مدلهای یادگیری ماشین با یک GPU، و پروفایل GPU-Multi برای سناریوهایی که به چند GPU نیاز دارند. هر پروفایل، مقادیر مشخصی از CPU، حافظه، تعداد GPU و نیز Imageهای کانتینر متناظر را تعیین میکند.
Imageهای کانتینر بهصورت لایهای ساخته شدهاند: یک Image پایه با کتابخانههای علمی متداول مانند NumPy و Pandas، مجموعه Imageهای مجهز به CUDA و cuDNN برای پردازشهای GPU، و Imageهای تخصصی برای فریمورکهایی نظیر TensorFlow یا PyTorch. در کنار این موارد، امکان تعریف Image سفارشی مطابق نیازهای هر پروژه نیز فراهم شده است. ذخیرهسازی دائمی دادههای کاربران از طریق PVCهای متصل به هر Pod تأمین میشود تا دادهها پس از بستهشدن Notebook نیز حفظ شوند.
۵.۳ روش اجرای Batch Job/CronJob، صف و اولویتها
برای اجرای کارهای پردازشی سنگین که به تعامل مستقیم کاربر وابسته نیستند، از Job و CronJob در Kubernetes استفاده میشود. این سازوکار اجرای خودکار فرآیندهای طولانیمدت—مانند آموزش مدلهای یادگیری عمیق یا پردازش دستهای داده—را بدون نیاز به پایش مستمر ممکن میکند.
صفبندی کارها با ترکیبی از Priority Classهای Kubernetes و یک کنترلر سفارشی انجام شده است. کارها در سه سطح اولویت دستهبندی میشوند: High برای کارهای فوری و پروژههای دارای ددلاین نزدیک، Normal برای فعالیتهای رایج پژوهشی، و Low برای اجراهای آزمایشی یا کماهمیت. در صورت کمبود منابع، کارها وارد صف میشوند و بهمحض آزادشدن منابع، با لحاظ اولویت و زمان ثبت، اجرا خواهند شد.
CronJobها برای زمانبندی دورهای به کار میروند و در وظایفی از قبیل بازآموزی دورهای مدلها، پردازش دادههای ورودی جدید یا تولید گزارشهای عملکردی کاربرد دارند. هر CronJob با Concurrency Policy مشخص میکند که اجرای همزمان مجاز است یا باید تا پایان اجرای قبلی منتظر ماند.
در کنار این موارد، مکانیزم Preemption نیز فعال شده است؛ بنابراین، هنگامی که منابع برای کارهای با اولویت بالاتر لازم باشد، کارهای کماولویت متوقف میشوند تا منابع آزاد گردد. این رفتار با تعریف PriorityClassهای متناسب و تنظیم preemptionPolicy در هر کلاس کنترل میشود.
۵.۴ ذخیرهسازی مشترک Dataset و Checkpoint
مدیریت دادههای آموزشی و وضعیتهای میانی مدل از مسائل مهم در محیطهای یادگیری ماشین است. در پلتفرم حاضر، لایه ذخیرهسازی مشترک بهنحوی طراحی شده است که دسترسی همزمان چندین Pod به Datasetهای حجیم و فایلهای Checkpoint را با کارایی مناسب پشتیبانی کند.
این معماری بر TopoLVM استوار است و با بهرهگیری از قابلیتهای LVM، ذخیرهسازی بلوکی محلی را در سطح کلاستر مدیریت میکند. در مقایسه با راهکارهای متداول مبتنی بر فایلسیستم شبکهای، تأخیر دسترسی کاهش مییابد. برای هر نود ورکر، یک Volume Group اختصاصی بر اساس درایوهای NVMe محلی ایجاد شده است و TopoLVM بهصورت خودکار Logical Volumeهای موردنیاز را مطابق درخواستهای PVC تخصیص میدهد.
در لایه Kubernetes سه StorageClass مجزا تعریف شده است: dataset-storage برای دادههای آموزشی با سیاست ReadOnlyMany، checkpoint-storage برای ذخیره وضعیت مدلها با قابلیت ReadWriteOnce، و shared-workspace برای فضای کاری مشترک تیمها با حالت ReadWriteMany. این تفکیک اجازه میدهد سیاستهای بهینهسازی متناسب با ماهیت هر نوع داده اعمال شود.
برای Datasetهای بزرگ که در چند آزمایش بهطور همزمان مصرف میشوند، از Volume Cloning استفاده شده است. این قابلیت با Snapshotهای LVM، نسخههای سبک ایجاد میکند و از کپی فیزیکی غیرضروری میکاهد. همچنین برای Checkpointهای حجیم، سیاست Backup خودکار به Object Storage خارجی پیادهسازی شده است تا احتمال از دسترفتن داده در شرایط بحرانی کاهش یابد.
چرخه حیات دادهها نیز با یک Operator اختصاصی مدیریت میشود؛ به این ترتیب که Volumeهای بلااستفاده شناسایی شده و پس از سپریشدن دوره نگهداری تعیینشده، بهصورت خودکار حذف میگردند.
۵.۵ رجیستری داخلی و مدیریت Imageها
برای کاهش وابستگی به منابع خارجی و حفظ استقلال عملیاتی، رجیستری داخلی Container Image در نظر گرفته شده است. این رجیستری علاوه بر نگهداری Imageهای سفارشی کاربران، نقش Cache محلی برای Imageهای عمومی پرکاربرد را نیز ایفا میکند.
پیادهسازی رجیستری بر پایه Harbor انجام شده است. Harbor در قالب Helm Chart مستقر شده و برای متادیتا از PostgreSQL و برای Caching از Redis استفاده میکند. ذخیرهسازی Imageها نیز به TopoLVM متصل است تا کارایی خواندن و نوشتن در سطح مطلوب حفظ شود.
یکپارچگی احراز هویت از طریق OIDC صورت گرفته است؛ بنابراین کاربران با همان اعتبارنامههای مورد استفاده برای JupyterHub به رجیستری متصل میشوند. سیاستهای دسترسی نیز بر اساس نقشهای تعریفشده در Keycloak اعمال میگردد؛ برای نمونه، کاربران عادی تنها مجاز به مدیریت Imageهای مربوط به Namespace اختصاصی خود هستند.
بهمنظور ارتقای امنیت، Image Scanning با Trivy فعال شده است. هر Image پیش از مجازشدن برای استفاده در کلاستر، بهصورت خودکار از نظر آسیبپذیریهای شناختهشده بررسی میشود. در صورت مشاهده آسیبپذیری با سطح بحرانی، Image قرنطینه میشود و اعلان لازم برای مدیر سیستم ارسال میگردد.
فرآیندهای Pull و Push نیز با هدف کاهش بار شبکه بهینه شدهاند. Image Replication باعث میشود Imageهای پرمصرف بهصورت پیشگیرانه در رجیستری محلی کش شوند. همچنین Garbage Collection بهصورت دورهای اجرا میشود تا Layerهای بلااستفاده حذف و فضای ذخیرهسازی مدیریت شود.
۵.۶ اجزای پایه MLOps
پشتیبانی کامل از چرخه توسعه مدلهای یادگیری ماشین مستلزم زیرساختی است که آزمایش، آموزش، ارزیابی و استقرار را در قالبی منسجم پوشش دهد. لایه MLOps پلتفرم با تکیه بر مجموعهای از ابزارهای متنباز و یکپارچه این نیاز را پاسخ میدهد.
در این لایه، MLflow بهعنوان بستر مدیریت چرخه حیات مدل به کار گرفته شده است و در سه جزء اصلی مستقر میشود: Tracking Server برای ثبت آزمایشها و معیارها، Model Registry برای نسخهبندی و مدیریت مدلهای آموزشدیده، و Projects برای بستهبندی کد قابلبازتولید. دسترسی به سرویس از طریق Ingress فراهم شده و با سامانه احراز هویت یکپارچه ادغام گردیده است.
برای ارکستراسیون Pipelineهای چندمرحلهای، Kubeflow Pipelines پیادهسازی شده است. این ابزار امکان تعریف گردشکار با Python SDK را فراهم میکند؛ هر مرحله بهصورت یک Job مستقل روی Kubernetes اجرا میشود و تبادل خروجیها از طریق Artifact Store مشترک صورت میگیرد. قابلیت Caching نیز فعال است تا مراحل تکراری، در صورت امکان، از نتایج قبلی استفاده کنند.
در سطح نیازهای پیشرفتهتر، Kubeflow Training Operators نصب شدهاند تا الگوهای آموزش توزیعشده را پوشش دهند؛ از جمله TFJob برای TensorFlow، PyTorchJob برای PyTorch و MPIJob برای سناریوهای MPI-based. این Operatorها مدیریت Podهای Worker و Parameter Server و نیز پیکربندی شبکه بین آنها را بهصورت خودکار انجام میدهند.
یکپارچگی اجزا از طریق یک Dashboard مرکزی فراهم شده است؛ بهطوری که کاربر میتواند از محیط JupyterLab، Pipeline تعریف کند، آزمایش را در MLflow ثبت نماید و نتیجه را در Model Registry منتشر سازد. این زنجیره یکپارچه، مسیر انتقال مدل از مرحله آزمایش تا بهرهبرداری را کوتاهتر میکند.
۵.۷ مدیریت Secrets و Configuration
در استقرار سرویسهای کاربری، مدیریت ایمن دادههای حساس و پیکربندیهای متغیر اهمیت ویژه دارد. در معماری حاضر، برای تفکیک دادههای پیکربندی از منطق اپلیکیشن، رویکردی چندلایه اتخاذ شده است.
تنظیمات غیرحساس در ConfigMap نگهداری میشوند؛ از جمله پیکربندیهای محیطی، آدرس سرویسها و پارامترهای عملیاتی. این روش تغییر تنظیمات را بدون نیاز به بازسازی Imageهای کانتینری ممکن میکند. بهعنوان نمونه، تنظیمات JupyterHub شامل آدرس سرویس احراز هویت، سقف پیشفرض مصرف منابع و پیکربندی شبکه در یک ConfigMap مستقل ذخیره شده است.
اطلاعات حساس—مانند کلیدهای API، گواهینامههای TLS و رمزهای عبور پایگاه داده—از طریق Secret مدیریت میشوند. در مقایسه با ConfigMap که دادهها را بهصورت متن ساده نگه میدارد، Secret امکان رمزنگاری دادهها در سطح etcd را فراهم میکند. در این پیادهسازی، کلیدهای خصوصی گواهینامههای SSL، توکنهای احراز هویت OAuth2 و اطلاعات دسترسی به سامانههای خارجی در Secret ذخیره شدهاند.
کنترل دسترسی به Secret با RBAC محدود شده است تا فقط Podهای مجاز امکان استفاده از دادههای حساس را داشته باشند. همچنین Secretها بهصورت volume در کانتینر mount میشوند تا از قرارگرفتن آنها در متغیرهای محیطی—که ریسک افشا در آنها بالاتر است—پرهیز شود.
در مدیریت پیکربندی، الگوی immutable configuration نیز رعایت شده است؛ یعنی با هر تغییر، نسخه جدیدی از ConfigMap یا Secret ایجاد و Deployment مرتبط بهروزرسانی میشود. نتیجه این رویکرد، امکان ردیابی تغییرات و بازگشت سریع به نسخههای قبلی است.
۵.۸ پیادهسازی GitOps
برای مدیریت چرخه حیات اپلیکیشنها، رویکرد GitOps بهکار گرفته شده است؛ به این معنا که Git نقش منبع واحد حقیقت (Single Source of Truth) را برای تعاریف زیرساختی و پیکربندیهای کلاستر ایفا میکند.
در این چارچوب، ArgoCD بهعنوان ابزار همگامسازی وضعیت کلاستر با مخزن Git انتخاب شده است. manifestهای Kubernetes شامل Deployment، Service، Ingress و سایر منابع، در ساختار دایرکتوری مشخصی سازماندهی شدهاند. ArgoCD بهصورت پیوسته مخزن را پایش میکند و هر اختلاف میان وضعیت تعریفشده و وضعیت واقعی کلاستر را تشخیص میدهد.
فرآیند استقرار بدین ترتیب انجام میشود که توسعهدهندگان تغییرات را در شاخه مربوطه commit میکنند و پس از بازبینی و تأیید، به شاخه اصلی merge میشود. سپس ArgoCD تغییرات را اعمال میکند؛ این اعمال میتواند خودکار باشد یا با تأیید دستی انجام شود. در کنار اتوماسیون، قابلیت ممیزی (Audit) نیز بهواسطه ثبت تاریخچه تغییرات در Git فراهم است.
برای جداسازی محیطها (توسعه، آزمون، تولید)، ساختار چندمخزنی به کار رفته است. هر محیط مخزن یا شاخه مستقل دارد و ArgoCD Application متناظر با همان محیط تعریف شده است؛ بنابراین، امکان ارزیابی تغییرات در محیط staging پیش از اعمال روی تولید فراهم میشود.
بازگشت (Rollback) نیز از مزیتهای مستقیم این رویکرد است: در صورت بروز مسئله، با بازگردانی به commit قبلی، کلاستر به وضعیت پایدار قبل بازمیگردد. در نهایت، استفاده از Helm و Chart در کنار ArgoCD، مدیریت پیکربندیهای پیچیدهتر را تسهیل کرده است.
فصل ۶: پایش، سختسازی امنیتی، آزمونها و تحویل نهایی
۶.۱ معماری Observability
پلتفرم GPU-as-a-Service به دلیل ماهیت چندلایه و ناهمگونی منابع سختافزاری، به معماری منسجم Observability نیاز دارد. این معماری بر سه مؤلفه اصلی متریکها (Metrics)، لاگها (Logs) و ردیابی توزیعشده (Distributed Tracing) تکیه دارد. در لایه پایه، Prometheus نقش موتور گردآوری و نگهداشت دادههای time-series را ایفا میکند و با تکیه بر Service Discovery در Kubernetes، اهداف پایش را بهصورت خودکار شناسایی و ثبت مینماید.
پایش منابع GPU با NVIDIA DCGM Exporter انجام میشود؛ بهگونهای که متریکهایی مانند دمای GPU، میزان استفاده از حافظه، توان مصرفی و خطاهای سختافزاری استخراج و منتشر میگردد. این دادهها در کنار متریکهای سطح Kubernetes (از جمله مصرف CPU و حافظه Pod ها) تحلیل میشوند تا تصویری یکپارچه از وضعیت بار کاری و سلامت زیرساخت فراهم شود. در ادامه، Alertmanager وظیفه مدیریت چرخه هشدارها را بر عهده دارد و با سازوکارهای grouping و throttling، از تولید هشدارهای تکراری و پرنویز جلوگیری میکند.
در لایه ارائه، Grafana بهعنوان ابزار بصریسازی به کار گرفته شده و داشبوردهای متناسب با نقشهای مختلف عملیاتی و توسعهای را در اختیار قرار میدهد. برای تأمین مقیاسپذیری در سناریوهای چندکلاستری، معماری Prometheus مبتنی بر federation طراحی شده است. اجزای پایش نیز در یک Namespace اختصاصی مستقر شدهاند و با اعمال NetworkPolicy، دسترسیها به حداقل لازم محدود گردیده است. در این چارچوب، نگهداشت متریکها برای حداقل سه ماه، با granularity متغیر متناسب با نوع داده و نیاز تحلیلی، پیشبینی شده است.
۶.۲ پیادهسازی Monitoring و داشبوردهای GPU
استقرار سامانه پایش در دو گام پیش رفته است. ابتدا NVIDIA GPU Operator بهصورت خودکار DCGM Exporter را روی همه نودهای دارای GPU مستقر میکند. این Exporter با استفاده از DCGM API به درایور NVIDIA متصل میشود و متریکهای لحظهای را در قالب سازگار با Prometheus در اختیار قرار میدهد. سپس، Prometheus Operator با Helm Chart رسمی نصب شده و از طریق تعریف ServiceMonitor، اهداف پایش بهصورت اعلانی (declarative) معرفی شدهاند.
داشبوردهای Grafana در سه سطح طراحی شدهاند:
1) داشبورد کلاستر برای ارائه نمای کلی از وضعیت نودها و GPU ها،
2) داشبورد Namespace برای تیمهای توسعه با تمرکز بر مصرف منابع JupyterHub و Notebook های فعال،
3) داشبورد تخصصی GPU شامل نمودارهای دما، توان، memory utilization و GPU utilization.
بهمنظور تسهیل تحلیل، این داشبوردها از متغیرهای پویا استفاده میکنند تا جابهجایی بین نودها و Namespace ها بدون نیاز به بازپیکربندی دستی انجام شود.
در حوزه هشدارهای بحرانی، قوانین alerting در Prometheus تعریف شدهاند که از جمله آنها میتوان به موارد زیر اشاره کرد: دمای GPU بالاتر از 85 درجه، استفاده از حافظه GPU بیش از 90 درصد، خطاهای ECC در حافظه GPU، و قطع ارتباط با DCGM Exporter. مسیر ارسال این هشدارها در Alertmanager به کانالهایی مانند Slack و ایمیل متصل است. برای کاهش false positive نیز inhibition rules در نظر گرفته شده تا در صورت فعال بودن هشدارِ علت اصلی، هشدارهای وابسته بهطور خودکار سرکوب شوند.
۶.۳ پیادهسازی Logging و Audit Trail
زیرساخت Logging با هدف جمعآوری متمرکز، نمایهسازی و امکان جستجوی سریع طراحی شده است. در این معماری، Fluent Bit بهعنوان agent سبکوزن روی همه نودها اجرا میشود و لاگهای کانتینرها را از مسیر /var/log/containers دریافت میکند. پس از پردازش اولیه و enrichment با metadata های Kubernetes (از جمله نام Pod، Namespace و label ها)، دادهها به Elasticsearch ارسال میشوند. Elasticsearch نیز با سازماندهی لاگها در index های روزانه، امکان تحلیل و بازیابی مؤثر را فراهم میکند.
برای مدیریت چرخه حیات دادهها، سیاست Index Lifecycle Management اعمال شده است؛ به این ترتیب لاگهای قدیمیتر از 30 روز به warm storage منتقل میشوند و پس از 90 روز حذف میگردند. Kibana بهعنوان رابط تحلیل و جستجو مورد استفاده قرار گرفته و داشبوردهایی برای الگوهای رایج خطا و رویدادهای امنیتی آماده شده است. کنترل دسترسی نیز با Spaces در Kibana پیادهسازی شده تا هر تیم صرفاً به لاگهای Namespace مربوط به خود دسترسی داشته باشد.
در بخش Audit Trail، Kubernetes Audit Logs فعال شده و با تعریف سیاستهای دقیق، رویدادهای حساس مانند ایجاد/حذف Secret ها، تغییرات RBAC و دسترسی به منابع GPU ثبت میشوند. لاگهای audit در index مجزا نگهداری شده و با retention policy طولانیتر (یک سال) ذخیره میگردند. افزون بر نگهداشت، alert های خودکار برای الگوهای مشکوک—از جمله تلاشهای ناموفق احراز هویت بهصورت متوالی، دسترسی به منابع غیرمجاز و تغییرات ناگهانی در پیکربندیهای حیاتی—تنظیم شده است.
۶.۴ پیادهسازی Alerting
در معماری پایش، هشداردهی حلقه اتصال بین دادههای خام متریک و اقدام عملیاتی است. بر همین اساس، Alertmanager در کنار Prometheus مستقر شده تا مدیریت، گروهبندی و توزیع هشدارها بهصورت متمرکز انجام گیرد.
قواعد هشدار در Prometheus در سه دسته تنظیم شدهاند: هشدارهای زیرساختی، هشدارهای مرتبط با GPU و هشدارهای سطح اپلیکیشن. در لایه زیرساخت، سلامت Node ها، مصرف CPU و حافظه، و وضعیت دیسک پایش میشود. برای نمونه، قانون NodeMemoryPressure زمانی فعال میگردد که مصرف حافظه از 85 درصد فراتر رود و این وضعیت بیش از 5 دقیقه پایدار بماند.
برای GPU نیز قوانین اختصاصی در نظر گرفته شده است؛ از جمله پایش دمای کارتها، استفاده از حافظه GPU و وضعیت عملیاتی DCGM Exporter. بهعنوان مثال، هشدار GPUTemperatureHigh در صورت عبور دمای GPU از 80 درجه سانتیگراد با اولویت بالا صادر میشود تا احتمال آسیب سختافزاری کاهش یابد.
Alertmanager با الگوی routing tree پیکربندی شده است تا هشدارها بر مبنای severity و منشأ، به مسیرهای متفاوت هدایت شوند. هشدارهای critical بهصورت فوری به تیم DevOps ارسال میشوند، در حالیکه هشدارهای warning پس از گروهبندی، در بازههای زمانی مشخص توزیع میگردند تا از alert fatigue جلوگیری شود. برای کنترل تکرار هشدار نیز سازوکارهای inhibition و silencing به کار گرفته شدهاند؛ بهطور نمونه، در صورت خارج شدن کامل یک Node از دسترس، هشدارهای مربوط به Pod های همان Node بهصورت خودکار سرکوب میشوند تا تمرکز تیم روی علت اصلی باقی بماند.
۶.۵ هاردنینگ امنیتی در سطح کلاستر کوبرنتیز
سختسازی امنیتی کلاستر Kubernetes با رویکرد چندلایه و مبتنی بر اصل defense in depth انجام شده است. اقدامات اجرایی با اتکا به CIS Kubernetes Benchmark و توصیههای امنیتی NSA طراحی و پیادهسازی گردید.
در سطح احراز هویت و مجوزدهی، RBAC (Role-Based Access Control) بهصورت دقیق تنظیم شده است. بهجای اتکا به ClusterRole های پیشفرض با دامنه دسترسی وسیع، Role های سفارشی بر اساس اصل least privilege تعریف گردید. برای هر Namespace، ServiceAccount های مجزا ایجاد و فقط دسترسیهای ضروری به آنها اعطا شد. همچنین استفاده از ServiceAccount پیشفرض در Namespace ها غیرفعال شده تا احتمال دسترسیهای ناخواسته کاهش یابد.
Pod Security Standards در سه سطح Privileged، Baseline و Restricted تعریف و اعمال شدهاند. برای Namespace های حساس، از جمله فضای کاری کاربران، سطح Restricted در نظر گرفته شده که محدودیتهایی مانند منع اجرای Container با کاربر root، الزام به تعریف resource limits و جلوگیری از بهکارگیری قابلیتهای پرریسک Linux را شامل میشود.
در لایه شبکه، NetworkPolicy بهمنظور microsegmentation پیادهسازی شده است. سیاست پیشفرض برای ترافیک ورودی به Pod ها حالت deny دارد و ارتباطات مجاز فقط بهصورت صریح تعریف میشوند. این رویکرد zero-trust سبب میشود در صورت نفوذ به یک Pod، امکان lateral movement در کلاستر تا حد زیادی محدود گردد.
برای حفاظت از دادههای حساس، Secret ها در etcd به شکل رمزنگاریشده ذخیره میشوند. پیکربندی encryption at rest با KMS provider فعال شده و کلیدهای رمزنگاری نیز بهصورت دورهای چرخش داده میشوند. دسترسی به API Server صرفاً از طریق TLS نسخه 1.3 و با cipher suite های قوی مجاز است و پروتکلهای قدیمیتر غیرفعال شدهاند.
فصل هفتم: خلاصه، نتیجهگیری و کارهای آینده
۷-۱ خلاصه
این پروژه بر طراحی و پیادهسازی یک پلتفرم Cloud-Native برای یادگیری ماشین، با تمرکز بر Kubernetes، استوار بود. زیرساخت نهایی بهصورت یک کلاستر متشکل از سه نود Master و چندین نود Worker پیادهسازی شد و استقرار آن با Kubespray انجام گرفت. در لایه مجازیسازی، از Proxmox VE و KVM استفاده شد و برای دسترسی مستقیم به GPUهای NVIDIA نیز قابلیت PCI Passthrough فراهم گردید.
شبکه کلاستر با تکیه بر Calico CNI و با پشتیبانی از NetworkPolicy طراحی شد تا ایزولهسازی ترافیک میان Namespaceها بهصورت سیاستمحور امکانپذیر باشد. در حوزه ذخیرهسازی محلی، TopoLVM مبتنی بر LVM بهکار گرفته شد تا تخصیص دینامیک حجمهای ذخیرهسازی، با latency پایین و متناسب با نیاز workloadهای ML، انجام شود.
یکی از اجزای محوری کار، یکپارچهسازی GPU Operator بود؛ بهنحوی که مدیریت درایورهای CUDA و Device Pluginها تا حد امکان خودکار شود. محیط توسعه نیز بر پایه JupyterHub در کلاستر مستقر شد و احراز هویت آن از طریق SSO و با اتکا بر Keycloak انجام گرفت. برای مدیریت پیکربندیها، رویکرد GitOps اتخاذ شد و ArgoCD بهعنوان ابزار اعمال و همگامسازی وضعیت کلاستر به کار رفت؛ نتیجه آن، امکان Continuous Deployment و بازگشت کنترلشده به نسخههای پیشین بود.
برای پایش، Prometheus جهت جمعآوری متریکها و DCGM Exporter برای پایش GPUها پیادهسازی شد و Grafana نیز برای نمایش و تحلیل دادهها مورد استفاده قرار گرفت. دسترسی به سرویسها از طریق Ingress Controller ارائه شد و ارتباطات بیرونی با TLS ایمنسازی گردید.
۷-۲ نتیجهگیری
خروجی این پیادهسازی نشان داد که یک معماری Cloud-Native میتواند نیازهای پیچیده workloadهای یادگیری ماشین را پوشش دهد. Kubernetes بهعنوان لایه ارکستراسیون، هم مقیاسپذیری افقی و هم مقیاسپذیری عمودی را در سطح سرویسها و بارهای کاری ممکن ساخت. ارزیابیهای عملکردی نیز بیانگر آن بود که با استفاده از PCI Passthrough، overhead مجازیسازی در مسیر دسترسی به GPU به کمتر از ۵٪ کاهش مییابد؛ موضوعی که در training مدلهای deep learning نقش تعیینکننده دارد.
اتخاذ GitOps برای مدیریت پیکربندیها، علاوه بر نظم عملیاتی، قابلیت audit و بازیابی سریع را تقویت کرد. با ثبت تمامی تغییرات زیرساخت در Git repository، امکان بازگشت به هر نقطه زمانی و بازتولید وضعیت فراهم شد؛ مزیتی که بهویژه در محیطهای پژوهشیِ نیازمند reproducibility اهمیت دارد.
در بخش هویت و دسترسی، پیادهسازی احراز هویت متمرکز با Keycloak و استفاده از OIDC، فرایند مدیریت دسترسی کاربران را سادهتر کرد و امکان اتصال به سرویسهای Identity موجود در سازمان را نیز به همراه داشت. از سوی دیگر، NetworkPolicyهای تعریفشده تضمین لازم را برای ایزولهسازی پروژهها و کاهش سطح تماس میان Namespaceها فراهم کردند.
سامانه پایش مبتنی بر Prometheus و Grafana دید نسبتاً کاملی از وضعیت cluster، مصرف منابع GPU و performance applicationها ارائه داد. متریکهای گردآوریشده از DCGM زمینه شناسایی bottleneckها و بهینهسازی بهرهبرداری از GPUها را مهیا کرد و به تصمیمگیری عملیاتی در تخصیص منابع کمک رساند.
با این حال، مسیر اجرا بدون چالش نبود. مهمترین دشواری به پیکربندی IOMMU و VFIO برای GPU Passthrough بازمیگشت که مستلزم تنظیمات دقیق در سطح BIOS و kernel بود. همچنین، تنوع نسخههای موردنیاز درایور CUDA برای applicationهای مختلف، طراحی دقیق Container imageها و استفاده از multi-stage builds را ضروری کرد تا از ناسازگاریهای اجرایی و افزایش غیرضروری حجم imageها جلوگیری شود.
۷-۳ کارهای آینده
ادامه توسعه این پلتفرم را میتوان در چند محور اصلی پی گرفت:
توسعه قابلیتهای MLOps: تکمیل یک pipeline جامع MLOps با تکیه بر Kubeflow برای مدیریت چرخه حیات مدل، از data preparation تا model serving. در همین راستا، یکپارچهسازی با ابزارهایی مانند MLflow برای experiment tracking و model registry میتواند نیازهای تیمهای data science را بهتر پوشش دهد.
بهینهسازی استفاده از GPU: پیادهسازی GPU sharing و time-slicing بهمنظور افزایش بهرهوری منابع GPU. در سختافزارهای مناسب، استفاده از NVIDIA MIG (Multi-Instance GPU) بهویژه در GPUهای نسل A100 و بالاتر، ظرفیت افزایش density و تفکیک منابع را فراهم میکند.
گسترش قابلیتهای ذخیرهسازی: اتصال پلتفرم به distributed storage systemهایی مانند Ceph یا MinIO برای میزبانی datasetهای حجیم. همچنین ایجاد یک data caching layer مبتنی بر NVMe میتواند I/O latency را در training workloadها کاهش دهد.
خودکارسازی مدیریت منابع: توسعه Kubernetes Operator اختصاصی برای تخصیص هوشمند GPU بر اساس نوع workload و سیاستهای اولویتبندی. در ادامه، پیادهسازی auto-scaling با تکیه بر متریکهای سفارشیِ GPU utilization میتواند تخصیص منابع را به شرایط واقعی بار کاری نزدیکتر کند.
تقویت امنیت: استقرار Pod Security Standards و بهکارگیری OPA (Open Policy Agent) برای policy enforcement در سطح cluster. افزون بر آن، یکپارچهسازی با ابزارهای vulnerability scanning نظیر Trivy بهمنظور بررسی خودکار Container imageها پیشنهاد میشود.
Multi-cluster Management: حرکت به سمت معماری federation چند cluster با هدف ارتقای high availability و فراهمسازی سازوکارهای disaster recovery. بهرهگیری از ابزارهایی مانند Rancher یا KubeFed میتواند مدیریت متمرکز و سیاستگذاری یکنواخت را در چند کلاستر تسهیل کند.