DevOps 30/08/2026 8 phút

Hai container khác nhau trong một pod gọi nhau qua localhost — và 'kubectl delete pod' mất đúng bằng grace period dù ứng dụng tắt ngay lập tức hay bướng bỉnh không chịu chết

Câu 'pod là đơn vị nhỏ nhất, không phải container' nghe như chi tiết thuật ngữ. Đo thử thì ra hai điều thú vị: hai container trong một pod chung một IP và nói chuyện qua localhost, và thời gian xoá pod hoàn toàn không phụ thuộc việc ứng dụng tắt nhanh hay chậm — nó chỉ đo đúng terminationGracePeriodSeconds.

DevOps 30/08/2026 8 phút

Cơ sở dữ liệu chớp tắt vài giây, và cả bốn pod ứng dụng — vốn đang khoẻ mạnh — rơi vào vòng lặp khởi động lại chỉ vì một dòng livenessProbe nghe rất hợp lý

Probe là thứ hiếm hoi mà cấu hình sai còn tệ hơn không cấu hình. Dựng ba kiểu sai phổ biến nhất và đo hậu quả: livenessProbe kiểm phụ thuộc ngoài khiến cả fleet restart khi DB chết (và restart không sửa được gì, còn làm phục hồi tệ hơn); timeoutSeconds mặc định 1 giây giết pod hoàn toàn khoẻ chỉ vì nó trả lời chậm hơn một giây; readinessProbe với failureThreshold 1 làm cả dịch vụ mất hết endpoint khi mọi pod cùng trượt một nhịp — mà kubectl get pods trông gần như bình thường. Và vì sao nhiều ứng dụng KHÔNG nên có livenessProbe.

DevOps 30/08/2026 8 phút

Ba probe của Kubernetes nghe như cùng một việc 'kiểm tra sức khoẻ' — nhưng khi hỏng, một cái giết container, một cái chỉ ngừng gửi việc, một cái bảo hai cái kia chờ

Ba probe trả lời ba câu hỏi khác nhau và Kubernetes phản ứng theo ba cách khác hẳn. livenessProbe hỏng thì container bị khởi động lại (và nếu lỗi không tự khỏi thì lặp mãi); readinessProbe hỏng thì pod bị gỡ khỏi Endpoints nhưng KHÔNG khởi động lại (RESTARTS=0, vẫn Running, chỉ 0/1); startupProbe thì tạm dừng cả hai cái kia cho ứng dụng khởi động lâu kịp lên. Đo cả ba, và vì sao dùng startupProbe đúng hơn hẳn việc nâng initialDelaySeconds — cái sau chữa lúc khởi động nhưng làm ì việc phát hiện lỗi suốt đời container.

DevOps 30/08/2026 8 phút

83% thời gian một lệnh kubectl chỉ là khởi động binary, không phải việc của cụm — và một cụm Kubernetes không ai đụng vào vẫn gọi API server ba lượt mỗi giây

kube-apiserver là cửa duy nhất vào cụm, nặng 265 MB — gấp năm lần etcd. Nhưng phần việc thật của nó cho một lệnh kubectl chỉ 4–8 mili giây; 24 mili giây còn lại là binary khởi động. Bài này đo chi phí một lệnh, cơ chế watch thay cho hỏi liên tục, và chỗ nguy hiểm nhất: webhook admission nằm ngay giữa đường ghi.

DevOps 30/08/2026 7 phút

Pod Guaranteed mang điểm chết -997, BestEffort mang 1000 — và tôi đọc được thứ tự bị OOM giết mà không phải làm cạn RAM node nào

Lớp QoS của Kubernetes không phải quy ước mềm — nó được chống lưng bằng một con số kernel thật: oom_score_adj, cộng thẳng vào điểm mà OOM killer dùng để chọn nạn nhân. Guaranteed mang -997 (gần như bất tử), BestEffort mang 1000 (chết đầu tiên), Burstable theo công thức 1000-(1000×requests/RAM node) khớp chính xác ba lần đo. Nghĩa là requests.memory không chỉ dùng để xếp lịch — nó trực tiếp hạ điểm chết của pod. Và mẹo đo: hiện tượng khó dựng (làm cạn node 16 GB) thì đọc thẳng con số quyết định nó.

DevOps 30/08/2026 7 phút

Vượt giới hạn CPU thì container bị bóp chậm lại nhưng sống nhăn; vượt giới hạn bộ nhớ thì bị giết ngay — cùng một cặp tham số, hai số phận trái ngược

requests và limits trông như một cặp, nhưng là hai cơ chế khác nhau, và CPU với bộ nhớ còn được xử lý khác nhau nữa. Đo cả bốn tổ hợp: limit CPU 100m thì container bị bóp 100% chu kỳ mà RESTARTS vẫn 0 (chậm mà không chết), còn limit RAM 128Mi thì OOMKilled exitCode 137 và RESTARTS tăng đều. Khác biệt cốt lõi: CPU nén được nên bị bóp, bộ nhớ không nén được nên bị giết. Kèm ba lớp QoS, vì sao không khai requests là tự nhận vé chết trước, và vì sao limits.cpu thường nên bỏ.