Перейти до вмісту

Модуль 2.2: Контрольні групи (cgroups)

Основи системи | Складність: [MEDIUM] | Час: 30–35 хв

Перед початком цього модуля:


Що ви зможете робити після цього модуля

Розділ «Що ви зможете робити після цього модуля»

Після проходження цього модуля ви зможете:

  • Налаштувати ліміти ресурсів cgroup для CPU, пам’яті та I/O
  • Пояснити, як requests та limits у Kubernetes відображаються на налаштування cgroup
  • Діагностувати контейнери зі статусом OOMKilled, читаючи облік пам’яті cgroup
  • Порівняти cgroups v1 та v2 й пояснити, чому індустрія мігрує на v2

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

Якщо namespaces забезпечують ізоляцію (що процес може бачити), то cgroups забезпечують обмеження (скільки ресурсів процес може спожити).

Кожен запит на ресурси (requests) та ліміт (limits) у Kubernetes, кожне обмеження пам’яті в Docker — усе це працює через cgroups.

Розуміння cgroups допоможе вам:

  • Розбиратися з OOM kills — чому мій контейнер вбили?
  • Налаштовувати ліміти — встановлювати правильні значення для стабільної роботи.
  • Розуміти “гальмування” (throttling) — чому додаток повільний, хоча CPU не на 100%?
  • Налагодити сервіси — systemd також використовує cgroups для керування службами.

Коли под Kubernetes виселяється (evicted) через нестачу пам’яті або ваш застосунок загадково гальмує — причина в cgroups.


  • cgroups були розроблені інженерами Google у 2006 році. Їм потрібен був спосіб контролювати використання ресурсів у своїх гігантських дата-центрах.

  • Ліміти пам’яті в Kubernetes активують OOM killer — коли контейнер перевищує свій ліміт, ядро вбиває його миттєво. Немає поступового сповільнення — тільки раптова смерть.

  • Ліміти CPU працюють інакше — ваш контейнер не вбивають, його просто «гальмують» (throttling), якщо він використав свою квоту часу процесора.

  • cgroups v2 — тепер стандарт. Починаючи з Kubernetes 1.25+, версія v2 використовується за замовчуванням. Вона набагато краще організована, ніж стара версія v1.


Control groups (cgroups) організовують процеси в ієрархічні групи, використання ресурсів якими можна обмежувати, моніторити та контролювати.

┌─────────────────────────────────────────────────────────────────┐
│ ІЄРАРХІЯ CGROUP │
│ │
│ / (корінь) │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ system │ │ user │ │ kubepods│ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ┌────┴────┐ ... ┌─────┴─────┐ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐ │
│ │ sshd │ │ docker │ │ burstable│ │guaranteed│ │
│ │ 512 MB │ │ 2 GB │ │ (под) │ │ (под) │ │
│ └─────────┘ └─────────┘ └────┬─────┘ └────┬─────┘ │
└─────────────────────────────────────────────────────────────────┘

Що контролюють cgroups:

Розділ «Що контролюють cgroups:»
  • CPU: Час процесора та конкретні ядра.
  • Memory: Оперативна пам’ять та файл підкачки (swap).
  • PIDs: Кількість процесів (захист від fork-бомб).
  • I/O: Швидкість запису/читання на диск.
  • Network: Пріоритети мережевого трафіку.

Ліміти пам’яті та OOM Killer

Розділ «Ліміти пам’яті та OOM Killer»

Це найкритичніша частина для Kubernetes.

Ліміт пам'яті = 512MB
Використано: 400MB (OK)
Використано: 512MB → КЕРНЕЛЬ ВБИВАЄ ПРОЦЕС (OOM KILL)

Як зрозуміти, що стався OOM Kill?

Розділ «Як зрозуміти, що стався OOM Kill?»
  1. В системних логах:
    Terminal window
    dmesg | grep -i "oom"
  2. В Kubernetes:
    Terminal window
    kubectl describe pod <назва>
    # Шукайте статус: Last State: Terminated, Reason: OOMKilled

Запам’ятайте: OOM Kill надсилає сигнал SIGKILL (9). Програма не встигає нічого зберегти — вона просто зникає.


На відміну від пам’яті, перевищення ліміту CPU не є фатальним.

Kubernetes вимірює CPU в “міліядрах” (m). 500m = 50% одного ядра. Якщо ваш ліміт 500m, а програма хоче 100%, ядро просто поставить її на паузу на частину часу. Це називається throttling.

Terminal window
# Перевірити, чи ваш процес "гальмують" (cgroups v2)
cat /sys/fs/cgroup/system.slice/nginx.service/cpu.stat
# Шукайте nr_throttled та throttled_usec

Важливо: Kubernetes 1.35+ вимагає cgroup v2. Підтримка старої версії v1 вимкнена. Якщо ваші сервери дуже старі (CentOS 7 тощо) — Kubernetes на них більше не запуститься.

Чому v2 краща?

  • Єдина ієрархія: Всі ресурси (CPU, RAM) керуються в одному місці.
  • Кращий контроль I/O: Нарешті можна нормально обмежувати швидкість дисків.
  • Менше багів: v1 була надто складною і заплутаною.

  1. Що станеться з контейнером, якщо він перевищить ліміт оперативної пам’яті?

    Відповідь Ядро активує OOM Killer (Out-of-Memory Killer), який миттєво вб'є процес у контейнері за допомогою сигналу SIGKILL. Контейнер буде перезапущено.
  2. Чим відрізняється поведінка системи при перевищенні ліміту CPU від ліміту Memory?

    Відповідь Перевищення ліміту пам'яті призводить до вбивства процесу (OOM Kill). Перевищення ліміту CPU призводить лише до сповільнення процесу (Throttling) — він просто чекатиме своєї черги на процесор довше.
  3. Яка компанія винайшла cgroups?

    Відповідь Google.
  4. Де в файловій системі Linux можна побачити налаштування cgroups?

    Відповідь У директорії `/sys/fs/cgroup/`.

Завдання: Побачити cgroups у дії на вашій системі.

  1. Подивіться, до яких груп належить ваша оболонка:
    Terminal window
    cat /proc/$$/cgroup
  2. Подивіться на використання ресурсів сервісами (аналог top для cgroups):
    Terminal window
    systemd-cgtop
  3. (Тільки якщо є Docker) Запустіть контейнер із лімітом пам’яті й подивіться, де він з’явиться:
    Terminal window
    docker run -d --name mem-limit --memory 100m nginx
    find /sys/fs/cgroup -name "*mem-limit*"

Критерії успіху: Ви розумієте, що cgroups — це механізм обмеження ресурсів, і знаєте, як перевірити їх статус.


  • Namespaces = Ізоляція (хто я? що я бачу?).
  • Cgroups = Обмеження (скільки мені можна з’їсти?).
  • Memory limit — фатальний (OOM Kill).
  • CPU limit — сповільнює (Throttling).
  • v2 — майбутнє і стандарт для сучасного Kubernetes.

Далі: Модуль 2.3: Capabilities та LSMs — дізнайтеся, як Linux надає права доступу тонше, ніж просто “root або не root”.