Bài viết mới nhất

Tổng 2300 bài
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

Image layers và overlayfs: vì sao 100 container cùng image không tốn 100 lần đĩa

Image Docker là chồng nhiều layer chỉ-đọc; container chỉ thêm một lớp ghi mỏng chồng lên. Bài này chạy thật: docker history phơi bày từng layer, tự dựng overlayfs để thấy copy-on-write (sửa file thì copy sang upper, lower giữ nguyên), và ba container cùng image mỗi cái chỉ thêm 4.1kB trong khi 67.9MB image dùng chung.

DevOps 22/09/2026 6 phút

Dockerfile cache: vì sao đổi một dòng code khiến build cài lại toàn bộ dependencies

Mỗi lệnh Dockerfile là một layer được cache; đổi một layer làm hỏng cache của MỌI layer sau nó. Đặt COPY . . trước khi cài dependencies là lỗi kinh điển: sửa một dòng code buộc build cài lại toàn bộ deps. Bài này đo thật hai Dockerfile cùng app: sau khi sửa code, bản sai mất 3.8s (cài lại deps), bản đúng chỉ 0.6s.

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 5 phút

Multi-stage build: vì sao image Go của bạn nặng 400MB thay vì 3MB

Để BUILD một chương trình cần trình biên dịch và cả toolchain hàng trăm MB; để CHẠY chỉ cần binary vài MB. Nếu build và chạy cùng một image, image cuối mang theo cả toolchain. Bài này build một chương trình Go thật hai cách: một-stage cho image 407MB, multi-stage (copy binary sang scratch) cho 3.4MB — cùng chạy y hệt, giảm ~120 lần.