در این پست به بررسی مفهوم job managed در Kubernetes و تأثیر آن بر تفویض کنترل Jobها به کنترل‌کننده‌های خارجی می‌پردازیم.


کلیدواژه‌های اصلی شامل job managed، management cluster، worker cluster و .spec.managedBy هستند که به توضیح نحوه عملیات و معماری MultiKueue کمک می‌کنند.

در Kubernetes نسخه 1.35، فیلد جدید .spec.managedBy به سطح عمومی (GA) رسیده و حالا به کنترل‌کننده‌های خارجی اجازه می‌دهد مسئولیت کامل Reconcilingِ یک Job را بر عهده بگیرند. این قابلیت الگوهای زمان‌بندی پیشرفته‌ای مثل بازفرست چندشاخه‌ای و توزیع مجدد چندشاخه‌ای را ممکن می‌سازد و برای معماری‌های Multi-cluster batch مانند MultiKueue طراحی شده است 🙂

دلیل اصلی این قابلیت، پشتیبانی از معماری‌هایی است که بین یک Management Cluster و مجموعه‌ای از Worker Clusters تمایز قائل می‌شوند. در این مدل Management Cluster مسئول ارسال و هماهنگی Jobهاست، اما خود Podها را اجرا نمی‌کند. برای اینکه کاربرها بتوانند وضعیت Jobs را ببینند، لازم است Jobها در Management Cluster پذیرفته شوند اما ایجاد Pod در آن انجام نشود؛ اجرا و ساخت Podها توسط Worker Clusterها انجام می‌شود و وضعیت اجرا سپس به Management Cluster آینه‌سازی می‌شود. این کار به کاربر اجازه می‌دهد بدون دسترسی به Worker Cluster، پیشرفت Job را به‌صورت زنده مشاهده کند 👀

در Worker Cluster، Jobهای ارسال‌شده معمولاً مانند Jobs عادی اجرا می‌شوند و توسط Job controller داخلی کنترل می‌گردند (بدون .spec.managedBy). سپس وضعیت از Jobِ در حال اجرا در Worker Cluster به Jobِ مرآیی‌شده در Management Cluster کپی می‌شود تا دید یکپارچه فراهم شود.

ممکن است این سوال پیش بیاید که «چرا به‌سادگی Job controller داخلی را غیرفعال نکنیم؟» در عمل دو مانع معمول وجود دارد: اول، در بسیاری از محیط‌های ابری و کنترل‌پلن‌های مدیریت‌شده، دسترسی برای تغییر فلگ‌های کنترل‌کننده وجود ندارد؛ دوم، سناریوهای Hybrid وجود دارند که در آن‌ها برخی کارها باید در خود Management Cluster اجرا شوند و برخی دیگر به Worker سپرده شود. فیلد .spec.managedBy اجازه می‌دهد این تصمیم به صورت per-Job گرفته شود و انعطاف لازم را فراهم می‌کند.

نحوه کار .spec.managedBy ساده است: اگر فیلد خالی باشد یا مقدار رزروشده kubernetes.io/job-controller را داشته باشد، رفتار پیش‌فرض برقرار است و Job توسط Job controller داخلی مدیریت می‌شود. اما اگر مقدار دیگری قرار گیرد، Job controller داخلی به‌طور کامل از تطبیق (reconciling) آن Job چشم‌پوشی می‌کند. توجه داشته باشید که این فیلد Immutable است تا از orphan شدن Podها یا نشت منابع جلوگیری شود — یعنی نمی‌توانید یک Job در حال اجرا را بین کنترلرها منتقل کنید 🔒

اگر می‌خواهید یک کنترل‌کننده خارجی بنویسید، باید مطمئن شوید که controller شما با تعریف‌های Job API سازگار است. پیاده‌سازی کامل انطباق (reconciliation) نیازمند توجه ویژه به قواعد اعتبارسنجی وضعیت Job است؛ در واقع بخش زیادی از تلاش طراحی صرف تدوین این قواعد شد تا رفتارها در اکوسیستم هماهنگ باشند.

فیلد .spec.managedBy خیلی سریع به رابط استانداردی برای واگذاری کنترل در اکوسیستم batch تبدیل شده است. چند پروژه و کنترل‌کننده در حال افزودن این فیلد یا معادل آن هستند تا بتوانند کنترل تطبیق را به MultiKueue یا سایر کنترل‌کننده‌های مشابه واگذار کنند: MultiKueue، Trainer، KubeRay، AppWrapper و Tekton Pipelines از جمله نام‌هایی هستند که به این مسیر گرایش نشان داده‌اند 🚀

در حالی که با .spec.managedBy می‌توان از صفر یک کنترل‌کننده Job سفارشی ساخت، تا کنون کمتر دیده شده که پروژه‌ها از این فیلد برای ساخت کامل یک کنترل‌کننده تازه استفاده کنند؛ هدف اصلی فراهم کردن یک مکانیزم استاندارد برای الگوهای تفویض اختیار مثل MultiKueue بوده تا نیازی به بازآفرینی چرخ نباشد.

برای مطالعه عمیق‌تر، مستندات کاربر را درباره Jobs، تفویض مدیریت Job به کنترل‌کننده خارجی و مستندات MultiKueue مطالعه کنید و برای درک طراحی داخلی به KEP مربوطه و تاریخچه طراحی نگاه بیندازید. اگر علاقه‌مند به مشارکت هستید، در جلسات Batch WG و SIG Apps حضور پیدا کنید یا به کانال‌های مرتبط در Slack بپیوندید — مشارکت جامعه همیشه به بهبودِ این نوع ویژگی‌ها کمک می‌کند 🤝

از همه کسانی که در بحث‌های طراحی، بررسی‌ها و رفع اشکال مشارکت کردند تشکر می‌کنیم — همکاری بین تیم‌ها و SIGها بود که این قابلیت را قابل استفاده برای محیط‌های واقعی کرد 🙏