How we built a dynamic Kubernetes API Server for the API Aggregation Layer in Cozystack
Bài tóm tắt Kubernetes 2024 3. Quy mô lớn Độ khó: Khó
Kubernetes · 2024 · 3. Quy mô lớn · Độ khó: Khó — bài gốc
Bài khách trên blog Kubernetes, do tác giả của Cozystack (PaaS mã nguồn mở, Andrei Kvapil) viết; "chúng tôi" là team Cozystack. Company ghi Kubernetes theo sheet.
Bối cảnh
- Mở rộng Kubernetes thường bằng CRD + controller (kubebuilder, operator-sdk): khai báo resource, controller reconcile. Cách khác là API aggregation layer: viết một extension API server chạy riêng, đăng ký bằng
APIService; API server chính chuyển mọi request của một API group sang nó. - Hợp khi cần: subresource mệnh lệnh (
/exec,/log; KubeVirt có/console,/vnc); không lưu ở etcd (metrics-server lấy số liệu từ kubelet lúc gọi); resource chỉ tạo được một lần rồi trả kết quả (SelfSubjectAccessReview, token upload của KubeVirt CDI); tự làm validation, chuyển đổi version, định dạng bảng; đăng ký kiểu resource động lúc chạy. - Không nên dùng khi backend không ổn định hay request chậm: API server phụ chết có thể chặn xoá namespace (Kubernetes chờ xem còn resource nào), hoặc làm mọi lệnh
kubectlin cảnh báometrics.k8s.iokhông có.
Bài toán của Cozystack
- Mọi ứng dụng trên Cozystack là một Helm chart, triển khai bằng resource HelmRelease của FluxCD trong namespace của tenant.
- Giới hạn RBAC: không lọc được quyền
listtrên cùng một kind theo label hay theo trường;resourceNameschỉ có tác dụng vớiget/update. Không thể cho user chỉ thấy HelmRelease của chart Postgres. - Cần API công khai: không thể để user tạo HelmRelease trực tiếp vì họ chỉ định được chart và tham số tuỳ ý.
Thay đổi chính
- Viết extension API server từ
sample-apiserver(bỏapiserver-buildervì đã alpha và hai năm không cập nhật), tắt etcd. - Một kiểu chung
Application, nhưng đăng ký vào scheme dưới nhiềuKindtheo tên chart, đọc từ file cấu hình/ConfigMap:kind: Postgres → chart: postgres,Kafka,Redis,VirtualMachine... Thêm chart mới không cần codegen hay biên dịch lại. - Registry riêng chuyển đổi hai chiều Application ↔ HelmRelease, lọc theo tên chart,
sourceRef, tiền tố tên; càiGet/List/Create/Delete, trảunstructuredđể giữ đúngKind. - Kết quả: hơn 20 kiểu (
buckets,postgreses,kafkas,kuberneteses,virtualmachines...) dùng như resource thường bằngkubectl, phân quyền bằng RBAC chuẩn theo từng kind. - Không có controller đồng bộ giữa hai loại resource: mọi request được proxy trong suốt sang HelmRelease và ngược lại, nên không có trạng thái trung gian; dashboard và tích hợp cũ dùng HelmRelease vẫn chạy.
Bài học cho SWE
- Một mặt tiền API dịch sang resource nội bộ cho phép đổi phân quyền và giới hạn những gì user được làm mà không đổi bên dưới (Nền tảng nội bộ cho service (đường ray chung)).
- Khi không cần lưu bản sao, proxy hai chiều tránh được cả một lớp đồng bộ và lệch trạng thái; đổi lại API phụ trở thành phụ thuộc trên đường đi của các thao tác lõi, nên phải nhanh và ổn định.
- So với vòng reconcile ở PlanetScale 2026: CRD + controller lưu trạng thái và hội tụ dần; extension API server trả lời ngay từ nguồn khác.
Liên quan
#Kubernetes#API Aggregation Layer#Extension API server#CRD#Controller#RBAC#HelmRelease#FluxCD#PaaS#Public API#Cozystack
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (1)