Sổ tay kỹ thuật

Linux namespaces và cgroups v2 – nền tảng của container

concept#linux#containers#docker· cập nhật 2026-11-06

Hiểu namespace (netns, veth) và cgroups v2 để debug mạng container, giới hạn tài nguyên và đọc đúng các lệnh docker/systemd.

Sửa trang này
Mục lục

Container không phải VM: đó là process bình thường của kernel host, được cô lập bằng namespace (thấy gì) và bị giới hạn bằng cgroups (dùng được bao nhiêu). Docker, containerd, Kubernetes, systemd đều chỉ là lớp điều khiển hai cơ chế này.

Namespace

Namespace Cô lập Ví dụ tác động
net Interface, IP, route, iptables/nftables, socket Container có eth0 và bảng route riêng
mnt Mount point Container thấy rootfs của image
pid Không gian PID Process đầu tiên trong container là PID 1
uts Hostname hostname khác host
ipc Shared memory, message queue
user Ánh xạ UID/GID Root trong container là user thường trên host (rootless)
cgroup Góc nhìn cây cgroup Container chỉ thấy cgroup của nó

Mạng container: netns + veth + bridge

flowchart LR E1["ctr1 eth0 (netns ctr1)"] --- V1["vethA trên host"] E2["ctr2 eth0 (netns ctr2)"] --- V2["vethB trên host"] V1 --- BR["bridge docker0"] V2 --- BR BR -->|"NAT MASQUERADE"| UP["eno1 ra Internet"]

veth là cặp interface nối như sợi cáp: một đầu trong netns của container, đầu kia gắn vào bridge trên host. Ra ngoài thì đi qua NAT trên host (Docker mặc định bridge docker0 dải 172.17.0.0/16).

Tự dựng lại để hiểu (chạy trên máy lab, cần root):

netns-lab.sh
ip netns add red
ip link add veth-red type veth peer name veth-host
ip link set veth-red netns red
ip addr add 198.51.100.1/24 dev veth-host && ip link set veth-host up
ip -n red addr add 198.51.100.2/24 dev veth-red
ip -n red link set veth-red up && ip -n red link set lo up
ip netns exec red ping -c2 198.51.100.1
ip netns del red        # xoá netns, veth đi kèm cũng mất
Mục đích Lệnh
Liệt kê namespace đang có lsns / lsns -t net
netns tạo bằng ip netns ip netns list
Vào netns của container Docker (dùng tool của host) nsenter -t $(docker inspect -f '{{.State.Pid}}' <ctr>) -n ip addr
tcpdump bên trong container không có tcpdump nsenter -t <pid> -n tcpdump -i eth0 -nn
Đầu veth trên host ứng với container ip -n <netns> link xem eth0@ifN, rồi ip link | grep '^N:' trên host

cgroups v2

cgroups v2 (unified hierarchy) là một cây duy nhất tại /sys/fs/cgroup, mặc định trên Ubuntu 22.04+, Debian 11+, RHEL 9. systemd quản lý cây này: mỗi service là một cgroup dưới system.slice, container Docker nằm dưới system.slice/docker-<id>.scope (với cgroup driver systemd).

File trong cgroup Ý nghĩa Ví dụ
cgroup.controllers Controller khả dụng cpuset cpu io memory pids
cgroup.procs PID thuộc cgroup Ghi PID vào để chuyển process
memory.max Trần RAM, vượt thì OOM kill trong cgroup 536870912 hoặc max
memory.high Ngưỡng bắt đầu throttle/reclaim
memory.current / memory.events Đang dùng / số lần oom_kill
cpu.max quota period (µs) 50000 100000 = 0.5 CPU
cpu.weight Tỷ trọng chia CPU khi tranh chấp (mặc định 100)
io.max Giới hạn IOPS/bps theo thiết bị 8:0 rbps=10485760
pids.max Số process/thread tối đa Chặn fork bomb
*.pressure PSI: thời gian bị nghẽn vì tài nguyên cat memory.pressure
Mục đích Lệnh
Đang chạy cgroup v2? stat -fc %T /sys/fs/cgroup → cgroup2fs
Cây cgroup theo service systemd-cgls
top theo cgroup systemd-cgtop
Process thuộc cgroup nào cat /proc/<pid>/cgroup
Đặt giới hạn cho service đang chạy systemctl set-property nginx.service MemoryMax=1G CPUQuota=200%
Chạy lệnh trong cgroup tạm có giới hạn systemd-run --scope -p MemoryMax=500M -p CPUQuota=50% ./job.sh
Giới hạn container Docker docker run --memory 512m --cpus 0.5 --pids-limit 200 ...
Container bị OOM chưa docker inspect -f '{{.State.OOMKilled}}' <ctr>

So sánh nhanh

Namespace cgroups
Trả lời câu hỏi Process thấy gì Process dùng được bao nhiêu
Giao diện syscall unshare, setns, clone Filesystem /sys/fs/cgroup
Công cụ ip netns, unshare, nsenter, lsns systemctl, systemd-run, systemd-cgls
Lỗi hay gặp Container không ra mạng, sai DNS OOMKilled, CPU bị throttle

Khi nào dùng

  • Debug mạng container mà image không có công cụ: nsenter -n để dùng ip, ss, tcpdump của host trong netns container.
  • Lab mạng nhẹ trên một máy (nhiều "router" bằng netns + veth, chạy FRR trong từng netns) thay vì dựng nhiều VM.
  • Giới hạn tài nguyên cho script/agent chạy nền bằng MemoryMax=/CPUQuota= trong systemd service mà không cần Docker.
  • Hiểu vì sao container bị kill: memory.events và OOMKilled, xem thêm Linux performance troubleshooting.
  • Lỗi mạng Docker cụ thể: Docker networking troubleshooting.