DevOps 31/08/2026 8 phút

Pod báo CrashLoopBackOff nhưng container chưa từng chạy một giây nào — cột STATUS của Kubernetes đang mô tả việc nó đang làm, không phải việc đã hỏng

Dựng bảy sự cố thật rồi đo xem công cụ nào nói thật. CrashLoopBackOff che hai nguyên nhân hoàn toàn khác nhau — ứng dụng chết (đọc logs) và lệnh khởi động không tồn tại (logs rỗng, exit 128, phải đọc events). ContainerCreating nghe như đang tiến triển nhưng đứng đó vĩnh viễn vì thiếu Secret. Quy tắc dùng ngay: nhật ký rỗng mà restarts>0 thì container không crash, nó không khởi động nổi — và bảng mã thoát 128/137/143 nói container chết thế nào.

DevOps 31/08/2026 7 phút

Ai cũng bảo nginx non-root chết vì không mở nổi cổng 80 — tôi đo thì cổng 80 mở ngon lành, thứ giết nó là một lệnh mkdir

Thêm runAsUser: 1000 vào nginx thì pod chết — nhưng không phải vì cổng. Log chỉ thẳng: lỗi mkdir /var/cache/nginx, tức lỗi ghi hệ tệp, sửa bằng chown chứ chẳng cần đặc quyền gì. Đo tiếp cái ai cũng lặp lại 'cổng dưới 1024 cần root hoặc NET_BIND_SERVICE': uid 1000 mở cổng 80 vẫn được, capability kia chẳng làm gì, vì ip_unprivileged_port_start trong netns container là 0. Và một lần thử fsGroup không tái tạo nổi lỗi vì thư mục emptyDir là 0777 — bài học về phép thử dễ dãi cho kết quả xanh vô nghĩa.

DevOps 31/08/2026 8 phút

Pod distroless không có cả sh lẫn ls, kubectl exec bó tay hoàn toàn — nhưng vẫn đọc được cấu hình và biến môi trường thật của nó qua /proc/1/root

Image càng gọn thì kẻ tấn công càng ít thứ để dùng — và bạn cũng vậy lúc gỡ rối. Khi exec vô dụng với distroless, kubectl debug luồn một ephemeral container vào ĐÚNG pod đang hỏng mà không khởi động lại gì. Đo cái bẫy lớn nhất: thiếu --target thì container gỡ rối nằm không gian PID riêng, không thấy tiến trình nào của ứng dụng (PID 1 là sh của chính nó, không phải /pause của mục tiêu). Có --target rồi thì đọc cả hệ tệp lẫn /proc/1/environ thật của container mục tiêu — thứ exec không bao giờ với tới.

DevOps 31/08/2026 7 phút

Job xong việc trong 5 giây nhưng Kubernetes báo chạy hết 41 giây — thủ phạm là một sidecar không biết khi nào nên dừng

Từ Kubernetes 1.29, một dòng restartPolicy: Always biến init container thành sidecar — không chặn bước sau, sống suốt đời pod, và tự bị giết khi container chính thoát (chữa hẳn cái bệnh CronJob-có-service-mesh chạy mãi không kết thúc). Nhưng đo dấu thời gian ra một điều bất ngờ: Job 'xong' vẫn tốn 41 giây cho việc 5 giây, vì sidecar busybox không bắt SIGTERM nên cộng thẳng cả hạn ân hạn 30 giây vào mỗi lần chạy. Hạ hạn xuống 5 thì DURATION về 16 giây, chênh đúng 25.

DevOps 31/08/2026 7 phút

Xoá pod db-1 của StatefulSet rồi để nó dựng lại: IP đổi, nhưng tên, PVC và dữ liệu 'du lieu cua db-1' còn nguyên vẹn — đó là cả điểm khác biệt với Deployment

Deployment giả định các bản thay thế được cho nhau; với cơ sở dữ liệu thì không. Đo ba thứ StatefulSet có mà Deployment không: khởi động tuần tự (4,3 / 9,6 / 14,9 giây, chờ bản trước), danh tính ổn định (tên DNS và PVC riêng cho từng bản — xoá pod rồi dựng lại thì chỉ IP đổi, dữ liệu còn), và thu gọn không xoá PVC (an toàn dữ liệu nhưng vẫn trả tiền đĩa). Cùng cái bẫy nguy hiểm nhất: node chết thì StatefulSet CHỜ, vì hai bản cùng tên ghi cùng dữ liệu là hỏng — và --force là lời cam đoan 'bản cũ đã chết' mà nếu sai thì mất dữ liệu.

DevOps 31/08/2026 7 phút

Vết NoExecute đuổi sạch pod khỏi node trong 1,3 giây, còn anti-affinity cứng khiến 2 trong 5 bản không bao giờ chạy — bốn cơ chế điều pod, và chỗ ai cũng lẫn

Đo bốn cơ chế điều pod chạy ở đâu trên cụm thật. NoExecute đuổi mọi pod đang chạy trong 1,3 giây (so với node chết mất gần 6 phút). Điểm hay nhầm nhất: toleration chỉ CHO PHÉP pod lên node có vết, nó KHÔNG ép — muốn ép pod lên node GPU phải thêm nodeSelector, vì 'giữ kẻ khác ra' và 'đưa mình vào' là hai việc tách biệt. Và anti-affinity cứng chặn thẳng (3 Running, 2 Pending, số bản bị trần bởi số node) trong khi mềm rải đều mà không bao giờ để pod Pending.