DevOps 31/08/2026 9 phút

Hai pod cùng một dòng mã, đồ thị CPU vẽ y hệt nhau — nhưng một cái chậm gấp 23 lần, và cái chỉ số ai cũng nhìn không hề thấy điều đó

Pod chạy được nhưng chậm khó lần hơn pod hỏng hẳn, vì mọi thứ đều xanh. Hai pod khác nhau đúng mỗi limits.cpu: p50 gần như bằng nhau (4,9 so 3,9 ms) mà p95 chênh 23 lần — và ~96 ms không ngẫu nhiên, đó chính là chu kỳ 100 ms của CFS. Đồ thị 'CPU usage' vẽ hai pod trùng khít vì usage giống nhau; bằng chứng nằm ở cpu.stat: 36/50 chu kỳ bị bóp, 3,28 giây bị treo. Và từ K8s 1.33, đổi limit không cần khởi động lại pod nên p95 rơi từ 95,9 xuống 4,1 ms ngay trong lúc gỡ.

DevOps 31/08/2026 8 phút

Ba lỗi mạng hoàn toàn khác nhau trong Kubernetes cho ra đúng một thông báo và đúng một thời gian — và một lệnh duy nhất phân biệt được cả ba

Nhãn sai, cổng sai, pod chưa sẵn sàng — ba nguyên nhân khác hẳn nhau nhưng đều ra ConnectionRefused ~0 ms, và DNS thì phân giải tốt ở cả ba nên nslookup chẳng chứng minh gì. Đo cách một bảng endpointslices tách được ba bệnh cùng triệu chứng, và vì sao khác biệt Refused-ngay-lập-tức so với Timeout-đúng-hạn-chờ (3004 ms khi bật NetworkPolicy) là phép chia đôi tốt nhất khi lần lỗi mạng.

DevOps 31/08/2026 8 phút

Tôi xoá tay một Service do Helm tạo, rồi hỏi helm status — nó vẫn thản nhiên báo 'deployed', vì Helm chỉ đọc lại biên nhận của chính mình chứ không nhìn vào cụm

Đo hai thứ ở Helm: nó thêm gì vào manifest, và nó KHÔNG biết gì. 380 dòng chart nguồn chỉ sinh ra 100 dòng YAML — giá trị của Helm không nằm ở viết ít mà ở tham số hoá. Trạng thái release là một Secret base64 hai lần rồi gzip, giữ cả mã nguồn chart nên 1,9 KB manifest phình thành 12 KB. Nhưng chỗ đáng nhớ nhất: xoá tay một Service thì helm status vẫn báo deployed, vì Helm không phải bộ điều khiển — nó đọc lại cái nó ĐÃ làm, không phải cái đang CÓ. Và uninstall để lại PVC của StatefulSet lẫn CRD, vì Helm chỉ dọn được thứ chính nó tạo.

DevOps 31/08/2026 8 phút

Tôi từng nói Kustomize gọn hơn Helm — đo lại thì 41 dòng so 37 dòng, gần như hoà; khác biệt thật nằm ở chỗ Kustomize không nhớ nó đã tạo ra gì

Đo Kustomize trên đúng bài toán đã đo Helm, và phát hiện phép so 380-dòng ở phần trước là so nhầm chart mẫu với overlay tối giản. Đo cho công bằng: Helm 37 dòng, Kustomize 41 dòng — đếm dòng là hoà. Khác biệt thật ít ai nói tới: Kustomize không có trạng thái release (0 Secret trong namespace), nên bỏ một tài nguyên khỏi khai báo thì nó vẫn còn nguyên trong cụm — Helm xoá được vì nhớ lần trước, Kustomize phải mượn --applyset. Cùng lúc configMapGenerator băm nội dung nên đổi cấu hình là Deployment tự cuộn lại, thứ Helm phải tự gắn checksum mới có.

DevOps 31/08/2026 9 phút

30 dòng YAML mua được kiểm tra dữ liệu và cột hiển thị riêng cho Kubernetes — nhưng nó tạo ra 0 pod, vì một CRD là danh từ còn Operator mới là động từ

Tự viết cả CRD lẫn Operator rồi đo. 30 dòng YAML cho validation, giá trị mặc định và cột hiển thị mà không viết dòng mã nào — nhưng tạo xong TrangWeb thì namespace vẫn 0 Deployment, 0 pod. 38 dòng Python biến nó thành Operator thật (soBan 2→4 sau ~5 giây, xoá là Deployment tự biến mất nhờ ownerReferences). Chi phí thật lộ ra ở chỗ khác: vòng lặp quét 20 đối tượng gọi 660 lệnh API trong 60 giây, 11 lệnh/giây kể cả khi không có gì đổi — và với 200 đối tượng là 110 lệnh/giây không bao giờ nghỉ.

DevOps 31/08/2026 8 phút

Ghi 50 MB vào ổ đĩa nhưng snapshot cả cụm Kubernetes chỉ phình thêm 135 KB — vì nó sao lưu bản thiết kế chứ không sao lưu đồ đạc trong nhà

Đo hai nửa của việc sao lưu Kubernetes. Snapshot etcd nhỏ hơn thư mục /var/lib/etcd 14,9 lần và chụp trong 0,1 giây — nhưng ghi 50 MB vào một PersistentVolume chỉ làm nó tăng 0,26%, vì etcd lưu định nghĩa đối tượng chứ không lưu nội dung volume. Và cái bẫy tên gọi: 'kubectl get all' bỏ sót 119 đối tượng, kể cả MỌI Secret. Bản sao lưu đó khôi phục lại một cụm không mật khẩu, không cấu hình, không phân quyền.