Blog
Thoughts on engineering, design, and building great products.
Operator: CRD Cộng Vòng Lặp Reconcile
CRD cho ta một kiểu dữ liệu mới, nhưng tạo một custom resource thì chưa có gì xảy ra. Operator ghép CRD với một controller chạy vòng lặp: theo dõi custom resource và hành động để đưa thực tế về khớp mong muốn. Bài này dựng một operator thật từ đầu — một CRD Echo và một controller chạy trong pod — rồi xem nó tự tạo Deployment khi ta tạo Echo, tự scale khi ta sửa replicas, và để Deployment bị dọn khi ta xóa Echo.
Admission Webhook: Chen Vào Đường Ghi
Bài 54 dùng admission có sẵn (Pod Security). Bài này tự viết một admission của riêng mình: một dịch vụ HTTPS mà API server gọi tới trước khi lưu mỗi object, trả về cho hay không cho. Ta dựng một validating webhook thật bằng Python — tự ký cert cho service, để API server tin qua caBundle, và bắt mọi pod phải có label team. Pod thiếu label bị API server từ chối ngay; pod ở namespace ngoài phạm vi thì không bị đụng.
CustomResourceDefinition: Thêm Kiểu Của Riêng Bạn
Part XII chuyển từ dùng Kubernetes sang mở rộng nó. Bài đầu là CustomResourceDefinition — khai một kiểu object mới, và API server lập tức phục vụ nó như resource gốc: kubectl get được, validate theo schema, lưu trong etcd. Ta dựng một CRD Widget có ràng buộc kiểu và miền giá trị, tạo custom resource hợp lệ, xem hai cái sai bị từ chối, rồi cập nhật status qua subresource riêng.
Secret, Lối Vòng và Hardening
Part XI khép lại ở Secret và những lỗ hổng còn sót. Ta đọc thẳng etcd để xác nhận Secret được mã hóa at-rest từ Bài 5, rồi dựng một lối vòng thật: một ServiceAccount không có quyền đọc Secret vẫn moi được giá trị bằng cách tạo một pod mount Secret đó và đọc log. Cuối bài là bảng các bước siết cụm tự dựng — cái nào đã làm trong series, cái nào còn thiếu.
Seccomp, AppArmor và Capabilities
Bài 54 bắt pod khai runAsNonRoot, drop ALL capabilities, seccomp RuntimeDefault — nhưng đó mới là chính sách ở mức Kubernetes. Bài này xuống tầng kernel xem chúng làm gì thật: đọc /proc/self/status của hai pod, một mặc định một đã siết, so từng dòng CapEff, Seccomp, NoNewPrivs, AppArmor. Rồi chứng minh bằng tay rằng drop một capability chặn được thao tác cụ thể — chown bị từ chối ngay cả khi container vẫn chạy bằng root.
Pod Security Standards và Admission
RBAC quyết ai được tạo pod, nhưng không xét pod đó xin gì. Một pod chạy privileged hay mượn hostNetwork là cửa thoát ra node. Pod Security Admission chặn ngay từ lúc tạo: gắn một nhãn lên namespace, API server đo pod theo ba mức privileged/baseline/restricted và từ chối pod vi phạm. Bài này bật restricted lên một namespace, xem pod thường bị đá ra với danh sách lỗi, viết một pod tuân thủ cho chạy được, rồi thử chế độ warn chỉ cảnh báo.
ServiceAccount và Bound Token
Bài 51–52 dùng ServiceAccount mà chưa mổ nó. Bài này đi vào cơ chế: mỗi namespace có một SA default, kubelet tự tiêm vào pod một token ngắn hạn qua projected volume, và token đó bound vào đúng pod lẫn node. Để chứng minh là bound thật, ta lấy token trong một pod đang chạy, gọi API thành công, rồi xóa pod — token cũ lập tức thành 401. Kèm cách tắt auto-mount và đọc các claim trong JWT.