Коли ви визначаєте Pod, ви можете додатково вказати, скільки кожного ресурсу потребує контейнер. Найпоширеніші ресурси, які вказують, — це CPU та памʼять (RAM); є й інші.
Коли ви вказуєте запит ресурсів для контейнерів в Podʼі, kube-scheduler використовує цю інформацію для вибору вузла, на який розмістити Pod. Коли ви вказуєте обмеження ресурсів для контейнера, kubelet забезпечує виконання цих обмежень, щоб запущений контейнер не міг використовувати більше цього ресурсу, ніж обмеження, яке ви встановили. Kubelet також резервує принаймні запитану кількість цього системного ресурсу спеціально для використання цим контейнером.
Якщо вузол, на якому запущений Pod, має достатньо вільного ресурсу, то контейнер може (і має право) використовувати більше ресурсу, ніж зазначено в його request для цього ресурсу.
Наприклад, якщо ви встановите запит memory 256 MiB для контейнера, і цей контейнер буде в Podʼі, запланованому на вузол із 8GiB памʼяті та без інших Podʼів, то контейнер може спробувати використати більше оперативної памʼяті.
Обмеження — то вже інша справа. Обидва обмеження cpu та memory застосовуються kubeletʼом (та середовищем виконання контейнерів), і, зрештою, забезпечуються ядром. На вузлах Linux ядро Linux застосовує обмеження за допомогою cgroups. Поведінка застосування обмежень cpu та memory дещо відрізняється.
Обмеження cpu застосовуються через тротлінг CPU (CPU throttling). Коли контейнер наближається до свого обмеження cpu, ядро обмежує доступ до CPU відповідно до обмеження контейнера. Тож обмеження cpu є жорстким обмеженням, що застосовує ядро. Контейнери не можуть використовувати більше CPU, ніж зазначено в їх обмеженні cpu.
Обмеження memory застосовуються ядром через завершення процесів за нестачі памʼяті (OOM kills). Якщо контейнер використовує більше памʼяті, ніж його обмеження memory, ядро може його завершити. Однак завершення відбувається тільки тоді, коли ядро виявляє тиск на памʼять. Тому контейнер, який виділяє забагато памʼяті, може бути завершений не одразу. Це означає, що обмеження memory застосовуються реактивно. Контейнер може використовувати більше памʼяті, ніж його обмеження memory, але в такому разі його може бути завершено.
MemoryQoS, яка додає тротлінг памʼяті та необовʼязкове багаторівневе резервування памʼяті на вузлах Linux за допомогою cgroup v2. Докладніше дивіться Memory QoS з cgroup v2.Тип ресурсу має базову одиницю вимірювання, і його можна запитувати, обмежувати або і те, й інше. Kubernetes має такі вбудовані типи ресурсів:
| Тип ресурсу | Опис | Базова одиниця |
|---|---|---|
cpu | Обчислювальні ресурси | cpu (ядро) |
memory | Оперативна памʼять | Байти |
ephemeral-storage | Локальне тимчасове сховище | Байти |
hugepages-<size> | Великі сторінки (тільки Linux) | Байти |
Кластери також можуть надавати розширені ресурси (ресурси з власною назвою, які зазвичай надають втулки пристроїв).
Для робочих навантажень на Linux ви можете вказати ресурси великих сторінок (huge pages). Великі сторінки є функцією, специфічною для Linux, де ядро вузла виділяє блоки памʼяті, значно більші за стандартний розмір сторінки.
Наприклад, у системі, де розмір стандартної сторінки становить 4KiB, ви можете вказати обмеження hugepages-2Mi: 80Mi. Якщо контейнер намагається виділити понад 40 великих сторінок по 2MiB (загалом 80 MiB), це виділення завершиться невдачею.
hugepages-* не можна виділяти понад наявні (overcommit). Це відрізняється від ресурсів memory та cpu.CPU та памʼять спільно називаються обчислювальними ресурсами або ресурсами. Обчислювальні ресурси — це вимірювані величини, які можна запитувати, виділяти та використовувати. Вони відрізняються від ресурсів API. Ресурси API, такі як Podʼи та Services, є обʼєктами, які можна читати та змінювати через API-сервер Kubernetes.
Для кожного контейнера ви можете вказати обмеження та запити ресурсів, зокрема такі:
spec.containers[].resources.limits.cpuspec.containers[].resources.limits.memoryspec.containers[].resources.limits.ephemeral-storagespec.containers[].resources.limits.hugepages-<size>spec.containers[].resources.requests.cpuspec.containers[].resources.requests.memoryspec.containers[].resources.requests.ephemeral-storagespec.containers[].resources.requests.hugepages-<size>Хоча ви можете вказувати запити та обмеження тільки для окремих контейнерів, також корисно думати про загальні запити та обмеження ресурсів для Podʼа. Для певного ресурсу запит/обмеження ресурсів Podʼа — це сума запитів/обмежень цього типу для кожного контейнера в Podʼі.
За умови, що у вашому кластері увімкнено функціональну можливість PodLevelResources, ви можете вказувати запити та обмеження ресурсів на рівні Podʼа. На рівні Podʼа Kubernetes 1.37 підтримує запити або обмеження ресурсів лише для певних типів ресурсів: cpu та/або memory, та/або hugepages. Завдяки цій функції Kubernetes дозволяє вам декларувати загальний бюджет ресурсів для Podʼа, що є особливо корисним під час роботи з великою кількістю контейнерів, де може бути важко точно визначити індивідуальні потреби у ресурсах. Крім того, це дає змогу контейнерам у межах Podʼа ділитися один з одним ресурсами, що простоюють, покращуючи використання ресурсів.
Для Podʼа ви можете вказати обмеження та запити ресурсів для CPU і памʼяті, включивши таке:
spec.resources.limits.cpuspec.resources.limits.memoryspec.resources.limits.hugepages-<size>spec.resources.requests.cpuspec.resources.requests.memoryspec.resources.requests.hugepages-<size>Обмеження та запити ресурсів CPU вимірюються в одиницях cpu. У Kubernetes 1 одиниця CPU еквівалентна 1 фізичному ядру CPU або 1 віртуальному ядру, залежно від того, чи є вузол фізичним хостом або віртуальною машиною, яка працює всередині фізичної машини.
Допускаються дробові запити. Коли ви визначаєте контейнер зі значенням 0.5 у spec.containers[].resources.requests.cpu, ви запитуєте вдвічі менше часу CPU, ніж якби запросили 1.0 CPU. Для одиниць ресурсів CPU вираз кількості 0.1 еквівалентний виразу 100m, що можна прочитати як "сто millicpu". Деякі люди кажуть "сто міліядер", і це розуміється так само.
Ресурс CPU завжди вказується як абсолютна кількість ресурсу, ніколи як відносна кількість. Наприклад, 500m CPU представляє приблизно ту саму обчислювальну потужність незалежно від того, чи працює цей контейнер на одноядерній, двоядерній або 48-ядерній машині.
Kubernetes не дозволяє вказувати ресурси CPU з точністю вище 1m або 0.001 CPU. Щоб уникнути випадкового використання неприпустимої кількості CPU, корисно вказувати одиниці CPU, використовуючи форму milliCPU замість десяткової форми, коли використовується менше ніж 1 одиниця CPU.
Наприклад, у вас є Pod, який використовує 5m або 0.005 CPU, і ви хочете зменшити його ресурси CPU. Використовуючи десяткову форму, важко помітити, що 0.0005 CPU є неприпустимим значенням, тоді як використовуючи форму milliCPU, легше помітити, що 0.5m є неприпустимим значенням.
Обмеження та запити для memory вимірюються в байтах. Ви можете вказувати памʼять як звичайне ціле число або як число з фіксованою комою, використовуючи один із таких суфіксів кількості: E, P, T, G, M, k. Ви також можете використовувати еквіваленти степенів двійки: Ei, Pi, Ti, Gi, Mi, Ki. API Kubernetes також дозволяє використовувати суфікс m (для мілібайтів: 1/1000 байта), але вказувати його немає сенсу: завжди потрібно призначати цілі числа байтів або іноді більші блоки, такі як кратні 1 гібібайту.
Ось кілька прикладів визначення обсягу памʼяті, які приблизно представляють те саме значення:
128974848, 129e6, 129M, 128974848000m, 123Mi
Звертайте увагу на регістр суфіксів. "M" означає мегабайти, тоді як "m" означає мілібайти. Якщо ви запитуєте 400m памʼяті, це запит на 0,4 байта. Той, хто вводить це, ймовірно, мав на увазі запросити 400 мебібайтів (400Mi) або 400 мегабайтів (400M).
У цьому Podʼі є два контейнери. Обидва контейнери визначені із запитом на 0,25 CPU і 64MiB (226 байт) памʼяті. Кожен контейнер має обмеження в 0,5 CPU та 128MiB памʼяті. Можна сказати, що Pod має запит на 0,5 CPU та 128 MiB памʼяті й обмеження в 1 CPU та 256MiB памʼяті.
---
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: log-aggregator
image: images.my-company.example/log-aggregator:v6
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Цю можливість можна увімкнути за допомогою функціональної можливості PodLevelResources. Цей Pod має явний запит на 1 CPU та 100 MiB памʼяті, а також явне обмеження в 1 CPU та 200 MiB памʼяті. Контейнер pod-resources-demo-ctr-1 має явні запити та обмеження. Однак контейнер pod-resources-demo-ctr-2 просто спільно використовуватиме ресурси, доступні в межах ресурсів 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: pod-resources-demo-ctr-1
image: nginx
resources:
limits:
cpu: "0.5"
memory: "100Mi"
requests:
cpu: "0.5"
memory: "50Mi"
- name: pod-resources-demo-ctr-2
image: fedora
command:
- sleep
- inf
Коли ви створюєте Pod, планувальник Kubernetes вибирає вузол, на якому Pod буде запущено. Кожен вузол має максимальну місткість для кожного з типів ресурсів: кількість CPU та обсяг памʼяті, які він може надати для Podʼів. Планувальник гарантує, що для кожного типу ресурсів сума запитів ресурсів запланованих контейнерів буде менше, ніж місткість вузла. Зверніть увагу, що навіть якщо фактичне використання ресурсів CPU або памʼяті на вузлі дуже низьке, планувальник все одно відмовляється розміщувати Pod на вузлі, якщо перевірка місткості не пройшла успішно. Це захищає від нестачі ресурсів на вузлі, коли пізніше збільшується використання ресурсів, наприклад, під час щоденного піку кількості запитів.
Коли kubelet запускає контейнер як частину Podʼа, він передає запити та обмеження для памʼяті та CPU цього контейнера до середовища виконання контейнерів.
У Linux середовище виконання контейнерів зазвичай налаштовує cgroups ядра, які застосовують і забезпечують виконання визначених вами обмежень.
memory.min та memory.low.emptyDir. Kubelet відстежує томи emptyDir типу tmpfs як використання памʼяті контейнера, а не як локальне тимчасове сховище. Під час використання emptyDir у памʼяті обовʼязково ознайомтеся з примітками нижче.Якщо контейнер перевищує свій запит на памʼять і вузол, на якому він працює, загалом стикається з нестачею памʼяті, ймовірно, що Pod, якому належить цей контейнер, буде виселено.
Контейнеру може бути дозволено або не дозволено перевищувати своє обмеження CPU протягом тривалого часу. Однак середовища виконання контейнерів не завершують Podʼи або контейнери через надмірне використання CPU.
Щоб визначити, чи контейнер неможливо запланувати або чи його завершують через обмеження ресурсів, див. розділ Усунення несправностей.
Після створення Podʼа може знадобитися налаштувати його ресурси CPU або памʼяті відповідно до фактичних моделей використання. Kubernetes пропонує два підходи до зміни розміру ресурсів Podʼа:
This is a stable feature in Kubernetes, and has been since version v1.35. It was first available in the v1.27 release. You can no longer disable or opt out of this feature or behavior (it is locked); if you explicitly set a value for the associated feature gate InPlacePodVerticalScaling, Kubernetes ignores it but does not report any error.
Ви можете змінити requests та limits CPU та памʼяті контейнерів у запущеному Podʼі без його повторного створення. Це називається вертикальним масштабуванням Podʼа на місці або зміною розміру Podʼа на місці. Щоб виконати зміну розміру на місці, оновіть специфікації ресурсів контейнера за допомогою субресурсу Podʼа /resize. Ви можете контролювати, чи потрібно перезапускати контейнер, встановивши поле resizePolicy у специфікації контейнера.
To use this feature, you (or a cluster administrator) will need to enable the InPlacePodVerticalScalingSchedulerPreemption feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Коли увімкнено функціональну можливість InPlacePodVerticalScalingSchedulerPreemption, відкладені запити на зміну розміру на місці можуть спонукати kube-scheduler витіснити Podʼи з нижчим пріоритетом на призначеному вузлі, щоб звільнити місце для зміни розміру. Для отримання додаткових відомостей див. Витіснення для зміни розміру Podʼа на місці.
Підхід cloud native до зміни ресурсів Podʼа полягає в оновленні шаблону Podʼа в обʼєкті робочого навантаження (такому як Deployment або StatefulSet) і дозволі контролеру робочого навантаження замінити Podʼи новими, що мають оновлені ресурси. Цей підхід працює з будь-якою версією Kubernetes і дозволяє змінювати будь-які специфікації Podʼів.
Детальніше про зміну розміру Podʼів див. Зміна розміру Podʼа. Детальні інструкції щодо зміни розміру на місці див. у розділі Зміна розміру ресурсів CPU та памʼяті, призначених контейнерам. Ви також можете використовувати Vertical Pod Autoscaler для автоматичного управління рекомендаціями щодо ресурсів Podʼа.
Kubelet повідомляє про використання ресурсів Podʼа як частину status Podʼа.
Якщо у вашому кластері доступні інструменти для моніторингу, то використання ресурсів Podʼа можна отримати або безпосередньо з Metrics API, або з ваших інструментів моніторингу.
emptyDir, що зберігаються в памʼятіTo use this feature, you (or a cluster administrator) will need to enable the InPlacePodVerticalScalingMemoryBackedVolumes feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Коли увімкнено функціональну можливість InPlacePodVerticalScalingMemoryBackedVolumes, ви можете динамічно змінювати sizeLimit тому emptyDir, що зберігається в памʼяті (medium: Memory), на запущеному Podʼі без повторного створення Podʼа або перезапуску контейнерів. Покрокові інструкції див. у розділі Зміна розміру ресурсів CPU та памʼяті, призначених контейнерам.
sizeLimit для тому emptyDir, цей том може використовувати памʼять до обмеження памʼяті цього Podʼа (Pod.spec.containers[].resources.limits.memory). Якщо ви не встановлюєте обмеження памʼяті, Pod не має верхньої межі на споживання памʼяті і може використовувати всю доступну памʼять на вузлі. Kubernetes планує Podʼи на основі запитів на ресурси (Pod.spec.containers[].resources.requests) і не враховує використання памʼяті понад запит під час вирішення, чи може інший Pod розміститися на даному вузлі. Це може призвести до відмови в обслуговуванні та змусити ОС виконати обробку нестачі памʼяті (OOM). Можна створити будь-яку кількість emptyDir, які потенційно можуть використовувати всю доступну памʼять на вузлі, що робить OOM більш ймовірним.З точки зору управління памʼяттю, є деякі подібності між використанням памʼяті як робочої області процесу і використанням памʼяті для emptyDir, що зберігається в памʼяті. Але під час використання памʼяті як тому, як у випадку з emptyDir, що зберігається в памʼяті, є додаткові моменти, на які слід звернути увагу:
emptyDir, що зберігаються в памʼяті, корисні через свою продуктивність, але памʼять зазвичай набагато менша за розміром і набагато дорожча за інші носії, такі як диски або SSD. Використання великої кількості памʼяті для томів emptyDir може вплинути на нормальну роботу вашого Podʼа або всього вузла, тому їх слід використовувати обережно.Якщо ви адмініструєте кластер або простір імен, ви також можете встановити ResourceQuota, що обмежує використання памʼяті; також може бути корисно визначити LimitRange для додаткового забезпечення обмежень. Якщо ви вказуєте spec.containers[].resources.limits.memory для кожного Podʼа, то максимальний розмір тому emptyDir буде дорівнювати обмеженню памʼяті Podʼа.
Як альтернатива, адміністратор кластера може забезпечити дотримання обмежень на розмір томів emptyDir в нових Podʼах, використовуючи механізм політики, такий як ValidatingAdmissionPolicy.
Щодо загальних концепцій про локальне тимчасове сховище та порад щодо налаштування запитів і/або обмежень локального тимчасового сховища для контейнера, дивіться сторінку локальне тимчасове сховище.
Kubelet може вимірювати, скільки локального тимчасового сховища використовується. Він робить це, якщо ви ввімкнули ізоляцію ємності локального тимчасового сховища.
Kubernetes відстежує обсяг тимчасового сховища, яке використовує Pod, із таких джерел:
emptyDir./var/log/pods)./etc/hosts.Розширені ресурси — це повністю кваліфіковані назви ресурсів поза доменом kubernetes.io. Вони дозволяють операторам кластера оголошувати, а користувачам використовувати ресурси, які не вбудовані в Kubernetes.
Щоб скористатися розширеними ресурсами, потрібно виконати два кроки. По-перше, оператор кластера повинен оголосити розширений ресурс. По-друге, користувачі повинні запитати розширений ресурс у Podʼах.
Розширені ресурси на рівні вузла повʼязані з вузлами.
Дивіться Втулок пристроїв щодо того, як оголошувати ресурси, що керуються втулком пристроїв на кожному вузлі.
Щоб оголосити новий розширений ресурс на рівні вузла, оператор кластера може надіслати HTTP-запит типу PATCH до API-сервера, щоб вказати доступну кількість в полі status.capacity для вузла у кластері. Після цієї операції поле status.capacity вузла буде містити новий ресурс. Kubelet автоматично й асинхронно оновлює поле status.allocatable, додаючи новий ресурс.
Оскільки планувальник використовує значення status.allocatable вузла під час оцінювання придатності Podʼа, планувальник враховує нове значення лише після цього асинхронного оновлення. Між моментом зміни місткості вузла новим ресурсом і часом, коли перший Pod, який запитує ресурс, може бути запланований на цьому вузлі, може відбуватися коротка затримка.
Приклад:
Нижче наведено приклад використання curl для формування HTTP-запиту, який оголошує пʼять ресурсів "example.com/foo" на вузлі k8s-node-1, master якого — k8s-master.
curl --header "Content-Type: application/json-patch+json" \
--request PATCH \
--data '[{"op": "add", "path": "/status/capacity/example.com~1foo", "value": "5"}]' \
http://k8s-master:8080/api/v1/nodes/k8s-node-1/status
~1 — це кодування символу / у шляху патча. Значення шляху операції у JSON-Patch інтерпретується як JSON-Pointer. Докладніше дивіться IETF RFC 6901, розділ 3.Розширені ресурси на рівні кластера не повʼязані з вузлами. Зазвичай ними керують розширювачі планувальника, які відповідають за споживання ресурсів і квоту ресурсів.
Ви можете вказати розширені ресурси, які обробляються розширювачами планувальника, в конфігурації планувальника.
Приклад:
Ця конфігурація для політики планувальника вказує на те, що розширений ресурс на рівні кластера "example.com/foo" обробляється розширювачем планувальника.
ignoredByScheduler вказує, що планувальник не перевіряє ресурс "example.com/foo" в своєму предикаті PodFitsResources.{
"kind": "Policy",
"apiVersion": "v1",
"extenders": [
{
"urlPrefix":"<extender-endpoint>",
"bindVerb": "bind",
"managedResources": [
{
"name": "example.com/foo",
"ignoredByScheduler": true
}
]
}
]
}
Розподілення розширених ресурсів за допомогою DRA дозволяє адміністраторам кластерів вказувати extendedResourceName у DeviceClass, після чого пристрої, що відповідають DeviceClass, можуть бути запитані з розширених запитів ресурсів Podʼа. Читайте більше про Розподілення розширених ресурсів за допомогою DRA.
Користувачі можуть використовувати розширені ресурси у специфікаціях Podʼа, подібно до CPU та памʼяті. Планувальник відповідає за облік ресурсів, щоб одночасно не виділялося більше доступної кількості ресурсів для Podʼів.
API-сервер обмежує кількість розширених ресурсів цілими числами. Приклади дійсних значень: 3, 3000m та 3Ki. Приклади недійсних значень: 0.5 та 1500m (тому що 1500m буде давати в результаті 1.5).
kubernetes.io, який зарезервований.Щоб використовувати розширений ресурс у Podʼі, включіть назву ресурсу як ключ у мапу spec.containers[].resources.limits у специфікації контейнера.
Pod планується лише тоді, коли задоволено всі запити ресурсів, включаючи CPU, памʼять та будь-які розширені ресурси. Pod залишається у стані PENDING, доки запит ресурсу неможливо задовольнити.
Приклад:
Нижче наведено Pod, який запитує 2 CPU та 1 "example.com/foo" (розширений ресурс).
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: myimage
resources:
requests:
cpu: 2
example.com/foo: 1
limits:
example.com/foo: 1
Обмеження ідентифікаторів процесів (PID) дозволяють налаштувати kubelet для обмеження кількості PID, яку може використовувати певний Pod. Див. Обмеження PID для отримання інформації.
FailedSchedulingЯкщо планувальник не може знайти жодного вузла, де може розміститися Pod, Pod залишається незапланованим, поки не буде знайдено місце. Кожного разу, коли планувальник не може знайти місце для Podʼа, створюється подія. Ви можете використовувати kubectl для перегляду подій Podʼа; наприклад:
kubectl describe pod frontend | grep -A 9999999999 Events
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 23s default-scheduler 0/42 nodes available: insufficient cpu
У наведеному вище прикладі Pod із назвою "frontend" не вдалося запланувати через нестачу ресурсу CPU на будь-якому вузлі. Схожі повідомлення про помилку також можуть вказувати на невдачу через недостатню памʼять (PodExceedsFreeMemory). Загалом, якщо Pod знаходиться в стані очікування з таким типом повідомлення, є кілька речей, які варто спробувати:
cpu: 1, то Pod з запитом cpu: 1.1 ніколи не буде запланованим.Ви можете перевірити місткості вузлів та виділені обсяги ресурсів за допомогою команди kubectl describe nodes. Наприклад:
kubectl describe nodes e2e-test-node-pool-4lw4
Name: e2e-test-node-pool-4lw4
[ ... lines removed for clarity ...]
Capacity:
cpu: 2
memory: 7679792Ki
pods: 110
Allocatable:
cpu: 1800m
memory: 7474992Ki
pods: 110
[ ... lines removed for clarity ...]
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
kube-system coredns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
680m (34%) 400m (20%) 920Mi (11%) 1070Mi (13%)
У наведеному вище виводі ви можете побачити, що якщо Pod запитує більше 1,120 CPU або більше 6,23Gi памʼяті, то цей Pod не поміститься на вузлі.
Подивившись на розділ "Pods", ви можете побачити, які Podʼи займають місце на вузлі.
Обсяг ресурсів, доступних для Podʼів, менший за місткість вузла, оскільки системні демони використовують частину доступних ресурсів. В API Kubernetes кожен вузол має поле .status.allocatable (див. NodeStatus для деталей).
Поле .status.allocatable описує обсяг ресурсів, доступних для Podʼів на цьому вузлі (наприклад: 15 віртуальних CPU та 7538 MiB памʼяті). Для отримання додаткової інформації про доступні для розподілу (allocatable) ресурси вузла в Kubernetes дивіться Резервування обчислювальних ресурсів для системних демонів.
Ви можете налаштувати квоти ресурсів для обмеження загального обсягу ресурсів, який може споживати простір імен. Kubernetes забезпечує дотримання квот для обʼєктів в конкретному просторі імен, коли існує ResourceQuota в цьому просторі імен. Наприклад, якщо ви призначаєте конкретні простори імен різним командам, ви можете додавати ResourceQuotas в ці простори імен. Встановлення квот ресурсів допомагає запобігти використанню однією командою так багато будь-якого ресурсу, що це впливає на інші команди.
Вам також варто розглянути, який доступ ви надаєте до цього простору імен: повний дозвіл на запис у простір імен дозволяє тому, хто має такий доступ, видаляти будь-який ресурс, включаючи налаштований ResourceQuota.
Робота вашого контейнера може бути завершена через нестачу ресурсів. Щоб перевірити, чи контейнер був завершений через досягнення обмеження ресурсів, викличте kubectl describe pod для потрібного Podʼа:
kubectl describe pod simmemleak-hra99
Вивід буде схожий на:
Name: simmemleak-hra99
Namespace: default
Image(s): saadali/simmemleak
Node: kubernetes-node-tf0f/10.240.216.66
Labels: name=simmemleak
Status: Running
Reason:
Message:
IP: 10.244.2.75
Containers:
simmemleak:
Image: saadali/simmemleak:latest
Limits:
cpu: 100m
memory: 50Mi
State: Running
Started: Tue, 07 Jul 2019 12:54:41 -0700
Last State: Terminated
Reason: OOMKilled
Exit Code: 137
Started: Fri, 07 Jul 2019 12:54:30 -0700
Finished: Fri, 07 Jul 2019 12:54:33 -0700
Ready: False
Restart Count: 5
Conditions:
Type Status
Ready False
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 42s default-scheduler Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
Normal Pulled 41s kubelet Container image "saadali/simmemleak:latest" already present on machine
Normal Created 41s kubelet Created container simmemleak
Normal Started 40s kubelet Started container simmemleak
Normal Killing 32s kubelet Killing container with id ead3fb35-5cf5-44ed-9ae1-488115be66c6: Need to kill Pod
У наведеному вище прикладі Restart Count: 5 вказує на те, що контейнер simmemleak у Podʼі був завершений та перезапущений пʼять разів (до цього моменту). Причина OOMKilled показує, що контейнер намагався використовувати більше памʼяті, ніж встановлене йому обмеження.
Наступним кроком може бути перевірка коду застосунку на витік памʼяті. Якщо ви виявите, що застосунок працює так, як очікувалося, розгляньте встановлення вищого обмеження памʼяті (і, можливо, запиту) для цього контейнера.