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

Token gắn vào pod Kubernetes in kèm cả tên pod lẫn tên node — pod chết là token vô hiệu ngay lập tức, không đợi hết hạn

Mỗi pod tự xưng danh với API server bằng một token ngắn hạn nằm ở /var/run/secrets, và nó không phải chìa khóa vạn năng: token gắn với đúng pod và đúng node, pod bị xoá thì token chết ngay nên kẻ nhặt được token của pod đã chết chẳng dùng được gì. Đo tiếp: cùng token đó gọi API cho kết quả 200/403 khớp CHÍNH XÁC RBAC — vì token chỉ trả lời 'anh là ai', còn 'anh được làm gì' vẫn do RBAC quyết. Và token dài hạn cho CI thì không gắn pod nào, dùng được ở bất cứ đâu, không thu hồi nổi trừ khi xoá ServiceAccount.

DevOps 31/08/2026 7 phút

Mức restricted của Kubernetes từ chối thẳng một pod nginx hoàn toàn vô hại — không vì nó nguy hiểm, mà vì nó không chịu khai rằng mình an toàn

Pod Security Standards bật bằng đúng một nhãn namespace, không cài gì thêm. Đo trên cùng một pod ở ba mức: restricted từ chối cả một nginx bình thường, và toàn văn lời từ chối cho thấy lý do — nó đòi bốn dòng securityContext khai báo tường minh, vì mặc định của Kubernetes là mở (chạy root, giữ đủ capability, cho leo thang quyền) nên im lặng bị coi là nguy hiểm. Thêm cái bẫy: enforce chỉ xét lúc TẠO pod nên pod vi phạm đang chạy vẫn sống, và sự cố chỉ nổ ở lần deploy hoặc scale tiếp theo.

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

Chỉ dời một lệnh echo từ trước ra sau, thời gian xoá pod nhảy từ 0,6 lên 31 giây — và câu 'dùng sh -c là mất tín hiệu' hoá ra sai

Cùng một chương trình Python bắt SIGTERM, bốn cách khai lệnh, thời gian dừng chênh nhau 50 lần. Bí mật nằm ở một tối ưu hoá vô hình của shell: nếu lệnh cuối không còn gì phía sau, shell tự exec thành chính nó nên ứng dụng thành PID 1 và nhận tín hiệu; thêm một echo phía sau là shell phải ở lại giữ PID 1, và kernel bỏ qua mọi tín hiệu PID 1 không đăng ký. Thêm phép đo thứ hai nghịch trực giác: ứng dụng đóng cổng càng NHANH càng mất nhiều yêu cầu, và preStop sleep 5 đưa 3 lỗi về 0.