نسخه Kubernetes 1.37 که برای 26 آگوست برنامه‌ریزی شده، مجموعه‌ای متنوع از قابلیت‌های alpha را در چند حوزه مهم وارد می‌کند؛ از مدیریت پیشرفته چرخه‌عمر workloadها گرفته تا بهبودهای بیشتر در DRA (Dynamic Resource Allocation)، ارتقای امنیت و storage، و حتی مهاجرت به nftables 🚀. در این مرور، 22 قابلیت alpha را که برای اولین‌بار وارد Kubernetes شده‌اند بررسی می‌کنیم تا تصویری روشن از مسیر بعدی container orchestration داشته باشیم.

نکته: تلاش می‌کنیم تغییرات واقعی را تا حد ممکن دقیق و درست توضیح دهیم. با این حال، چون وضعیت featureهای Kubernetes همیشه در حال تغییر است، ممکن است بعضی از Kubernetes Enhancement Proposals (KEPs) که در این مطلب آمده‌اند، نزدیک زمان release از milestone خارج شوند.

Nodes Pod-Level Checkpoint/Restore KEP #5823 (issue)
Feature gate: PodLevelCheckpointRestore

در Kubernetes، Podها ذاتاً موقتی هستند؛ یعنی اگر یک Pod کرش کند یا به node دیگری منتقل شود، حذف می‌شود و دوباره از صفر بالا می‌آید. قابلیت Pod-Level Checkpoint/Restore این رفتار را تغییر می‌دهد و اجازه می‌دهد از کل Pod snapshot بگیرید. قبلاً فقط می‌شد از containerهای جداگانه snapshot گرفت (KEP-2008)، که به خاطر shared بودن network و memory بین containerها، محدودیت‌های زیادی ایجاد می‌کرد.

این مکانیزم جدید به شما اجازه می‌دهد کل Pod و منابع وابسته به آن را freeze کنید؛ مثل وضعیت memory، درخت processها، file descriptorهای باز و تنظیمات یا metadata سطح Pod. بعد این وضعیت در یک فایل ذخیره می‌شود و هر زمان لازم بود، Pod دقیقاً از همان نقطه‌ای که متوقف شده بود، دوباره restore می‌شود 📦

این KEP برای چهار سناریوی عملی خیلی مفید است:

– حذف delayهای startup برای applicationهای سنگین مثل workloadهای Java یا ML. می‌توانید برنامه را یک‌بار اجرا کنید، صبر کنید fully ready شود، مثلاً memory را پر کند و cacheها را warm کند، بعد snapshot بگیرید و همان وضعیت را سریع روی nodeهای دیگر replicate کنید.
– نقش backup برای workloadهای long-running. اگر workload fail شود یا لازم باشد به node دیگری migrate شود، snapshot کمک می‌کند از آخرین state ذخیره‌شده ادامه بدهید، نه اینکه همه محاسبات را از اول انجام دهید.
– ساده‌تر شدن maintenance سرورها. می‌توانید Podهای در حال اجرا را pause کنید، آن‌ها را امن به ماشین دیگری منتقل کنید و بدون از دست دادن progress، ادامه دهید.
– کمک به debugging و forensics. در واقع هدف اصلی KEP-2008 هم همین بود: می‌توانید از یک Pod freezeشده snapshot بگیرید و برای بررسی عمیق‌تر در محیط staging به تیم توسعه بدهید، بدون اینکه application اصلی مختل شود.

این feature در سطح kubelet کار می‌کند. kubelet با container runtimeهایی مثل containerd یا CRI-O هماهنگ می‌شود و آن runtime هم از ابزار Linux به نام CRIU (Checkpoint/Restore in Userspace) استفاده می‌کند. CRIU processها را متوقف می‌کند و RAM، fileهای باز و وضعیت network connectionها را در یک archive بسته‌بندی می‌کند. هنگام restore هم با کمک قابلیت‌های Linux kernel، process tree را با PIDهای اصلی و محیط network اولیه بازسازی می‌کند و در عین حال قوانین امنیتی سیستم را هم رعایت می‌کند 🔒

در نسخه alpha، API با دو method جدید گسترش پیدا کرده است:

– CheckpointPod — برای ساخت checkpoint در سطح Pod
– RestorePod — برای restore کردن Pod sandbox از روی checkpoint ذخیره‌شده

DRA Optional Node Preparation KEP #5945 (issue)
Feature gate: DRAOptionalNodePreparation

این KEP یک محدودیت معماری در مکانیزم Dynamic Resource Allocation (DRA) را حل می‌کند؛ محدودیتی که مدیریت resourceهای مجازی یا cloud را سخت می‌کرد. قبلاً kubelet همیشه سعی می‌کرد قبل از شروع container و بعد از پایان آن، از طریق gRPC با driver محلی ارتباط بگیرد تا device را prepare یا cleanup کند. همین موضوع باعث می‌شد administratorها مجبور شوند روی همه nodeهای cluster، DaemonSetهایی با driverهای dummy یا no-op نصب کنند؛ حتی وقتی هیچ نیازی به پیکربندی سخت‌افزار فیزیکی روی سرورها نبود.

KEP-5945 یک field بولی جدید به نام SkipNodeOperations را در ResourceSliceSpec و DeviceRequestAllocationResult اضافه می‌کند. وقتی driver اعلام کند که setup سمت node لازم نیست، kubelet دیگر دنبال plugin محلی نمی‌گردد و در نتیجه gRPC callهای اضافی حذف می‌شوند. این یعنی می‌توانید از resourceهای network، virtual یا cloud استفاده کنید، بدون اینکه مجبور باشید software اضافه‌ای روی nodeها اجرا کنید 🛠️

این تغییر هم reliability cluster را بهتر می‌کند چون نیاز به local agentهای تکراری را از بین می‌برد، هم maintenance را ساده‌تر می‌کند. علاوه بر این، مصرف CPU و memory هم کاهش پیدا می‌کند و احتمال گیر کردن Podها در حالت Terminating به خاطر failure در local driver کمتر می‌شود. برای deviceهای سنتی که هنوز به configuration فیزیکی روی node نیاز دارند، backward compatibility کامل حفظ شده است.

DRA Device Compatibility Groups KEP #5963 (issue)
Feature gate: DRADeviceCompatibilityGroups

قبلاً وقتی قرار بود با DRA سخت‌افزارهای تخصصی مثل GPU بین Podها share شوند، scheduling دردسرهای جدی داشت. scheduler فقط ظرفیت کل device فیزیکی را می‌دید و درخواست Podها را از آن کم می‌کرد، اما نمی‌فهمید این درخواست‌ها از نظر سخت‌افزاری با هم سازگار هستند یا نه. برای مثال، نمی‌شود دو profile مجازی‌سازی متفاوت مثل MIG و vGPU را هم‌زمان روی یک GPU اجرا کرد.

در نتیجه، اگر scheduler یک Pod را به nodeای می‌فرستاد که با Podهای موجود ناسازگار بود، Pod جدید وارد loop خطا می‌شد؛ مثلاً CrashLoopBackOff یا UnexpectedAdmissionError، و Kubernetes هم نمی‌توانست به‌صورت خودکار آن را به node دیگری reschedule کند.

KEP-5963 مفهوم Device Compatibility Groups را وارد Kubernetes می‌کند. حالا هنگام انتخاب node برای یک Pod، scheduler فقط ظرفیت آزاد را نگاه نمی‌کند، بلکه سازگاری منطقی configurationها را هم بررسی می‌کند. اگر یک device فیزیکی از قبل Podی را اجرا کند که به یک mode خاص نیاز دارد، scheduler اجازه نمی‌دهد Podی با mode ناسازگار روی همان node قرار بگیرد، حتی اگر ظرفیت خالی کافی وجود داشته باشد 🔁

برای این کار، DRA API هم توسعه پیدا کرده است: یک field جدید به نام compatibilityGroups به توضیحات resourceهای سخت‌افزاری موجود، یعنی object نوع ResourceSlice، اضافه شده. این field شامل مجموعه‌ای از labelهای متنی است که توسط driver سخت‌افزار تولید می‌شوند. هر بار که یک Pod جدید schedule می‌شود، Kubernetes بررسی می‌کند که compatibility groupهای آن با Podهای در حال اجرای همان device اشتراک دارند یا نه. اگر هم‌پوشانی وجود نداشته باشد، scheduler آن node را رد می‌کند و سراغ node دیگری با hardware مناسب می‌رود.

Support Default Pod Sysctls in Kubelet KEP #5996 (issue)
Feature gate: DefaultPodSysctls

الان Kubernetes اجازه می‌دهد برای هر Pod به‌صورت جداگانه از طریق فیلد securityContext.sysctls در specification آن، sysctl parameterها را تنظیم کنید. اما در عمل، administratorهای node معمولاً لازم دارند kernel parameterها را به‌صورت یکپارچه روی همه workloadهای یک node یا یک node pool اعمال کنند. برای نمونه، applicationهای high-performance networking ممکن است روی nodeهای تخصصی به مقادیر خاصی از net.* یا kernel.shm* به‌صورت سراسری نیاز داشته باشند. تنظیم دستی این مقادیر برای تک‌تک Podها هم زمان‌بر است و هم احتمال خطا دارد.

KEP-5996 این مشکل را با فعال کردن configuration سطح node برای kernel parameterها حل می‌کند. kubelet هنگام ساخته شدن Pod sandbox، این تنظیمات را به‌صورت خودکار روی همه Podهای همان node اعمال می‌کند ✨

برای این کار، یک field جدید به نام DefaultPodSysctls به KubeletConfiguration اضافه می‌شود. این field یک map[string]string از جفت‌های key-value است. kubelet این مقدارها را با لیستی که از manifest خود Pod می‌آید merge می‌کند. با این حال، تنظیماتی که صریحاً در spec.securityContext.sysctls خود Pod تعریف شده باشند، اولویت دارند و روی مقدارهای پیش‌فرض node override می‌شوند.

Dynamic resize of memory-backed volumes KEP #6030 (issue)
Feature gate: InPlacePodVerticalScalingMemoryBackedVolumes

در Kubernetes می‌توانید temporary storage از نوع emptyDir را با sizeLimit مشخص داخل Pod mount کنید و مقدار medium را روی Memory بگذارید. در این حالت، kubelet یک tmpfs volume در RAM می‌سازد. تا قبل از این، sizeLimit برای چنین volumeهایی ثابت بود و اگر می‌خواستید آن را تغییر دهید، باید Pod را restart می‌کردید.

حالا با KEP-6030 می‌توانید volumeهای in-memory را بدون ساخت دوباره Pod و به‌صورت on the fly resize کنید 📈

برای این کار، فیلد Pod.Spec.Volumes[].EmptyDir.SizeLimit در زمان update از طریق subresource /resize برای Podهای موجودی که medium: Memory دارند، mutable می‌شود. علاوه بر این، یک substructure جدید داخل VolumeStatus اضافه شده تا بتوانید progress واقعی resize شدن volume را هم track کنید.

DRA: Standard numaNode Device Attribute KEP #6072 (issue)
Feature gate: none (requires DRAListTypeAttributes)

در پیاده‌سازی فعلی DRA در Kubernetes، driverهای مختلف اطلاعات affinity نسبت به NUMA node را با پنج نام متفاوت و وابسته به vendor منتشر می‌کنند. این پراکندگی باعث می‌شود نتوان یک rule واحد برای scheduler نوشت تا resourceهایی مثل GPU، NIC و CPU را روی یک NUMA node مشترک allocate کند و به بهترین سرعت انتقال داده برسد.

KEP 6072 این مشکل را با استاندارد کردن attribute به نام resource.kubernetes.io/numaNode حل می‌کند. deviceها می‌توانند این attribute را در دو قالب منتشر کنند. قالب اول یک integer ساده است که به یک NUMA node فیزیکی مشخص اشاره می‌کند و نیازی به feature gate ندارد. قالب دوم یک list از integerهاست که بر اساس latencyهای سخت‌افزاری ACPI SLIT ساخته می‌شود و برای آن باید feature gate مربوط به DRAListTypeAttributes را فعال کنید (KEP-5491) 📍

در نتیجه، scheduler Kubernetes می‌تواند deviceهای سازگار را با پیدا کردن intersection بین setهای پشتیبانی‌شده آن‌ها group کند. مثلاً اگر CPU روی node 4 pin شده باشد و NIC اعلام کند با nodeهای [6, 4, 5, 7] به‌خوبی کار می‌کند، scheduler این اشتراک را پیدا می‌کند: 4. بعد هم workload را روی همان NUMA node درست اجرا می‌کند.

TLS Credentials in gRPC Probe KEP #4939 (issue)
Feature gate: GRPCContainerProbeTLS

Kubernetes 1.23 پشتیبانی native از gRPC برای liveness و readiness probeها را اضافه کرد (KEP-2727)، اما یک مشکل جدی داشت: TLS را پشتیبانی نمی‌کرد. چون خیلی از شرکت‌ها از internal Certificate Authority (CA) استفاده می‌کنند و تمام traffic بین microserviceها را encrypt می‌کنند، سرور gRPC که با TLS تنظیم شده باشد، درخواست‌های plaintext probe را از Kubernetes رد می‌کرد. در نتیجه، توسعه‌دهنده‌ها هنوز مجبور بودند از طریق exec یک ابزار خارجی را صدا بزنند 😕

KEP-4939 یک فیلد mode جدید به پرو…