Модуль 4.3: Вимоги та ліміти ресурсів
Складність:
[MEDIUM]— Критично для продакшену, впливає на плануванняЧас на виконання: 35–45 хвилин
Передумови: Модуль 1.1 (Поди), розуміння концепцій CPU та пам’яті
Що ви зможете робити
Розділ «Що ви зможете робити»Після завершення цього модуля ви зможете:
- Налаштувати запити та ліміти ресурсів для CPU та пам’яті у специфікаціях Підів
- Діагностувати проблеми OOMKilled та обмеження CPU, зіставляючи ліміти зі спостережуваною поведінкою
- Спроєктувати розподіл ресурсів, що балансує продуктивність, вартість та надійність планування
- Пояснити як запити впливають на планування, а ліміти — на обмеження під час виконання
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Запити та ліміти ресурсів контролюють, скільки CPU та пам’яті можуть використовувати ваші контейнери. Без них один контейнер може спожити всі ресурси вузла, залишивши інші поди без ресурсів. Належне управління ресурсами є необхідним для стабільності кластера.
На іспиті CKAD перевіряють:
- Встановлення запитів та лімітів
- Розуміння різниці між ними
- Що відбувається при перевищенні лімітів
- LimitRanges та ResourceQuotas
Аналогія з орендою квартири
Запити ресурсів — це як гарантоване паркомісце — вам забезпечено цей простір. Ліміти — це як максимальна місткість будівлі — ви можете тимчасово використовувати більше простору, але є жорстка межа. Якщо ви її перевищите (пам’ять), вас виселять (OOMKilled). Якщо будівля заповнена (вузол), нові мешканці (поди) чекають, поки звільниться місце.
Запити проти лімітів
Розділ «Запити проти лімітів»Визначення
Розділ «Визначення»| Термін | Значення | Коли застосовується |
|---|---|---|
| Запит (Request) | Гарантований мінімум ресурсів | Під час планування |
| Ліміт (Limit) | Максимально дозволені ресурси | Під час виконання |
Як вони працюють
Розділ «Як вони працюють»┌─────────────────────────────────────────────────────────────┐│ Запит ресурсів проти ліміту │├─────────────────────────────────────────────────────────────┤│ ││ Пам'ять: ││ ├── Запит: 256Mi (гарантовано, для планування) ││ ├── Фактичне використання може бути від 0 до ліміту ││ └── Ліміт: 512Mi (жорстка межа, перевищення = OOMKill) ││ ││ CPU: ││ ├── Запит: 100m (гарантовано, для планування) ││ ├── Може перевищувати запит, якщо вузол має вільну ││ │ потужність ││ └── Ліміт: 500m (обмежується, якщо перевищено, НЕ вбиває) ││ ││ ┌────────────────────────────────────────────────────┐ ││ │ │ ││ │ 0 Запит Факт. Ліміт │ ││ │ | | | | │ ││ │ ├───────────┼───────────┼────────────┤ │ ││ │ │гарантовано│ з можл. │ макс. │ │ ││ │ │ │ перевищ. │ │ │ ││ │ └───────────┴───────────┴────────────┘ │ ││ │ │ ││ └────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────┘Встановлення ресурсів
Розділ «Встановлення ресурсів»Базовий синтаксис
Розділ «Базовий синтаксис»apiVersion: v1kind: Podmetadata: name: resource-demospec: containers: - name: app image: nginx resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" cpu: "500m"Одиниці вимірювання
Розділ «Одиниці вимірювання»CPU:
| Значення | Опис |
|---|---|
1 | 1 ядро CPU |
1000m | 1000 мілікорів = 1 ядро |
500m | 0.5 ядра |
100m | 0.1 ядра (10%) |
Пам’ять:
| Значення | Опис |
|---|---|
128Mi | 128 мебібайтів (на основі 1024) |
1Gi | 1 гібібайт = 1024 Mi |
128M | 128 мегабайтів (на основі 1000) |
1G | 1 гігабайт = 1000 M |
Що відбувається при досягненні лімітів
Розділ «Що відбувається при досягненні лімітів»Перевищення ліміту пам’яті
Розділ «Перевищення ліміту пам’яті»Контейнер використовує > ліміту → OOMKilled → Контейнер перезапускається# Перевірити, чи під був OOMKilledk describe pod my-pod | grep -A5 "Last State"k get pod my-pod -o jsonpath='{.status.containerStatuses[0].lastState}'Перевищення ліміту CPU
Розділ «Перевищення ліміту CPU»Контейнер використовує > ліміту → Обмежується (сповільнюється, НЕ вбивається)Обмеження CPU непомітне для контейнера — він просто працює повільніше.
Класи QoS
Розділ «Класи QoS»Kubernetes призначає класи якості обслуговування на основі налаштувань ресурсів:
| Клас QoS | Умова | Пріоритет витіснення |
|---|---|---|
| Guaranteed | Запити = Ліміти для всіх контейнерів | Останній (захищений) |
| Burstable | Запити < Ліміти (або встановлено лише одне) | Середній |
| BestEffort | Запити та ліміти не встановлені | Перший (витісняється першим) |
Приклад Guaranteed
Розділ «Приклад Guaranteed»resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "256Mi" # Те саме, що запит cpu: "100m" # Те саме, що запитПриклад Burstable
Розділ «Приклад Burstable»resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" # Більше за запит cpu: "500m" # Більше за запитПриклад BestEffort
Розділ «Приклад BestEffort»resources: {} # Ресурси не визначеніВплив на планування
Розділ «Вплив на планування»Під не планується
Розділ «Під не планується»Якщо жоден вузол не має достатньо доступних ресурсів (ємність - виділені запити):
# Перевірити, чому під у стані Pendingk describe pod my-pod
# В подіях буде:# 0/3 nodes are available: 3 Insufficient cpu.# або# 0/3 nodes are available: 3 Insufficient memory.Перевірка ємності вузла
Розділ «Перевірка ємності вузла»# Ємність та доступні ресурси вузлаk describe node NODE_NAME | grep -A5 Capacityk describe node NODE_NAME | grep -A5 Allocatable
# Вже виділені ресурсиk describe node NODE_NAME | grep -A10 "Allocated resources"LimitRange
Розділ «LimitRange»Стандартні значення та обмеження на рівні простору імен:
apiVersion: v1kind: LimitRangemetadata: name: cpu-memory-limitsspec: limits: - default: # Ліміти за замовчуванням, якщо не вказано cpu: "500m" memory: "512Mi" defaultRequest: # Запити за замовчуванням, якщо не вказано cpu: "100m" memory: "256Mi" max: # Максимально дозволено cpu: "2" memory: "2Gi" min: # Мінімально дозволено cpu: "50m" memory: "64Mi" type: Container# Переглянути LimitRangek get limitrangek describe limitrange cpu-memory-limitsResourceQuota
Розділ «ResourceQuota»Загальні обмеження ресурсів на рівні простору імен:
apiVersion: v1kind: ResourceQuotametadata: name: compute-quotaspec: hard: requests.cpu: "4" requests.memory: "8Gi" limits.cpu: "8" limits.memory: "16Gi" pods: "10"# Переглянути використання квотиk get resourcequotak describe resourcequota compute-quotaШвидка довідка
Розділ «Швидка довідка»# Встановити ресурси в специфікації подаresources: requests: cpu: "100m" memory: "256Mi" limits: cpu: "500m" memory: "512Mi"
# Перевірити ресурси подаk get pod POD -o jsonpath='{.spec.containers[*].resources}'
# Перевірити ємність вузлаk describe node NODE | grep -A10 "Allocated"
# Перевірити клас QoSk get pod POD -o jsonpath='{.status.qosClass}'Чи знали ви?
Розділ «Чи знали ви?»-
CPU — стисливий ресурс, пам’ять — ні. Якщо ви перевищите ліміт CPU, вас обмежать. Якщо ви перевищите ліміт пам’яті, вас вб’ють.
-
Запити впливають на планування, ліміти — на час виконання. Під із запитом пам’яті 1Gi не буде заплановано на вузлі, де доступно лише 512Mi, навіть якщо контейнер використовує лише 100Mi.
-
Kubernetes не запобігає перевищенню пам’яті. Якщо всі поди одночасно досягнуть своїх лімітів, вузол вичерпає пам’ять і почне вбивати поди.
-
Синтаксис
cpu: 0.1еквівалентнийcpu: 100m(100 мілікорів).
Типові помилки
Розділ «Типові помилки»| Помилка | Чому це шкодить | Рішення |
|---|---|---|
| Ресурси не встановлені | Поди BestEffort витісняються першими | Завжди встановлюйте запити |
| Запит > Ліміт | Некоректно, відхиляється | Запит повинен бути ≤ Ліміту |
| Пам’яті занадто мало | Постійний OOMKilled | Профілюйте застосунок, збільшіть ліміти |
| CPU занадто мало | Застосунок працює повільно | Моніторте за допомогою k top, коригуйте |
| Те саме, що ємність вузла | Немає місця для системних подів | Залишайте запас |
Тест
Розділ «Тест»-
Яка різниця між запитами та лімітами?
Відповідь
Запити — це гарантовані ресурси, які використовуються для рішень планування. Ліміти — це максимально дозволені ресурси, які застосовуються під час виконання. Запити повинні бути ≤ Лімітів. -
Що відбувається, коли контейнер перевищує ліміт пам’яті?
Відповідь
Контейнер отримує OOMKilled (завершується) і може бути перезапущений залежно від політики перезапуску. -
Що відбувається, коли контейнер перевищує ліміт CPU?
Відповідь
Контейнер обмежується (сповільнюється), але НЕ вбивається. CPU — стисливий ресурс. -
Який клас QoS отримує під, якщо запити дорівнюють лімітам?
Відповідь
Guaranteed. Це клас з найвищим пріоритетом, і поди витісняються останніми.
Практична вправа
Розділ «Практична вправа»Завдання: Налаштувати та спостерігати за поведінкою ресурсів.
Частина 1: Базові ресурси
cat << 'EOF' | k apply -f -apiVersion: v1kind: Podmetadata: name: resource-demospec: containers: - name: app image: nginx resources: requests: memory: "64Mi" cpu: "50m" limits: memory: "128Mi" cpu: "100m"EOF
# Перевірити клас QoSk get pod resource-demo -o jsonpath='{.status.qosClass}'echo
# Перевірити ресурсиk get pod resource-demo -o jsonpath='{.spec.containers[0].resources}'Частина 2: Демонстрація OOMKill
cat << 'EOF' | k apply -f -apiVersion: v1kind: Podmetadata: name: memory-hogspec: containers: - name: app image: polinux/stress command: ["stress"] args: ["--vm", "1", "--vm-bytes", "200M", "--vm-hang", "1"] resources: limits: memory: "100Mi"EOF
# Спостерігати за OOMKilledk get pod memory-hog -w
# Перевірити причинуk describe pod memory-hog | grep -A3 "Last State"Очищення:
k delete pod resource-demo memory-hogПрактичні вправи
Розділ «Практичні вправи»Вправа 1: Базові ресурси (Ціль: 2 хвилини)
Розділ «Вправа 1: Базові ресурси (Ціль: 2 хвилини)»cat << 'EOF' | k apply -f -apiVersion: v1kind: Podmetadata: name: drill1spec: containers: - name: nginx image: nginx resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "200m" memory: "256Mi"EOF
k get pod drill1 -o jsonpath='{.spec.containers[0].resources}'echok delete pod drill1Вправа 2: Перевірка класу QoS (Ціль: 2 хвилини)
Розділ «Вправа 2: Перевірка класу QoS (Ціль: 2 хвилини)»# Guaranteed (запити = ліміти)cat << 'EOF' | k apply -f -apiVersion: v1kind: Podmetadata: name: drill2spec: containers: - name: nginx image: nginx resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "100m" memory: "128Mi"EOF
k get pod drill2 -o jsonpath='{.status.qosClass}'echok delete pod drill2Вправа 3: Генерація пода з ресурсами (Ціль: 2 хвилини)
Розділ «Вправа 3: Генерація пода з ресурсами (Ціль: 2 хвилини)»# Використати --dry-run для генерації, потім додати ресурсиk run drill3 --image=nginx --dry-run=client -o yaml > /tmp/drill3.yaml
# Відредагувати для додавання ресурсів (на іспиті використовуйте vim)cat << 'EOF' | k apply -f -apiVersion: v1kind: Podmetadata: name: drill3spec: containers: - name: drill3 image: nginx resources: requests: cpu: 50m memory: 64Mi limits: cpu: 100m memory: 128MiEOF
k get pod drill3 -o yaml | grep -A8 resourcesk delete pod drill3Вправа 4: Deployment з ресурсами (Ціль: 3 хвилини)
Розділ «Вправа 4: Deployment з ресурсами (Ціль: 3 хвилини)»cat << 'EOF' | k apply -f -apiVersion: apps/v1kind: Deploymentmetadata: name: drill4spec: replicas: 2 selector: matchLabels: app: drill4 template: metadata: labels: app: drill4 spec: containers: - name: nginx image: nginx resources: requests: cpu: "50m" memory: "64Mi" limits: cpu: "100m" memory: "128Mi"EOF
k get pods -l app=drill4k delete deploy drill4Вправа 5: Перевірка ресурсів вузла (Ціль: 2 хвилини)
Розділ «Вправа 5: Перевірка ресурсів вузла (Ціль: 2 хвилини)»# Отримати ім'я вузлаNODE=$(k get nodes -o jsonpath='{.items[0].metadata.name}')
# Перевірити ємністьk describe node $NODE | grep -A5 "Capacity:"
# Перевірити доступні ресурсиk describe node $NODE | grep -A5 "Allocatable:"
# Перевірити виділені ресурсиk describe node $NODE | grep -A10 "Allocated resources:"Вправа 6: LimitRange (Ціль: 4 хвилини)
Розділ «Вправа 6: LimitRange (Ціль: 4 хвилини)»# Створити простір імен з LimitRangek create ns drill6
cat << 'EOF' | k apply -n drill6 -f -apiVersion: v1kind: LimitRangemetadata: name: default-limitsspec: limits: - default: cpu: "200m" memory: "256Mi" defaultRequest: cpu: "100m" memory: "128Mi" type: ContainerEOF
# Створити під без ресурсівk run drill6-pod --image=nginx -n drill6
# Перевірити, що стандартні значення застосованіk get pod drill6-pod -n drill6 -o jsonpath='{.spec.containers[0].resources}'echo
# Очищенняk delete ns drill6Наступний модуль
Розділ «Наступний модуль»Модуль 4.4: SecurityContexts — Налаштування параметрів безпеки подів та контейнерів.