linux-labs

Вики / Процессы

cgroups и namespaces (как устроены контейнеры)

Концепция Linux · cgroups v2 ПроцессыКонтейнерыЯдро

Изоляция (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

См. также