level resources در Kubernetes: تأثیر آن بر QoS و اولویت‌ها


استفاده از level resources امکان مدیریت متمرکز بودجهٔ منابع Pod را فراهم می‌کند و تفاوت کلیدی با تعریف منابع در هر کانتینر را نشان می‌دهد.

خبر خوب برای تیم‌های DevOps/SRE: در نسخه Kubernetes v1.34 قابلیت Pod Level Resources به وضعیت Beta ارتقا یافته و به‌صورت پیش‌فرض فعال است 🎉. این ویژگی یک لایه جدید از انعطاف‌پذیری برای تعریف و مدیریت تخصیص منابع به صورت سطح Pod فراهم می‌کند و می‌توانید آن را همراه با تنظیمات سطح کانتینر استفاده کنید.

تا پیش از این، منابع عموماً روی هر کانتینر جداگانه تعریف می‌شد و برای Podهای چندکانتینره اغلب مجبور بودید مقادیر را تکرار یا با دقت حساب‌وکتاب کنید. حالا با Pod Level Resources می‌توانید درخواست‌ها (requests) و محدودیت‌ها (limits) برای کل Pod — شامل CPU، memory و hugepages — را تعریف کنید تا منابع بین کانتینرها به‌صورت جمعی مدیریت شوند.

چه مزایایی دارد؟ این قابلیت چند فایدهٔ عملی دارد: اول اینکه نیاز به مدیریت ریزبه‌ریز روی هر کانتینر را کاهش می‌دهد؛ دوم اینکه به کانتینرها اجازه می‌دهد از ظرفیت بلااستفادهٔ همدیگر در داخل یک Pod بهره ببرند؛ و سوم، این کمک می‌کند تا sidecarها باعث گلوگاه نشوند. برای مثال، قبلاً اگر sidecar مثل logging agent یا service mesh proxy به حد CPU خودش می‌رسید، ممکن بود Pod کند شود حتی اگر کانتینر اپلیکیشن اصلی منابع خالی داشت. با Pod-level resources، بودجهٔ منابع به‌صورت کل Pod در نظر گرفته می‌شود و یا همهٔ کانتینرها با هم محدود می‌شوند یا همگی می‌توانند از بودجهٔ مشترک استفاده کنند.

نحوهٔ رفتار با اولویت‌ها: اگر هم pod-level و هم container-level مشخص شده باشند، مقدار pod-level اولویت دارد؛ بنابراین برنامه‌ریز (scheduler) برای جایابی نود از pod-level requests استفاده می‌کند و در زمان اجرا pod-level limit حکم سقف سخت را برای مجموع مصرف همهٔ کانتینرها ایفا می‌کند — حتی اگر مجموع limits کانتینرها بالاتر باشد، مصرف کلی نمی‌تواند از pod-level limit فراتر برود. همچنین pod-level resources در تعیین کلاس QoS تأثیر دارند و برای Podهای اجرا شده روی Linux، محاسبهٔ OOM score adjustment هر دو سطح را در نظر می‌گیرد.

برای شروع: نیاز به کلاستر Kubernetes نسخهٔ 1.34 یا جدیدتر دارید؛ همهٔ کامپوننت‌های کلاستر از جمله control plane و نودها باید همین نسخه یا جدیدتر باشند. PodLevelResources feature gate در v1.34 در حالت beta است و به‌طور پیش‌فرض فعال شده است ✅.

مثال اولیه: می‌توانید CPU، memory و hugepages را در فیلد resources در سطح Pod تعریف کنید. نمونهٔ سادهٔ یک manifest:

apiVersion: v1
kind: Pod
metadata:
  name: pod-resources-demo
  namespace: pod-resources-example
spec:
  # The 'resources' field at the Pod specification level defines the overall
  # resource budget for all containers within this Pod combined.
  resources: # Pod-level resources
    # 'limits' specifies the maximum amount of resources the Pod is allowed to use.
    # The sum of the limits of all containers in the Pod cannot exceed these values.
    limits:
      cpu: "1" # The entire Pod cannot use more than 1 CPU core.
      memory: "200Mi" # The entire Pod cannot use more than 200 MiB of memory.
    # 'requests' specifies the minimum amount of resources guaranteed to the Pod.
    # This value is used by the Kubernetes scheduler to find a node with enough capacity.
    requests:
      cpu: "1" # The Pod is guaranteed 1 CPU core when scheduled.
      memory: "100Mi" # The Pod is guaranteed 100 MiB of memory when scheduled.
  containers:
  - name: main-app-container
    image: nginx
  - name: auxiliary-container
    image: fedora
    command: ["sleep", "inf"]

در این مثال Pod به‌صورت کلی 1 CPU و 100Mi حافظه درخواست می‌کند و محدود به 1 CPU و 200Mi حافظه است؛ کانتینرها زیر این قید کلی کار می‌کنند.

مثال تعامل با requests سطح کانتینر: اگر هم در سطح Pod مقادیر و هم برای برخی کانتینرها مقادیر مشخص شوند، مقدار Pod نقش اصلی را ایفا می‌کند. مثال زیر را ببینید:

apiVersion: v1
kind: Pod
metadata:
  name: pod-resources-demo
  namespace: pod-resources-example
spec:
  resources:
    limits:
      cpu: "1"
      memory: "200Mi"
    requests:
      cpu: "1"
      memory: "100Mi"
  containers:
  - name: main-app-container
    image: nginx
    resources:
      requests:
        cpu: "0.5"
        memory: "50Mi"
  - name: auxiliary-container
    image: fedora
    command: [ "sleep", "inf"]
    # This container has no resource requests or limits specified.

شرح رفتار در این حالت: pod-level limits سقف کلی را تعیین می‌کند (قابل نقض نیست)، containers می‌توانند از ظرفیت بلااستفادهٔ همدیگر برای burst استفاده کنند به شرطی که مجموع مصرف زیر سقف pod باشد، و container-level requests در داخل بودجهٔ guaranteedِ Pod اولویت‌بندی داخلی ایجاد می‌کنند — یعنی main-app-container که request مشخص دارد، در زمان فشار منابع نسبت به auxiliary-container اولویت دارد.

محدودیت‌ها و نکات عملی ⚠️:

– در v1.34 امکان in-place resize برای pod-level resources وجود ندارد؛ تلاش برای تغییر مقادیر pod-level روی Pod در حال اجرا با خطا مواجه می‌شود. (توجه کنید که in-place resize خودش همگر به‌صورت جداگانه و مربوط به container-level است و آن هم وضعیت مستقلی دارد.)

– در سطح Pod فعلاً فقط CPU، memory و hugepages قابل تعریف هستند.

– Pod-level resources برای Windows pods پشتیبانی نمی‌شوند: اگر Pod صراحتاً spec.os.name: “windows” داشته باشد، API server آن را رد می‌کند؛ اگر Pod مشخص نشده باشد اما روی نود ویندوز زمان‌بندی شود، Kubelet روی آن نود admission را رد خواهد کرد.

– برخی resource managers مثل Topology Manager، Memory Manager و CPU Manager فعلاً بر اساس pod-level resources هماهنگ‌سازی انجام نمی‌دهند و نباید انتظار رفتار یکپارچهٔ کامل از آنها داشته باشید.

قدم‌های بعدی و بازخورد 📣: اگر می‌خواهید این قابلیت را در محیط آزمایشی یا مرحلهٔ staging بررسی کنید، کلاستر خود را به v1.34 ارتقا دهید و مطمئن شوید PodLevelResources feature gate روی control plane و همهٔ نودها فعال است (پیش‌فرض در v1.34 فعال است). بازخورد شما برای بهبود این ویژگی ارزشمند است — می‌توانید issues یا PRها را در GitHub باز کنید یا در کانال‌های مرتبط با SIG Node بحث کنید.

خلاصهٔ سریع: Pod Level Resources در v1.34 ابزار قدرتمندی است برای ساده‌تر کردن مدیریت منابع در Podهای چندکانتینره، کاهش تکرار تنظیمات و بهبود کارایی داخلی Pod؛ اما قبل از استفاده در production به محدودیت‌ها (مثل عدم پشتیبانی Windows و نبود in-place resize برای pod-level) توجه کنید 😊.