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.
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 redip link add veth-red type veth peer name veth-hostip link set veth-red netns redip addr add 198.51.100.1/24 dev veth-host && ip link set veth-host upip -n red addr add 198.51.100.2/24 dev veth-redip -n red link set veth-red up && ip -n red link set lo upip netns exec red ping -c2 198.51.100.1ip 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 (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).