namespaces
Types: pid (processes), net (network/interfaces), mnt (mounts), user
(UID), uts (hostname), ipc, cgroup.
Isolation (namespaces) and resource limits (cgroups) — the foundation of containers and systemd.
lsns
namespaces (isolation)
systemd-cgls
cgroup tree
systemd-cgtop
per-cgroup resource usage
sudo nsenter -t PID -a bash
enter all namespaces of a process
sudo systemctl set-property nginx.service MemoryMax=512M CPUQuota=50% TasksMax=100
systemctl show nginx.service -p MemoryCurrent -p MemoryMax
Containers (Docker) are ordinary Linux processes that the kernel handles with two mechanisms:
systemd uses the same mechanisms (each service gets its own cgroup).
Types: pid (processes), net (network/interfaces), mnt (mounts), user
(UID), uts (hostname), ipc, cgroup.
CPUQuota=50% is half of one core; MemoryMax= is a hard ceiling: going over
it causes an OOM inside that service's group (see
oom-killer); TasksMax= limits the number of processes.
systemd places processes in a tree of groups. Services live in the
system.slice slice, user sessions in user.slice; a group of services can
get a slice of its own with Slice=shop.slice in the unit. Whose process it
is shows in the CGroup line of systemctl status and in ps -o unit:
In the training image system.slice and user.slice have the cpu
controller on (cat /sys/fs/cgroup/system.slice/cgroup.subtree_control).
When several groups need the CPU, the kernel first shares it between the
groups by CPUWeight (100 by default), and only inside a group between
processes by their nice value. An experiment on one CPU with
two stress-ng --cpu 1:
| Where the processes are | CPU shares |
|---|---|
two services, CPUWeight=100 and CPUWeight=900 |
9.7 % and 88.7 % |
two services, one with nice -n 19 |
49.1 % and 49.1 % |
one service, one process with nice -n 19 |
96.6 % and 1.4 % |
nice works only between neighbours in a group. To make one service yield
to another, lower its weight or set a ceiling:
The service hit its cgroup's MemoryMax — the kernel killed it (a cgroup-OOM,
not a global one). systemctl show svc -p MemoryMax -p MemoryCurrent; raise
the limit or fix the leak (see oom-killer).
Limit it through systemd: CPUQuota=, IOWeight=/IOReadBandwidthMax=. This
is cgroups, not ulimit (that limits a process/user, different things).
It's by design (namespaces isolate). To "look inside", use nsenter -t PID -a
into the process's namespaces.
systemd-cgtop (like top, but by cgroup/service) — shows right away which
service is loading the system.
Found an inaccuracy? Report an error in the article