Вики / Процессы
cgroups и namespaces (как устроены контейнеры)
Изоляция (namespaces) и лимиты ресурсов (cgroups) — фундамент контейнеров и systemd.
Контейнеры (Docker) — это не «лёгкие ВМ», а обычные процессы Linux с двумя механизмами ядра:
- namespaces — изоляция: процесс видит свой набор PID, сети, точек монтирования, пользователей, имени хоста (как будто отдельная система);
- cgroups — лимиты и учёт ресурсов: CPU, память, I/O для группы процессов.
Этим же пользуется systemd (каждая служба — в своей cgroup).
lsns # все namespaces и какие процессы в них
lsns -t net # только сетевые namespaces
ls -l /proc/$$/ns/ # namespaces текущей оболочки
sudo nsenter -t PID -n ss -tlnp # выполнить в СЕТЕВОМ namespace процесса PID
sudo nsenter -t PID -a bash # войти во ВСЕ namespaces процесса (как «внутрь контейнера»)
unshare --net --pid --fork bash # запустить шелл в новых namespace (демо изоляции)
ip netns list # именованные сетевые namespaces (см. ip)
Типы: pid (процессы), net (сеть/интерфейсы), mnt (монтирования), user (UID),
uts (hostname), ipc, cgroup.
systemd-cgls # дерево cgroups (кто где)
systemd-cgtop # потребление ресурсов по cgroup (как top)
cat /sys/fs/cgroup/cgroup.controllers # доступные контроллеры
systemctl status nginx # внизу — CGroup и текущее потребление
# лимиты службе — через systemd (правильный способ):
sudo systemctl set-property nginx.service MemoryMax=512M CPUQuota=50% IOWeight=50
systemctl show nginx -p MemoryMax -p CPUQuota -p MemoryCurrent
# или в юните [Service]: MemoryMax=512M / CPUQuota=50% / TasksMax=100
CPUQuota=50% — половина одного ядра; MemoryMax= — жёсткий потолок (превышение →
cgroup-OOM именно этой службе, не всей системе); TasksMax= — лимит числа процессов.
Процесс «убит», в логах memory cgroup / oom-kill
Служба упёрлась в MemoryMax своей cgroup — ядро убило её (cgroup-OOM, не глобальный).
systemctl show svc -p MemoryMax -p MemoryCurrent; подними лимит или почини утечку
(см. memory-swap).
Служба «съедает» весь CPU/диск
Ограничь через systemd: CPUQuota=, IOWeight=/IOReadBandwidthMax=. Это cgroups,
а не ulimit (тот — на процесс/пользователя, иные вещи).
Контейнер не видит другие процессы/сеть — это норма
Так задумано (namespaces изолируют). Чтобы «заглянуть внутрь» — nsenter -t PID -a
в нужные namespaces процесса.
Где реально потребление по службам
systemd-cgtop (как top, но по cgroup/службам) — сразу видно, какая служба грузит.
lsns # namespaces (изоляция)
systemd-cgls ; systemd-cgtop # дерево / потребление cgroups
sudo nsenter -t PID -a bash # войти во все namespaces процесса
sudo systemctl set-property svc MemoryMax=512M CPUQuota=50% TasksMax=100
systemctl show svc -p MemoryCurrent -p MemoryMax
См. также
- ulimit и лимиты ресурсов — Процессы
- systemd — Службы и systemd
- Docker (контейнеры) — Службы и systemd