Какие лимиты можно ставить с помощью cgroups
Что проверяют
Понимаете ли вы, как на уровне ядра устроены лимиты, которые вы задаёте в Docker и Kubernetes. Следом обычно спрашивают разницу между cgroup v1 и v2 и что происходит с процессом, упёршимся в лимит памяти или CPU.
Как отвечать
cgroups это механизм ядра Linux, который собирает процессы в иерархию групп и навешивает на группы контроллеры ресурсов. В современных дистрибутивах по умолчанию работает cgroup v2 с единой иерархией в /sys/fs/cgroup, поэтому файлы называйте из v2:
- CPU:
cpu.maxзадаёт квоту и период,50000 100000означает половину ядра;cpu.weightзадаёт вес при конкуренции, по умолчанию 100; - ядра и NUMA:
cpuset.cpusиcpuset.mems; - память:
memory.maxжёсткий потолок, за ним OOM killer внутри группы;memory.highмягкий порог, после которого ядро притормаживает процессы и отбирает память;memory.minиmemory.lowзащищают память группы от вытеснения;memory.swap.maxограничивает своп; - диск:
io.maxс лимитамиrbps,wbps,riops,wiopsна устройство иio.weight; - процессы:
pids.max, защита от fork-бомбы; - прочее:
hugetlb,rdma,misc.
Про сеть скажите отдельно: полосу cgroups не ограничивают. В v1 net_cls лишь помечал пакеты, а резал tc; в v2 сетевую политику вешают на группу eBPF-программами.
Свяжите с инструментами: docker run --cpus --memory --pids-limit, в systemd CPUQuota=, MemoryMax=, TasksMax=. В Kubernetes limits.cpu становится cpu.max, requests.cpu становится cpu.weight, limits.memory становится memory.max.
Где спотыкаются
Называют только файлы v1 (memory.limit_in_bytes, cpu.cfs_quota_us) и не знают, какая версия стоит на их серверах. Проверка: stat -fc %T /sys/fs/cgroup выдаёт cgroup2fs на v2.
Путают троттлинг CPU с нехваткой ядер. Квота считается за период 100 мс, многопоточный сервис может выбрать её за 20 мс и простоять остаток, отсюда рост задержек при низкой средней загрузке.
Забывают, что в память группы входит страничный кеш, а рантаймы, не читающие лимиты cgroup, видят все ядра и всю память хоста.