نحوه دسترسی به منابع Kubernetes Pod

نحوه دسترسی به منابع Kubernetes Podپاداش توسط توحد

هنگام شروع کار با Kubernetes، معمولاً تنظیم منابع کانتینر را فراموش می کنیم. در این مرحله، کافی است اطمینان حاصل شود که تصویر Docker کار می کند و می تواند در خوشه Kubernetes مستقر شود.

اما بعداً برنامه باید در یک خوشه تولید همراه با سایر برنامه ها مستقر شود. برای این کار باید منابعی را برای کانتینر اختصاص دهید و مطمئن شوید که به اندازه کافی برای راه اندازی برنامه وجود دارد و سایر برنامه های در حال اجرا با مشکل مواجه نخواهند شد.

تیم Kubernetes aaS از Mail.ru ترجمه مقاله ای در مورد منابع کانتینر (CPU & MEM)، درخواست ها و محدودیت های منابع. مزایای این تنظیمات را خواهید آموخت و اگر آنها را تنظیم نکنید چه اتفاقی می افتد.

منابع محاسباتی

ما دو نوع منبع با واحدهای زیر داریم:

  • واحد پردازش مرکزی (CPU) - هسته ها؛
  • حافظه (MEM) - بایت.

منابع برای هر ظرف مشخص شده است. در فایل Pod YAML زیر، بخش منبعی را مشاهده خواهید کرد که شامل منابع درخواستی و محدود است:

  • Requested Pod Resources = مجموع منابع درخواستی همه کانتینرها.
  • Pod Resource Limit = مجموع تمام محدودیت های منبع Pod.

apiVersion: v1
kind: Pod
metadata:
  name: backend-pod-name
  labels:
    application: backend
spec:
  containers:
    — name: main-container
      image: my-backend
      tag: v1
      ports:
      — containerPort: 8080
      resources:
        requests:
          cpu: 0.2 # REQUESTED CPU: 200m cores
          memory: "1Gi" # REQUESTED MEM: 1Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
    — name: other-container
      image: other-app
      tag: v1
      ports:
      — containerPort: 8000
      resources:
        requests:
          cpu: "200m" # REQUESTED CPU: 200m cores
          memory: "0.5Gi" # REQUESTED MEM: 0.5Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi

نمونه ای از منابع درخواستی و محدود

رشته resources.requested از مشخصات Pod یکی از عناصری است که برای یافتن گره مورد نظر استفاده می شود. از قبل می توانید استقرار Pod را برای آن برنامه ریزی کنید. چگونه یک گره مناسب پیدا می کنید؟

Kubernetes از چندین جزء تشکیل شده است، از جمله یک گره اصلی یا گره اصلی (Kubernetes Control Plane). گره اصلی چندین فرآیند دارد: kube-apiserver، kube-controller-manager و kube-scheduler.

فرآیند kube-scheduler مسئول بررسی غلاف‌های جدید ایجاد شده و یافتن گره‌های کارگری است که با تمام درخواست‌های پاد، از جمله تعداد منابع درخواستی مطابقت دارند. لیست گره های یافت شده توسط kube-scheduler رتبه بندی شده است. غلاف بر روی گره ای با بالاترین امتیاز برنامه ریزی می شود.

نحوه دسترسی به منابع Kubernetes Podغلاف بنفش در کجا قرار می گیرد؟

در تصویر می بینید که kube-scheduler باید یک Pod بنفش جدید را برنامه ریزی کند. خوشه Kubernetes شامل دو گره است: A و B. همانطور که می بینید، kube-scheduler نمی تواند یک Pod را در گره A برنامه ریزی کند - منابع موجود (طلب نشده) با درخواست های Pod بنفش مطابقت ندارند. بنابراین، 1 گیگابایت حافظه درخواستی پاد بنفش روی گره A جا نمی‌شود، زیرا حافظه موجود 0,5 گیگابایت است. اما گره B منابع کافی دارد. در نتیجه، kube-scheduler تصمیم می گیرد که مقصد Pod بنفش گره B باشد.

اکنون می دانیم که منابع درخواستی چگونه بر انتخاب گره برای اجرای Pod تأثیر می گذارد. اما تاثیر منابع حاشیه ای چیست؟

محدودیت منبع مرزی است که CPU/MEM نمی تواند از آن عبور کند. با این حال، منبع CPU انعطاف پذیر است، بنابراین کانتینرهایی که به محدودیت های CPU خود می رسند باعث خروج Pod نمی شوند. در عوض، throttling CPU شروع می شود. اگر به حد مجاز استفاده از MEM برسد، کانتینر به دلیل OOM-Killer متوقف می‌شود و در صورتی که تنظیم RestartPolicy اجازه دهد، دوباره راه‌اندازی می‌شود.

منابع درخواستی و حداکثر با جزئیات

نحوه دسترسی به منابع Kubernetes Podارتباط منابع بین Docker و Kubernetes

بهترین راه برای توضیح نحوه عملکرد درخواست های منابع و محدودیت های منابع، معرفی رابطه بین Kubernetes و Docker است. در تصویر بالا می‌توانید ببینید که فیلدهای Kubernetes و پرچم‌های راه‌اندازی Docker چگونه به هم مرتبط هستند.

حافظه: درخواست و محدودیت

containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"

همانطور که در بالا ذکر شد، حافظه بر حسب بایت اندازه گیری می شود. بر اساس اسناد Kubernetes، می توانیم حافظه را به عنوان یک عدد مشخص کنیم. معمولاً یک عدد صحیح است، به عنوان مثال 2678 - یعنی 2678 بایت. می توانید از پسوندها نیز استفاده کنید G и Gi، نکته اصلی این است که به یاد داشته باشید که آنها معادل نیستند. اولی اعشاری و دومی باینری است. مانند مثال ذکر شده در مستندات k8s: 128974848, 129e6, 129M, 123Mi - عملاً معادل هستند.

گزینه Kubernetes limits.memory با پرچم مطابقت دارد --memory از داکر در صورت request.memory هیچ پیکانی برای Docker وجود ندارد زیرا داکر از این فیلد استفاده نمی کند. ممکن است بپرسید آیا این حتی ضروری است؟ بله نیاز است. همانطور که قبلاً گفتم، میدان برای Kubernetes مهم است. بر اساس اطلاعات به دست آمده از آن، kube-scheduler تصمیم می گیرد که کدام گره را برنامه ریزی کند.

اگر حافظه کافی برای یک درخواست تنظیم نکنید، چه اتفاقی می‌افتد؟

اگر ظرف به محدودیت های حافظه درخواستی رسیده باشد، Pod در گروهی از Pods قرار می گیرد که وقتی حافظه کافی در گره وجود نداشته باشد متوقف می شود.

اگر محدودیت حافظه را خیلی کم تنظیم کنید چه اتفاقی می افتد؟

اگر کانتینر از حد مجاز حافظه بیشتر شود، به دلیل OOM-Killed خاتمه می‌یابد. و در صورت امکان بر اساس RestartPolicy که مقدار پیش فرض است راه اندازی مجدد خواهد شد Always.

اگر حافظه درخواستی را مشخص نکنید چه اتفاقی می افتد؟

Kubernetes مقدار حد را می گیرد و آن را به عنوان مقدار پیش فرض تعیین می کند.

اگر محدودیت حافظه را مشخص نکنید چه اتفاقی می افتد؟

کانتینر هیچ محدودیتی ندارد، می تواند هر چقدر که بخواهد از حافظه استفاده کند. اگر او شروع به استفاده از تمام حافظه موجود گره کند، OOM او را می کشد. سپس کانتینر در صورت امکان بر اساس RestartPolicy راه اندازی مجدد می شود.

اگر محدودیت های حافظه را مشخص نکنید چه اتفاقی می افتد؟

این بدترین حالت است: زمان‌بندی‌کننده نمی‌داند که کانتینر به چند منبع نیاز دارد و این می‌تواند مشکلات جدی در گره ایجاد کند. در این مورد، خوب است که محدودیت های پیش فرض در فضای نام (تنظیم شده توسط LimitRange) وجود داشته باشد. هیچ محدودیت پیش‌فرضی وجود ندارد - Pod هیچ محدودیتی ندارد، می‌تواند هر اندازه که می‌خواهد از حافظه استفاده کند.

اگر حافظه درخواستی بیشتر از چیزی باشد که گره می تواند ارائه دهد، Pod برنامه ریزی نمی شود. مهم است که به یاد داشته باشید Requests.memory - نه حداقل مقدار این توصیفی از مقدار حافظه کافی برای کارکرد مداوم ظرف است.

معمولاً توصیه می شود که همان مقدار را برای request.memory и limit.memory. این تضمین می کند که Kubernetes یک Pod را روی گره ای که حافظه کافی برای اجرای Pod دارد اما برای اجرای آن کافی نیست، برنامه ریزی نمی کند. به خاطر داشته باشید: برنامه ریزی Kubernetes Pod فقط در نظر گرفته می شود requests.memoryو limits.memory را در نظر نمی گیرد.

CPU: درخواست و محدودیت

containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"

با یک CPU همه چیز کمی پیچیده تر است. با بازگشت به تصویر رابطه بین Kubernetes و Docker، می توانید آن را مشاهده کنید request.cpu مربوط به --cpu-shares، در حالیکه limit.cpu با پرچم مطابقت دارد cpus در داکر

CPU که Kubernetes درخواست می کند در 1024 ضرب می شود، یعنی نسبت چرخه های CPU. اگر می خواهید 1 هسته کامل درخواست کنید، باید اضافه کنید cpu: 1همانطور که در بالا نشان داده شده.

درخواست یک هسته کامل (نسبت = 1024) به این معنی نیست که ظرف شما آن را دریافت خواهد کرد. اگر دستگاه میزبان شما فقط یک هسته دارد و بیش از یک کانتینر را اجرا می کنید، همه کانتینرها باید CPU موجود را بین خود به اشتراک بگذارند. چگونه این اتفاق می افتد؟ بیایید به تصویر نگاه کنیم.

نحوه دسترسی به منابع Kubernetes Pod
درخواست CPU - سیستم تک هسته ای

بیایید تصور کنیم که یک سیستم میزبان تک هسته ای دارید که کانتینرها را اجرا می کند. مامان (Kubernetes) یک پای (CPU) پخت و می خواهد آن را بین بچه ها (ظروف) تقسیم کند. سه کودک یک پای کامل می خواهند (نسبت = 1024)، یک کودک دیگر نیم پای می خواهد (512). مامان می خواهد منصف باشد و یک محاسبه ساده انجام می دهد.

# Сколько пирогов хотят дети?
# 3 ребенка хотят по целому пирогу и еще один хочет половину пирога
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
# Выражение получается так:
3 (ребенка/контейнера) * 1 (целый пирог/полное ядро) + 1 (ребенок/контейнер) * 0.5 (половина пирога/половина ядра)
# Сколько пирогов испечено?
availableCakesNumber = 1
# Сколько пирога (максимально) дети реально могут получить?
newMaxRequest = 1 / 3.5 =~ 28%

بر اساس محاسبات، سه فرزند 28 درصد هسته را دریافت خواهند کرد و نه کل هسته. فرزند چهارم 14 درصد از هسته کامل را دریافت می کند، نه نیمی از آن. اما اگر یک سیستم چند هسته ای داشته باشید، همه چیز متفاوت خواهد بود.

نحوه دسترسی به منابع Kubernetes Pod
درخواست CPU - سیستم چند هسته ای (4).

در تصویر بالا می بینید که سه کودک یک پای کامل می خواهند و یکی نیمی از آن را می خواهد. از آنجایی که مامان چهار پای پخته است، هر کدام از فرزندانش هر چقدر که بخواهند می گیرند. در یک سیستم چند هسته ای، منابع پردازنده در تمام هسته های پردازنده موجود توزیع می شود. اگر یک کانتینر به کمتر از یک هسته کامل CPU محدود شود، همچنان می‌تواند از آن 100% استفاده کند.

محاسبات بالا برای درک نحوه توزیع CPU بین کانتینرها ساده شده است. البته به غیر از خود کانتینرها، فرآیندهای دیگری نیز وجود دارند که از منابع CPU نیز استفاده می کنند. هنگامی که فرآیندهای یک ظرف بیکار هستند، سایرین می توانند از منبع آن استفاده کنند. CPU: "200m" مربوط به CPU: 0,2، یعنی تقریباً 20٪ از یک هسته.

حالا بیایید در مورد صحبت کنیم limit.cpu. CPU که Kubernetes محدود می کند در 100 ضرب می شود. نتیجه مقدار زمانی است که ظرف می تواند در هر 100 میکرو ثانیه استفاده کند.cpu-period).

limit.cpu با پرچم داکر مطابقت دارد --cpus. این یک ترکیب جدید از قدیمی است --cpu-period и --cpu-quota. با تنظیم آن، نشان می‌دهیم که کانتینر می‌تواند از چه تعداد منبع CPU در دسترس قبل از شروع throttling استفاده کند:

  • CPU - ترکیب cpu-period и cpu-quota. cpus = 1.5 معادل تنظیم cpu-period = 100000 и cpu-quota = 150000;
  • دوره CPU - دوره زمانی زمانبندی CPU CFS، پیش فرض 100 میکروثانیه;
  • سهمیه پردازنده - تعداد میکروثانیه در داخل cpu-period، که توسط ظرف محدود شده است.

اگر CPU درخواستی کافی را نصب نکنید، چه اتفاقی می‌افتد؟

اگر کانتینر بیشتر از آنچه که نصب کرده نیاز داشته باشد، CPU را از سایر فرآیندها می‌دزدد.

اگر محدودیت CPU را خیلی کم تنظیم کنید چه اتفاقی می افتد؟

از آنجایی که منبع CPU قابل تنظیم است، throttling روشن می شود.

اگر درخواست CPU را مشخص نکنید چه اتفاقی می افتد؟

مانند حافظه، مقدار درخواست برابر با حد است.

اگر محدودیت CPU را مشخص نکنید چه اتفاقی می افتد؟

ظرف به اندازه نیاز از CPU استفاده می کند. اگر یک خط مشی پیش‌فرض CPU (LimitRange) در فضای نام تعریف شده باشد، این محدودیت برای کانتینر نیز استفاده می‌شود.

اگر یک درخواست یا محدودیت CPU را مشخص نکنید، چه اتفاقی می‌افتد؟

مانند حافظه، این بدترین سناریو است. زمانبند نمی داند کانتینر شما به چه تعداد منابع نیاز دارد و این می تواند مشکلات جدی در گره ایجاد کند. برای جلوگیری از این امر، باید محدودیت های پیش فرض را برای فضاهای نام (LimitRange) تعیین کنید.

به یاد داشته باشید: اگر بیشتر از آنچه که گره ها می توانند ارائه دهند، درخواست CPU داشته باشید، Pod برنامه ریزی نمی شود. Requests.cpu - نه حداقل مقدار، بلکه مقدار کافی برای راه اندازی Pod و کار بدون خرابی. اگر برنامه محاسبات پیچیده ای را انجام نمی دهد، بهترین گزینه نصب است request.cpu <= 1 و هر تعداد کپی که لازم است راه اندازی کنید.

مقدار ایده آل منابع درخواستی یا محدودیت منابع

با محدودیت منابع محاسباتی آشنا شدیم. اکنون زمان پاسخ به این سؤال است: «پاد من برای اجرای برنامه بدون مشکل به چند منبع نیاز دارد؟ مقدار ایده آل چقدر است؟

متأسفانه هیچ پاسخ روشنی برای این سؤالات وجود ندارد. اگر نمی دانید برنامه شما چگونه کار می کند یا به چه مقدار CPU یا حافظه نیاز دارد، بهترین گزینه این است که به برنامه مقدار زیادی حافظه و CPU بدهید و سپس تست های عملکرد را اجرا کنید.

علاوه بر تست های عملکرد، به مدت یک هفته بر رفتار برنامه در نظارت نظارت کنید. اگر نمودارها نشان می دهد که برنامه شما منابع کمتری را نسبت به درخواست شما مصرف می کند، می توانید مقدار CPU یا حافظه درخواستی را کاهش دهید.

به عنوان نمونه این را ببینید داشبورد گرافانا. تفاوت بین منابع یا محدودیت منابع درخواستی و مصرف فعلی منابع را نشان می دهد.

نتیجه

درخواست و محدود کردن منابع به سالم نگه داشتن خوشه Kubernetes شما کمک می کند. پیکربندی حد مناسب هزینه ها را به حداقل می رساند و برنامه ها را همیشه در حال اجرا نگه می دارد.

به طور خلاصه چند نکته را باید در نظر داشت:

  1. منابع درخواستی پیکربندی هستند که در زمان راه اندازی (زمانی که Kubernetes قصد میزبانی برنامه را دارد) در نظر گرفته می شود. در مقابل، محدود کردن منابع در زمان اجرا مهم است - زمانی که برنامه از قبل روی گره در حال اجرا است.
  2. در مقایسه با حافظه، CPU یک منبع تنظیم شده است. اگر CPU به اندازه کافی وجود نداشته باشد، Pod شما خاموش نمی شود و مکانیزم دریچه گاز روشن می شود.
  3. منابع درخواستی و محدودیت منابع مقادیر حداقل و حداکثر نیستند! با تعریف منابع درخواستی، مطمئن می شوید که برنامه بدون مشکل اجرا می شود.
  4. یک تمرین خوب این است که درخواست حافظه را برابر با محدودیت حافظه تنظیم کنید.
  5. Ok نصب درخواست شد CPU <=1، اگر برنامه محاسبات پیچیده را انجام ندهد.
  6. اگر منابع بیشتری از آنچه در یک گره موجود است درخواست کنید، Pod هرگز برای آن گره برنامه ریزی نمی شود.
  7. برای تعیین مقدار صحیح محدودیت منابع/منابع درخواستی، از آزمایش بار و نظارت استفاده کنید.

امیدوارم این مقاله به شما در درک مفهوم اساسی محدودیت منابع کمک کند. و شما قادر خواهید بود از این دانش در کار خود استفاده کنید.

موفق باشید!

دیگر چه بخوانیم:

  1. قابلیت مشاهده SRE: فضاهای نام و ساختار متریک.
  2. بیش از 90 ابزار مفید برای Kubernetes: استقرار، مدیریت، نظارت، امنیت و موارد دیگر.
  3. کانال ما اطراف کوبرنتس در تلگرام.

منبع: www.habr.com

اضافه کردن نظر