cgroup

Funkcja jądra pozwalająca grupować procesy i ograniczać oraz mierzyć ich zużycie zasobów (CPU, pamięci, I/O). Fundament technologii kontenerów.

cgroup (od control group) to mechanizm jądra Linuksa, który pozwala grupować procesy i nakładać na całe takie grupy limity zużycia zasobów: czasu CPU, pamięci RAM, przepustowości dysku (I/O) czy sieci. Oprócz limitowania cgroups potrafią też te zasoby mierzyć i izolować, dzięki czemu jeden rozpędzony proces nie zagłodzi reszty systemu. To jeden z dwóch filarów, na których stoją kontenery — drugim są namespace’y.

Najprościej myśleć o tym tak: namespace decyduje o tym, co proces widzi (własne PID-y, sieć, system plików), a cgroup o tym, ile zasobów wolno mu zużyć. Cgroups są zorganizowane w drzewo — limit nałożony na grupę nadrzędną obowiązuje wszystkie grupy potomne. Dzisiaj w użyciu jest głównie cgroups v2 z ujednoliconą hierarchią (jeden wspólny punkt montowania w /sys/fs/cgroup), choć w starszych systemach spotkasz jeszcze v1, gdzie każdy kontroler (cpu, memory, blkio…) miał osobne drzewo.

Jak to wygląda w praktyce

Najczęściej nie dotykasz cgroups bezpośrednio — robi to za ciebie warstwa wyżej. Gdy odpalasz docker run --memory=512m --cpus=1.5 nginx, Docker po prostu tworzy cgroup i wpisuje do niej te limity. W Kubernetes resources.limits i requests w manifeście Poda lądują dokładnie tu. Również systemd opakowuje każdą usługę we własną cgroup, więc możesz pisać np. MemoryMax=1G w pliku jednostki.

Chcesz pobawić się ręcznie? Spróbuj systemd-run --scope -p MemoryMax=100M stress --vm 1 --vm-bytes 200M — proces zostanie ubity przez OOM killera, bo przekroczy limit grupy. Drzewo cgroup razem z przypisanymi procesami podejrzysz poleceniem systemd-cgls, a bieżące zużycie zasobów per grupa pokaże systemd-cgtop.

Na co uważać

Częsty mit: „limit pamięci w cgroup chroni proces przed crashem”. Nie — gdy grupa przekroczy memory.max (v2), jądro odpala OOM killer i ubija proces wewnątrz tej cgroup, a nie losowy proces w systemie. To feature, nie bug. Druga pułapka to mieszanie wersji: aplikacje czytające stare ścieżki v1 potrafią się gubić na hoście z czystym v2. Trzecia — limit CPU to nie to samo co przypięcie do rdzeni; cpu.max dławi (throttling) udział w czasie, a fizyczne rdzenie ustawiasz przez cpuset.

Pojęcia powiązane: namespaces, kontenery, Docker, Kubernetes, systemd, OOM killer, LXC, runc, izolacja zasobów.