DevOps 22/09/2026 5 phút

Container không phải máy ảo: nó chỉ là một tiến trình bị cô lập

"Container là VM nhẹ" là hiểu lầm phổ biến nhất về Docker. Thực ra container là một tiến trình thường trên host, được cô lập bằng namespace và giới hạn bằng cgroup — dùng chung kernel host. Bài này chạy thật: alpine và ubuntu cùng thấy một kernel, tự tạo cô lập bằng unshare không cần docker (shell thành PID 1), và đo khởi động 164ms.

DevOps 22/09/2026 6 phút

PID namespace: ứng dụng trong container là PID 1 — và vì sao điều đó khiến docker stop chậm

Trong container, ứng dụng của bạn chạy với PID 1 như init của cả một hệ. Kernel bảo vệ PID 1: nó BỎ QUA các tín hiệu không có handler — nên app không xử lý SIGTERM sẽ phớt lờ docker stop. Bài này chạy thật: PID 1 sống sót sau SIGTERM, docker stop mất 3.1s (chờ grace rồi SIGKILL), và --init (tini) kéo xuống 0.1s.

DevOps 22/09/2026 5 phút

Network namespace: vì sao mỗi container có địa chỉ IP của riêng nó

Container có eth0, IP, bảng định tuyến và cổng của riêng nó — hai container đều mở cổng 80 mà không đụng nhau. Bài này chạy thật: container thấy eth0 172.17.0.5, network namespace mới chỉ có loopback (bị cắt mạng), và tự dựng cặp veth nối hai namespace với ping 0% loss — chính là cách Docker nối container vào bridge của host.

DevOps 22/09/2026 5 phút

cgroups: giới hạn CPU và bộ nhớ container — và vì sao vượt RAM thì bị giết, vượt CPU chỉ chậm

namespace cô lập tầm nhìn; cgroup là nửa còn lại — giới hạn tài nguyên. Bài này chạy thật: --cpus 0.25 làm cùng workload chậm đúng 4 lần, giới hạn nằm trong file /sys/fs/cgroup (memory.max, cpu.max), và container vượt --memory 32m bị kernel OOM kill thật (OOMKilled=true, exit 137). Hai kiểu vượt khác nhau: RAM bị giết, CPU chỉ throttle.

DevOps 22/09/2026 5 phút

Build context: vì sao docker build gửi cả thư mục lên daemon, và .dockerignore cứu bạn

Dấu chấm trong docker build . là build context — docker nén CẢ thư mục và gửi lên daemon trước khi build, kể cả file không dùng tới. Bài này đo thật: một thư mục 70MB (node_modules + .git) gửi nguyên context 70.01MB dù Dockerfile chỉ COPY app.py; thêm .dockerignore, context còn 4.096kB — và quan trọng hơn, nó chặn .env/.git lọt vào image.

DevOps 22/09/2026 6 phút

Bảo mật container: vì sao container mặc định chạy root, và ba lớp phòng thủ giảm rủi ro

Mặc định container chạy dưới quyền root — kẻ khai thác được app là có root trong container. Bài này đo thật ba lớp phòng thủ: --user chạy non-root (ghi /etc bị Permission denied), --cap-drop ALL bỏ quyền đặc quyền (root cũng không chown được), và --read-only khoá rootfs (không ghi được binary). Phòng thủ theo lớp để một container bị chiếm không thành thảm hoạ.