2 - Квоти ресурсів
Коли кілька користувачів або команд спільно використовують кластер із фіксованою кількістю вузлів, існує ризик, що одна команда використає більше за свою справедливу частку ресурсів.
Квоти ресурсів — це інструмент, за допомогою якого адміністратори розвʼязують цю проблему.
Квота ресурсів, визначена обʼєктом ResourceQuota, задає обмеження загального споживання ресурсів у кожному просторі імен. ResourceQuota також може обмежувати кількість обʼєктів, які можна створити в просторі імен, за типом API, а також загальний обсяг інфраструктурних ресурсів, які можуть споживати обʼєкти API в цьому просторі імен.
Увага:
Ані конкуренція, ані зміни до квоти не вплинуть на вже створені ресурси.Як працюють ResourceQuotas у Kubernetes
ResourceQuotas працюють так:
Різні команди працюють у різних просторах імен. Цей поділ можна забезпечити за допомогою RBAC або будь-якого іншого механізму авторизації.
Адміністратор кластера створює принаймні одну ResourceQuota для кожного простору імен.
- Щоб ці вимоги залишалися чинними, адміністратор кластера також повинен обмежити доступ до видалення або оновлення цієї ResourceQuota, наприклад, визначивши ValidatingAdmissionPolicy.
Користувачі створюють ресурси (Podʼи, Services тощо) у просторі імен, а система квот відстежує використання, щоб воно не перевищувало жорстких обмежень ресурсів, визначених у ResourceQuota.
Ви можете застосувати до ResourceQuota область дії, щоб обмежити, де вона застосовується.
Якщо створення або оновлення ресурсу порушує обмеження квоти, панель управління відхиляє цей запит із кодом стану HTTP 403 Forbidden. Помилка містить повідомлення з поясненням обмеження, яке було б порушено.
Якщо квоти увімкнено в просторі імен для таких ресурсів, як cpu та memory, користувачі повинні вказувати запити або обмеження для цих значень під час визначення Podʼа; інакше система квот може відхилити створення Podʼа.
Покроковий навчальний матеріал щодо квот ресурсів показує приклад того, як уникнути цієї проблеми.
Примітка:
- Ви можете визначити LimitRange, щоб примусово встановлювати стандартні значення для Podʼів, які не задають вимог до обчислювальних ресурсів (щоб користувачам не доводилося памʼятати про це).
Часто ви не створюєте Podʼи безпосередньо; наприклад, ви зазвичай створюєте обʼєкт керування робочим навантаженням, такий як Deployment. Якщо ви створюєте Deployment, який намагається використати більше ресурсів, ніж доступно, створення Deployment (або іншого обʼєкта керування робочим навантаженням) буде успішним, але Deployment може бути не в змозі забезпечити існування всіх керованих ним Podʼів. У цьому випадку ви можете перевірити стан Deployment, наприклад, за допомогою kubectl describe, щоб дізнатися, що сталося.
- Для ресурсів
cpu та memory ResourceQuotas вимагають, щоб кожен (новий) Pod у цьому просторі імен встановлював обмеження для цього ресурсу. Якщо ви застосовуєте квоту ресурсів у просторі імен для cpu або memory, ви та інші клієнти повинні вказувати requests або limits для цього ресурсу для кожного нового Podʼа, який ви надсилаєте. Якщо ви цього не зробите, панель управління може відхилити допуск цього Podʼа. - Для інших ресурсів: ResourceQuota працює та ігнорує Podʼи в просторі імен, які не встановлюють обмеження або запит для цього ресурсу. Це означає, що ви можете створити новий Pod без обмеження/запиту тимчасового сховища, якщо квота ресурсів обмежує тимчасове сховище цього простору імен.
Ви можете використовувати LimitRange для автоматичного встановлення стандартного запиту для цих ресурсів.
Назва обʼєкта ResourceQuota має бути дійсною назвою DNS-піддомену.
Приклади політик, які можна створити за допомогою просторів імен та квот:
- У кластері місткістю 32 GiB RAM і 16 ядер дозвольте команді A використовувати 20 GiB і 10 ядер, дозвольте команді B використовувати 10 GiB і 4 ядра, а 2 GiB і 2 ядра залиште в резерві для майбутнього розподілу.
- Обмежте простір імен "testing" використанням 1 ядра та 1 GiB RAM. Дозвольте простору імен "production" використовувати будь-який обсяг.
У випадку, коли загальна місткість кластера менша за суму квот просторів імен, може виникнути конкуренція за ресурси. Це обробляється за принципом «перший прийшов — перший обслужений».
Увімкнення квоти ресурсів
Підтримка ResourceQuota стандартно увімкнена в багатьох дистрибутивах Kubernetes. Вона увімкнена, коли прапорець --enable-admission-plugins= API-сервера має ResourceQuota серед своїх аргументів.
Квота ресурсів застосовується в певному просторі імен, коли у цьому просторі імен є
ResourceQuota.
Типи квот ресурсів
Механізм ResourceQuota дозволяє застосовувати різні види обмежень. У цьому розділі описано типи обмежень, які можна застосовувати.
Квота на інфраструктурні ресурси
Ви можете обмежити загальну суму обчислювальних ресурсів, які можна запитати в певному просторі імен.
Підтримуються такі типи ресурсів:
| Назва ресурсу | Опис |
|---|
limits.cpu | Для всіх Podʼів у нетермінальному стані сума обмежень CPU не може перевищувати це значення. |
limits.memory | Для всіх Podʼів у нетермінальному стані сума обмежень памʼяті не може перевищувати це значення. |
requests.cpu | Для всіх Podʼів у нетермінальному стані сума запитів CPU не може перевищувати це значення. |
requests.memory | Для всіх Podʼів у нетермінальному стані сума запитів памʼяті не може перевищувати це значення. |
hugepages-<size> | Для всіх Podʼів у нетермінальному стані кількість запитів великих сторінок зазначеного розміру не може перевищувати це значення. |
cpu | Те саме, що і requests.cpu |
memory | Те саме, що і requests.memory |
Квота для розширених ресурсів
Крім згаданих вище ресурсів, у випуску 1.10 було додано підтримку квот для розширених ресурсів.
Оскільки overcommit для розширених ресурсів не дозволяється, немає сенсу вказувати і requests, і limits для одного й того самого розширеного ресурсу у квоті. Тому для розширених ресурсів дозволені лише елементи квоти з префіксом requests..
Візьмімо як приклад ресурс GPU: якщо назва ресурсу — nvidia.com/gpu і ви хочете обмежити загальну кількість запитаних GPU в просторі імен до 4, ви можете визначити квоту так:
requests.nvidia.com/gpu: 4
Докладніше дивіться в розділі Перегляд та встановлення квот.
Квота для запитів на ресурси DRA
Запити на ресурси DRA (Dynamic Resource Allocation) можуть запитувати ресурси DRA за класом пристроїв. Наприклад, для класу пристроїв із назвою examplegpu, якщо ви хочете обмежити загальну кількість GPU, запитаних у просторі імен, до 4, ви можете визначити квоту так:
examplegpu.deviceclass.resource.k8s.io/devices: 4
Коли увімкнено виділення розширених ресурсів за допомогою DRA, той самий клас пристроїв із назвою examplegpu можна запитувати через розширений ресурс або явно, коли в полі ExtendedResourceName класу пристроїв задано, скажімо, example.com/gpu, тоді ви можете визначити квоту так:
requests.example.com/gpu: 4
або неявно, використовуючи похідну назву розширеного ресурсу від назви класу пристроїв examplegpu, тоді ви можете визначити квоту так:
requests.deviceclass.resource.kubernetes.io/examplegpu: 4
Усі пристрої, запитані через запити на ресурси або розширені ресурси, враховуються у всіх трьох наведених вище квотах. Квота розширеного ресурсу, наприклад requests.example.com/gpu: 4, також враховує пристрої, надані втулком пристроїв.
Докладніше дивіться в розділі Перегляд та встановлення квот.
Квота для сховища
Ви можете обмежити загальний обсяг сховища для томів, який можна запитати в певному просторі імен.
Крім того, ви можете обмежити споживання ресурсів сховища на основі повʼязаного StorageClass.
| Назва ресурсу | Опис |
|---|
requests.storage | Для всіх PersistentVolumeClaims сума запитів на сховище не може перевищувати це значення. |
persistentvolumeclaims | Загальна кількість PersistentVolumeClaims, які можуть існувати у просторі імен. |
<storage-class-name>.storageclass.storage.k8s.io/requests.storage | Для всіх PersistentVolumeClaims, повʼязаних із <storage-class-name>, сума запитів на сховище не може перевищувати це значення. |
<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims | Для всіх PersistentVolumeClaims, повʼязаних із <storage-class-name>, загальна кількість PersistentVolumeClaims, які можуть існувати у просторі імен. |
Наприклад, якщо ви хочете встановити квоту для сховища зі StorageClass gold окремо від StorageClass bronze, ви можете визначити квоту так:
gold.storageclass.storage.k8s.io/requests.storage: 500Gibronze.storageclass.storage.k8s.io/requests.storage: 100Gi
Квота для локального тимчасового сховища
СТАН ФУНКЦІОНАЛУ:
Alpha since Kubernetes v1.8
| Назва ресурсу | Опис |
|---|
requests.ephemeral-storage | Для всіх Podʼів у просторі імен сума запитів на локальне тимчасове сховище не може перевищувати це значення. |
limits.ephemeral-storage | Для всіх Podʼів у просторі імен сума обмежень на локальне тимчасове сховище не може перевищувати це значення. |
ephemeral-storage | Те саме, що і requests.ephemeral-storage. |
Примітка:
Під час використання середовища виконання контейнерів CRI логи контейнерів зараховуються до квоти тимчасового сховища. Це може призвести до неочікуваного виселення Podʼів, які вичерпали свої квоти сховища.
Докладніше дивіться в розділі Архітектура логів.
Квота на кількість обʼєктів
Ви можете встановити квоту на загальну кількість одного конкретного типу ресурсу в API Kubernetes, використовуючи такий синтаксис:
count/<resource>.<group> для ресурсів із груп API, що не належать до основної (non-core)count/<resource> для ресурсів з основної групи API (core)
Наприклад, API PodTemplate входить до основної групи API, тому, якщо ви хочете обмежити кількість обʼєктів PodTemplate у просторі імен, використовуйте count/podtemplates.
Такі типи квот корисні для захисту від вичерпання сховища панелі управління. Наприклад, ви можете обмежити кількість Secrets на сервері, враховуючи їхній великий розмір. Занадто велика кількість Secrets у кластері може фактично завадити запуску серверів і контролерів. Ви можете встановити квоту для Jobs, щоб захиститися від неправильно налаштованого CronJob. CronJobs, які створюють занадто багато Jobs у просторі імен, можуть призвести до відмови в обслуговуванні.
Якщо ви визначаєте квоту таким чином, вона застосовується до API Kubernetes, які є частиною API-сервера, та до будь-яких власних ресурсів, що підтримуються CustomResourceDefinition. Наприклад, щоб створити квоту на власний ресурс widgets у групі API example.com, використовуйте count/widgets.example.com. Якщо ви використовуєте агрегацію API для додавання власних API, які не визначені як CustomResourceDefinitions, основна панель управління Kubernetes не застосовує квоту до агрегованого API. Очікується, що сервер розширення API забезпечуватиме застосування квоти, якщо це доречно для цього власного API.
Загальний синтаксис
Нижче наведено список поширених прикладів типів обʼєктів, які ви можете захотіти підпорядкувати квоті на кількість обʼєктів, перелічених за рядками конфігурації, які ви будете використовувати.
count/podscount/persistentvolumeclaimscount/servicescount/secretscount/configmapscount/deployments.appscount/replicasets.appscount/statefulsets.appscount/jobs.batchcount/cronjobs.batch
Спеціалізований синтаксис
Існує інший синтаксис для встановлення такого самого типу квоти, який працює лише для певних типів API. Підтримуються такі типи:
| Назва ресурсу | Опис |
|---|
configmaps | Загальна кількість ConfigMaps, які можуть існувати в просторі імен. |
persistentvolumeclaims | Загальна кількість PersistentVolumeClaims, які можуть існувати в просторі імен. |
pods | Загальна кількість Podʼів у нетермінальному стані, які можуть існувати в просторі імен. Pod перебуває в термінальному стані, якщо .status.phase in (Failed, Succeeded) є true. |
replicationcontrollers | Загальна кількість ReplicationControllers, які можуть існувати в просторі імен. |
resourcequotas | Загальна кількість ResourceQuotas, які можуть існувати в просторі імен. |
services | Загальна кількість Services, які можуть існувати в просторі імен. |
services.loadbalancers | Загальна кількість Services типу LoadBalancer, які можуть існувати в просторі імен. |
services.nodeports | Загальна кількість NodePorts, виділених Services типу NodePort чи LoadBalancer, які можуть існувати в просторі імен. |
secrets | Загальна кількість Secrets, які можуть існувати в просторі імен. |
Наприклад, квота pods рахує та обмежує максимальну кількість pods, створених в одному просторі імен, які не є термінальними. Ви можете встановити квоту pods у просторі імен, щоб уникнути випадку, коли користувач створює багато невеликих Podʼів і вичерпує запас IP-адрес Podʼів у кластері.
Більше прикладів можна знайти в розділі Перегляд та встановлення квот.
Перегляд та встановлення квот
kubectl підтримує створення, оновлення та перегляд квот:
kubectl create namespace myspace
cat <<EOF > compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
requests.cpu: "1"
requests.memory: "1Gi"
limits.cpu: "2"
limits.memory: "2Gi"
requests.nvidia.com/gpu: 4
EOF
kubectl create -f ./compute-resources.yaml --namespace=myspace
cat <<EOF > object-counts.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
spec:
hard:
configmaps: "10"
persistentvolumeclaims: "4"
pods: "4"
replicationcontrollers: "20"
secrets: "10"
services: "10"
services.loadbalancers: "2"
EOF
kubectl create -f ./object-counts.yaml --namespace=myspace
kubectl get quota --namespace=myspace
NAME AGE
compute-resources 30s
object-counts 32s
kubectl describe quota compute-resources --namespace=myspace
Name: compute-resources
Namespace: myspace
Resource Used Hard
-------- ---- ----
limits.cpu 0 2
limits.memory 0 2Gi
requests.cpu 0 1
requests.memory 0 1Gi
requests.nvidia.com/gpu 0 4
kubectl describe quota object-counts --namespace=myspace
Name: object-counts
Namespace: myspace
Resource Used Hard
-------- ---- ----
configmaps 0 10
persistentvolumeclaims 0 4
pods 0 4
replicationcontrollers 0 20
secrets 1 10
services 0 10
services.loadbalancers 0 2
kubectl також підтримує квоту на кількість обʼєктів для всіх стандартних ресурсів простору імен, використовуючи синтаксис count/<resource>.<group>:
kubectl create namespace myspace
kubectl create quota test --hard=count/deployments.apps=2,count/replicasets.apps=4,count/pods=3,count/secrets=4 --namespace=myspace
kubectl create deployment nginx --image=nginx --namespace=myspace --replicas=2
kubectl describe quota --namespace=myspace
Name: test
Namespace: myspace
Resource Used Hard
-------- ---- ----
count/deployments.apps 1 2
count/pods 2 3
count/replicasets.apps 1 4
count/secrets 1 4
Квота та місткість кластера
ResourceQuotas не залежать від місткості кластера. Вони виражаються в абсолютних одиницях. Отже, якщо ви додаєте вузли до свого кластера, це не дає автоматично кожному простору імен можливості споживати більше ресурсів.
Іноді можуть знадобитися більш складні політики, такі як:
- Пропорційно розподіляти загальні ресурси кластера між кількома командами.
- Дозволяти кожному орендарю збільшувати використання ресурсів за потреби, але мати щедре обмеження, щоб запобігти випадковому вичерпанню ресурсів.
- Виявляти попит з боку одного простору імен, додавати вузли та збільшувати квоту.
Такі політики можна реалізувати, використовуючи ResourceQuotas як будівельні блоки, написавши «контролер», який стежить за використанням квот і коригує жорсткі обмеження квот кожного простору імен відповідно до інших сигналів.
Зверніть увагу, що квота ресурсів розподіляє сукупні ресурси кластера, але не створює обмежень щодо вузлів: Podʼи з кількох просторів імен можуть працювати на одному вузлі.
Області дії квоти
Кожна квота може мати повʼязаний набір scopes. Квота вимірюватиме використання ресурсу лише тоді, коли він відповідає перетину перелічених областей дії.
Коли до квоти додається область дії, вона обмежує кількість підтримуваних ресурсів тими, що стосуються цієї області дії. Ресурси, вказані у квоті поза дозволеним набором, призводять до помилки перевірки.
Kubernetes 1.37 підтримує такі області дії:
ResourceQuotas із заданою областю дії також можуть мати необовʼязкове поле scopeSelector. Ви визначаєте один або кілька виразів відповідності, які вказують operators і, якщо це доречно, набір values для відповідності. Наприклад:
scopeSelector:
matchExpressions:
- scopeName: BestEffort # Відповідає Podʼам із якістю обслуговування best-effort
operator: Exists # необовʼязково; для області дії BestEffort "Exists" мається на увазі
scopeSelector підтримує такі значення в полі operator:
InNotInExistsDoesNotExist
Якщо оператором є In або NotIn, поле values повинно мати щонайменше одне значення. Наприклад:
scopeSelector:
matchExpressions:
- scopeName: PriorityClass
operator: In
values:
- middle
Якщо оператором є Exists або DoesNotExist, поле values НЕ повинно бути вказане.
Область дії для Podʼів Best effort
Ця область дії відстежує лише квоту, спожиту Podʼами. Вона відповідає лише Podʼам, які мають клас QoS best-effort.
operator для scopeSelector повинен бути Exists.
Область дії для Podʼів Not-best-effort
Ця область дії відстежує лише квоту, спожиту Podʼами. Вона відповідає лише Podʼам, які мають клас QoS Guaranteed або Burstable.
operator для scopeSelector повинен бути Exists.
Область дії для Podʼів Non-terminating
Ця область дії відстежує лише квоту, спожиту Podʼами, які не завершуються. operator для scopeSelector повинен бути Exists.
Pod вважається таким, що не завершується, якщо поле .spec.activeDeadlineSeconds не встановлено.
Ви можете використовувати ResourceQuota з цією областю дії для керування такими ресурсами:
count.podspodscpumemoryrequests.cpurequests.memorylimits.cpulimits.memory
Область дії Podʼів Terminating
Ця область дії відстежує лише квоту, спожиту Podʼами, які завершуються. operator для scopeSelector повинен бути Exists.
Pod вважається таким, що завершується, якщо поле .spec.activeDeadlineSeconds встановлено на будь-яке число.
Ви можете використовувати ResourceQuota з цією областю дії для керування такими ресурсами:
count.podspodscpumemoryrequests.cpurequests.memorylimits.cpulimits.memory
Область дії спорідненості Podʼів між просторами імен
СТАН ФУНКЦІОНАЛУ:
GA since Kubernetes v1.24
Ви можете використовувати область дії квоти CrossNamespacePodAffinity, щоб обмежити, які простори імен можуть мати Podʼи з правилами спорідненості, що охоплюють кілька просторів імен. Зокрема, вона контролює, яким Podʼам дозволено встановлювати поля namespaces або namespaceSelector у правилах (анти)спорідненості Podʼів.
Може бути бажаним не дозволяти користувачам використовувати правила спорідненості між просторами імен, оскільки Pod з обмеженнями антиспорідненості може не дати Podʼам з усіх інших просторів імен бути запланованими в домені відмов.
За допомогою цієї області дії ви (як адміністратор кластера) можете заборонити певним просторам імен (наприклад, foo-ns у наведеному нижче прикладі) мати Podʼи, які використовують спорідненість Podʼів між просторами імен. Для цього створіть у цьому просторі імен обʼєкт ResourceQuota з областю дії CrossNamespacePodAffinity та жорстким обмеженням 0:
apiVersion: v1
kind: ResourceQuota
metadata:
name: disable-cross-namespace-affinity
namespace: foo-ns
spec:
hard:
pods: "0"
scopeSelector:
matchExpressions:
- scopeName: CrossNamespacePodAffinity
operator: Exists
Якщо ви хочете стандартно заборонити використання namespaces та namespaceSelector і дозволити його лише для певних просторів імен, ви можете налаштувати CrossNamespacePodAffinity як обмежений ресурс, встановивши для прапорця kube-apiserver --admission-control-config-file шлях до такого конфігураційного файлу:
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: ResourceQuotaConfiguration
limitedResources:
- resource: pods
matchScopes:
- scopeName: CrossNamespacePodAffinity
operator: Exists
За такої конфігурації Podʼи можуть використовувати namespaces та namespaceSelector у спорідненості Podʼів лише тоді, коли простір імен, у якому вони створені, має обʼєкт квоти ресурсів з областю дії CrossNamespacePodAffinity та жорстким обмеженням, більшим або рівним кількості Podʼів, що використовують ці поля.
Область дії PriorityClass
СТАН ФУНКЦІОНАЛУ:
GA since Kubernetes v1.17
ResourceQuota з областю дії PriorityClass відповідає лише тим Podʼам, які мають певний клас пріоритету, і лише якщо будь-який scopeSelector у специфікації квоти вибирає певний Pod.
Podʼи можна створювати з певним пріоритетом. Ви можете контролювати споживання системних ресурсів Podʼом на основі його пріоритету, використовуючи поле scopeSelector у специфікації квоти.
Коли область дії квоти задано для PriorityClass за допомогою поля scopeSelector, ResourceQuota може відстежувати (і обмежувати) лише такі ресурси:
podscpumemoryephemeral-storagelimits.cpulimits.memorylimits.ephemeral-storagerequests.cpurequests.memoryrequests.ephemeral-storage
Приклад
Цей приклад створює ResourceQuota, яка відповідає Podʼам з певними пріоритетами. Приклад працює так:
- Podʼи в кластері мають один із трьох PriorityClasses: "low", "medium", "high".
- Якщо ви хочете спробувати це, використовуйте тестовий кластер і налаштуйте ці три PriorityClasses, перш ніж продовжувати.
- Для кожного пріоритету створюється один обʼєкт квоти.
Перегляньте цей набір ResourceQuotas:
apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-high
spec:
hard:
cpu: "1000"
memory: "200Gi"
pods: "10"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values: ["high"]
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-medium
spec:
hard:
cpu: "10"
memory: "20Gi"
pods: "10"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values: ["medium"]
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-low
spec:
hard:
cpu: "5"
memory: "10Gi"
pods: "10"
scopeSelector:
matchExpressions:
- operator: In
scopeName: PriorityClass
values: ["low"]
Застосуйте YAML за допомогою kubectl create.
kubectl create -f https://k8s.io/examples/policy/quota.yaml
resourcequota/pods-high created
resourcequota/pods-medium created
resourcequota/pods-low created
Перевірте, що квота Used дорівнює 0, за допомогою команди kubectl describe quota.
Name: pods-high
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 1k
memory 0 200Gi
pods 0 10
Name: pods-low
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 5
memory 0 10Gi
pods 0 10
Name: pods-medium
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 10
memory 0 20Gi
pods 0 10
Створіть Pod з пріоритетом "high".
apiVersion: v1
kind: Pod
metadata:
name: high-priority
spec:
containers:
- name: high-priority
image: ubuntu
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
resources:
requests:
memory: "10Gi"
cpu: "500m"
limits:
memory: "10Gi"
cpu: "500m"
priorityClassName: high
Створіть Pod:
kubectl create -f https://k8s.io/examples/policy/high-priority-pod.yaml
Перевірте, що статистика "Used" для квоти пріоритету "high", pods-high, змінилася, а інші дві квоти залишилися без змін.
Name: pods-high
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 500m 1k
memory 10Gi 200Gi
pods 1 10
Name: pods-low
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 5
memory 0 10Gi
pods 0 10
Name: pods-medium
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 10
memory 0 20Gi
pods 0 10
Стандартне обмеження споживання PriorityClass
Може бути бажаним, щоб Podʼи з певним пріоритетом, наприклад "cluster-services", дозволялися в просторі імен тоді й лише тоді, коли існує відповідний обʼєкт квоти.
За допомогою цього механізму оператори можуть обмежувати використання певних високопріоритетних класів обмеженою кількістю просторів імен, і не кожен простір імен зможе стандартно споживати ці класи пріоритету.
Для цього потрібно використати прапорець kube-apiserver --admission-control-config-file, щоб передати шлях до такого конфігураційного файлу:
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: ResourceQuotaConfiguration
limitedResources:
- resource: pods
matchScopes:
- scopeName: PriorityClass
operator: In
values: ["cluster-services"]
Потім створіть обʼєкт квоти ресурсів у просторі імен kube-system:
apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-cluster-services
spec:
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["cluster-services"]
kubectl apply -f https://k8s.io/examples/policy/priority-class-resourcequota.yaml -n kube-system
resourcequota/pods-cluster-services created
У цьому випадку створення Podʼа буде дозволено, якщо:
priorityClassName Podʼа не вказано.priorityClassName Podʼа має значення, відмінне від cluster-services.priorityClassName Podʼа встановлено на cluster-services, Pod створюється у просторі імен kube-system і пройшов перевірку квоти ресурсів.
Запит на створення Podʼа буде відхилено, якщо його priorityClassName встановлено на cluster-services і Pod створюється в просторі імен, відмінному від kube-system.
Область дії VolumeAttributesClass
СТАН ФУНКЦІОНАЛУ:
GA since Kubernetes v1.36
More information about this feature
This is a stable feature in Kubernetes, and has been since version v1.36. It was first available in the v1.29 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 VolumeAttributesClass, Kubernetes ignores it but does not report any error.
Ця область дії відстежує лише квоту, спожиту PersistentVolumeClaims.
PersistentVolumeClaims можна створювати з певним VolumeAttributesClass і змінювати після створення. Ви можете контролювати споживання ресурсів сховища PVC на основі повʼязаних VolumeAttributesClasses, використовуючи поле scopeSelector у специфікації квоти.
PVC посилається на повʼязаний VolumeAttributesClass через такі поля:
spec.volumeAttributesClassNamestatus.currentVolumeAttributesClassNamestatus.modifyVolumeStatus.targetVolumeAttributesClassName
Відповідна ResourceQuota зіставляється й споживається лише тоді, коли ResourceQuota має scopeSelector, який вибирає PVC.
Коли область дії квоти задано для класу атрибутів тому за допомогою поля scopeSelector, обʼєкт квоти може відстежувати лише такі ресурси:
persistentvolumeclaimsrequests.storage
Детальніше про це читайте в розділі Обмеження використання сховища.
Що далі
3 - Обмеження та резервування ID процесів
СТАН ФУНКЦІОНАЛУ:
GA since Kubernetes v1.20
Kubernetes дозволяє обмежувати кількість ідентифікаторів процесів (PID), які може використовувати Pod. Також можна зарезервувати певну кількість доступних для розподілу PID для кожного вузла для використання операційною системою та демонами (а не Podʼами).
Ідентифікатори процесів (PID) є фундаментальним ресурсом на вузлах. Досягти обмеження на кількість завдань, не досягнувши жодних інших обмежень ресурсів, дуже просто, і це може призвести до нестабільної роботи хост-машини.
Адміністраторам кластерів потрібні механізми, щоб гарантувати, що Podʼи, які працюють у кластері, не зможуть спричинити вичерпання PID, яке перешкоджає роботі демонів хоста (таких як kubelet або kube-proxy, а потенційно й середовище виконання контейнерів). Крім того, важливо обмежувати PID між Podʼами, щоб вони мали обмежений вплив на інші робочі навантаження на тому самому вузлі.
Примітка:
На деяких інсталяціях Linux операційна система стандартно встановлює низьке обмеження PID, наприклад 32768. Розгляньте можливість збільшення значення /proc/sys/kernel/pid_max.Ви можете налаштувати kubelet для обмеження кількості PID, які може споживати конкретний Pod. Наприклад, якщо ОС хоста вашого вузла налаштовано на використання максимум 262144 PID і очікується, що на ньому розміщуватиметься менше ніж 250 Podʼів, можна надати кожному Podʼу бюджет у 1000 PID, щоб запобігти вичерпанню загальної кількості доступних PID на вузлі. Якщо адміністратор хоче застосувати overcommit для PID, як для CPU чи памʼяті, це теж можливо, але з певними додатковими ризиками. У будь-якому випадку один Pod не зможе вивести з ладу всю машину. Цей вид обмеження ресурсів допомагає запобігти впливу простих форк-бомб на роботу всього кластера.
Обмеження PID на рівні Podʼа дозволяє адміністраторам захистити один Pod від іншого, але не гарантує, що всі Podʼи, заплановані на цей хост, не зможуть вплинути на вузол загалом. Обмеження на рівні Podʼа також не захищає самі агенти вузла від вичерпання PID.
Ви також можете зарезервувати певну кількість PID для накладних витрат вузла, окремо від виділених для Podʼів. Це подібно до того, як ви можете резервувати CPU, памʼять чи інші ресурси для використання операційною системою та іншими засобами поза Podʼами та їхніми контейнерами.
Обмеження PID є важливим доповненням до запитів і обмежень обчислювальних ресурсів. Однак ви вказуєте його інакше: замість того, щоб визначати обмеження ресурсу Podʼа в .spec Podʼа, ви налаштовуєте обмеження як параметр kubelet. Обмеження PID, визначені в Podʼі, наразі не підтримуються.
Увага:
Це означає, що обмеження, яке застосовується до Podʼа, може відрізнятися залежно від того, куди заплановано Pod. Щоб спростити ситуацію, найкраще, щоб усі вузли використовували однакові обмеження та резервування ресурсу PID.Обмеження PID вузла
Kubernetes дозволяє зарезервувати певну кількість ідентифікаторів процесів для системного використання. Щоб налаштувати резервування, використовуйте параметр pid=<кількість> у параметрах командного рядка kubelet --system-reserved та --kube-reserved. Вказане вами значення оголошує, що вказану кількість ідентифікаторів процесів буде зарезервовано відповідно для системи в цілому та для системних демонів Kubernetes.
Обмеження PID на рівні Podʼа
Kubernetes дозволяє обмежити кількість процесів, запущених у Podʼі. Ви вказуєте це обмеження на рівні вузла, а не налаштовуєте його як обмеження ресурсів для певного Podʼа. Кожен вузол може мати власне обмеження PID. Щоб налаштувати обмеження, ви можете вказати параметр командного рядка kubelet --pod-max-pids або встановити PodPidsLimit у конфігураційному файлі kubelet.
Виселення на основі PID
Ви можете налаштувати kubelet так, щоб він починав завершувати Pod, коли той поводиться некоректно та споживає аномальну кількість ресурсів. Ця можливість називається виселенням (eviction). Ви можете налаштувати обробку випадків нестачі ресурсів для різних сигналів виселення. Використовуйте сигнал виселення pid.available, щоб налаштувати поріг кількості PID, які використовує Pod. Ви можете встановити мʼякі та жорсткі політики виселення. Однак навіть із жорсткою політикою виселення, якщо кількість PID зростає дуже швидко, вузол усе ще може перейти в нестабільний стан, досягнувши обмеження PID вузла. Значення сигналу виселення обчислюється періодично і НЕ забезпечує дотримання обмеження.
Обмеження PID — на рівні Podʼа та на рівні вузла — встановлює жорстку межу. Щойно її буде досягнуто, робоче навантаження почне отримувати помилки під час спроб отримати новий PID. Це може призвести або не призвести до повторного планування Podʼа, залежно від того, як робоче навантаження реагує на ці помилки та як для Podʼа налаштовано проби життєздатності та готовності. Однак, якщо обмеження встановлено правильно, ви можете гарантувати, що робочі навантаження інших Podʼів та системні процеси не вичерпають PID, коли один Pod поводиться некоректно.
Що далі