DevOps 31/08/2026 7 phút

Tôi cấp một ServiceAccount đúng quyền 'chỉ đọc' Secret — rồi đọc ra ngay SieuBiMat123, và ba quyền nghe vô hại khác hoá ra tương đương quyền quản trị

Cấp quyền từng lớp cho một ServiceAccount rồi đo chính xác nó mở ra được gì. Role bó rất chặt (đúng động từ, đúng tài nguyên, đúng namespace), nhưng 'chỉ đọc' Secret là đọc được mọi mật khẩu vì base64 không phải mã hoá. Ba quyền nghe vô hại trong một bản YAML — create pods, get secrets, create rolebindings — đều là đường leo thang lên quyền toàn cụm. Và kubectl auth can-i là cách duy nhất kiểm quyền thực tế thay vì đọc YAML rồi đoán.

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 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

Đặt minAvailable=4 cho một deployment 4 bản, và cái node đó không bao giờ rút ra bảo trì được nữa — cùng một lệnh drain: 2,1 giây, hay treo vĩnh viễn

PodDisruptionBudget bảo Kubernetes đừng đuổi quá nhiều bản cùng lúc. Đo bằng cách rút node ba lần: không PDB xong trong 2,1 giây, minAvailable=4 trên 4 bản treo mãi không xong, minAvailable=3 xong trong 6,6 giây. Bài học lớn: minAvailable là con số tuyệt đối nên thành bẫy khi HPA thu gọn số bản ban đêm — cho-phep-duoi tụt về 0 đúng lúc bạn muốn bảo trì; maxUnavailable=1 thì an toàn ở mọi quy mô. Và PDB chỉ chặn việc đuổi TỰ NGUYỆN, nó không phải cơ chế bảo đảm tính sẵn sàng.

DevOps 31/08/2026 8 phút

ulimit thề rằng 'unlimited' — nhưng container của tôi chết đứng ở đúng 19.162 tiến trình, và cái trần đó không nằm ở chỗ ulimit nhìn

Container có hai cái trần vô hình mà nó thường chạm trước cả trần RAM. ulimit -u báo unlimited trong khi trần thật là 19.162 (pids.max của cgroup, đúng 15% threads-max) — công cụ cũ tự tin trả lời sai câu hỏi vì nó chỉ thấy cơ chế RLIMIT có từ trước cgroup. Chạm trần thì lỗi tên là EAGAIN 'thử lại sau' nhưng không bao giờ hết, nên phần lớn thư viện thử lại vô hạn và biến một cái trần cứng thành vòng lặp đốt CPU không báo lỗi. Và lời khuyên 'nhớ tăng ulimit -n' đã hết việc vì trình chạy container đặt sẵn một triệu.

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.