Container Internals¶
Container không phải một khái niệm của kernel mà là sự kết hợp của nhiều cơ chế cô lập của Linux. Trang này đi qua từng cơ chế kèm lệnh thử. Một số lệnh cần quyền root.
Namespace¶
Namespace làm cho một tiến trình thấy "view" riêng của một loại tài nguyên hệ thống.
| Namespace | Cờ clone() |
Cô lập |
|---|---|---|
| mnt | CLONE_NEWNS |
Cây mount |
| pid | CLONE_NEWPID |
PID (tiến trình đầu tiên là PID 1) |
| net | CLONE_NEWNET |
Interface, bảng route, iptables |
| uts | CLONE_NEWUTS |
Hostname |
| ipc | CLONE_NEWIPC |
SysV IPC, POSIX message queue |
| user | CLONE_NEWUSER |
UID/GID (cho phép "root" trong container ánh xạ sang user thường trên host) |
| cgroup | CLONE_NEWCGROUP |
Gốc cây cgroup |
| time | CLONE_NEWTIME |
Offset của clock |
sudo unshare --fork --pid --mount-proc --uts --net bash # shell trong namespace mới
hostname demo; ps aux; ip link # chỉ thấy tiến trình, mạng của namespace
lsns # liệt kê namespace trên host
sudo nsenter -t <pid> -a bash # vào mọi namespace của một tiến trình
cgroups v2¶
cgroups giới hạn và đo tài nguyên của một nhóm tiến trình. Cây cgroup v2 nằm ở /sys/fs/cgroup.
| Controller | Giới hạn |
|---|---|
| cpu | cpu.max, cpu.weight |
| memory | memory.max, memory.high |
| io | io.max, io.weight |
| pids | pids.max |
cat /sys/fs/cgroup/cgroup.controllers
echo "+memory +pids" | sudo tee /sys/fs/cgroup/cgroup.subtree_control # bật controller cho cgroup con
sudo mkdir /sys/fs/cgroup/demo
echo 100M | sudo tee /sys/fs/cgroup/demo/memory.max
echo $$ | sudo tee /sys/fs/cgroup/demo/cgroup.procs # đưa shell hiện tại vào nhóm
Docker đặt giới hạn tương ứng bằng --memory, --cpus, --pids-limit.
Capabilities, seccomp, LSM¶
- Capabilities chia quyền root thành các quyền nhỏ (
CAP_NET_ADMIN,CAP_SYS_ADMIN...). Container nên bỏ bớt bằng--cap-drop, thêm lại đúng cái cần bằng--cap-add.--privilegedcấp gần như toàn bộ capability và truy cập thiết bị, làm yếu cô lập. - seccomp lọc syscall mà tiến trình được phép gọi. Docker có profile mặc định chặn một số syscall nguy hiểm.
- LSM (AppArmor, SELinux) áp chính sách truy cập bắt buộc theo nhãn hoặc theo profile.
Union filesystem (overlayfs)¶
Image gồm các layer chỉ đọc xếp chồng, mỗi container có thêm một lớp ghi. overlayfs hiện thực mô hình này:
mkdir lower upper work merged
echo hello > lower/a.txt
sudo mount -t overlay overlay -o lowerdir=lower,upperdir=upper,workdir=work merged
echo world > merged/b.txt # file mới xuất hiện trong upper/, lower/ không đổi
Ghi vào file của layer dưới sẽ copy file lên lớp upper trước (copy-on-write). Đây là lý do dữ liệu cần giữ phải đặt ở volume, xem Docker.
OCI và vòng đời¶
Open Container Initiative định nghĩa image spec (cách đóng gói layer và metadata) và runtime spec (cách chạy). Luồng khi chạy một container:
- Công cụ (Docker, Podman) lấy image từ registry, giải nén các layer.
- Tạo một bundle gồm
rootfs/vàconfig.json(mô tả namespace, cgroup, capabilities, mount, tiến trình). - Runtime cấp thấp
runcđọcconfig.json, tạo namespace và cgroup,pivot_rootvàorootfs, rồiexectiến trình.
| Tầng | Ví dụ |
|---|---|
| Công cụ người dùng | Docker CLI, Podman, nerdctl |
| Runtime cấp cao | containerd, CRI-O (quản lý image, vòng đời) |
| Runtime cấp thấp | runc, crun, Kata/gVisor (xem Sandbox & micro-VM) |
| Orchestration | Kubernetes, Docker Compose |
Container trên thiết bị nhúng¶
Cần kernel bật CONFIG_NAMESPACES, CONFIG_CGROUPS, CONFIG_OVERLAY_FS và các tùy chọn liên quan. Có script check-config.sh trong repo Moby để kiểm tra. Với Yocto có layer meta-virtualization cung cấp Docker, containerd, runc, LXC.