Cloud & hạ tầng

Xây dựng API Kubernetes động mà không cần custom controller

Các kỹ sư của Cozystack giải thích cách họ sử dụng lớp tổng hợp API (API aggregation layer) của Kubernetes để tạo ra các endpoint động, mang tính mệnh lệnh và vượt qua những hạn chế về lưu trữ của etcd.

Hình minh họa trừu tượng về các thành phần API module kết nối với lõi Kubernetes trung tâm.
Hình ảnh: Kubernetes Blog, giấy phép CC BY 4.0

Được dịch tự động từ bản gốc tiếng Anh.

Trong một bài đăng trên Kubernetes Blog vào tháng 11 năm 2024, Andrei Kvapil từ Ænix đã trình bày chi tiết cách nhóm của anh xây dựng một máy chủ API mở rộng động cho Cozystack. Bài viết khám phá việc triển khai kỹ thuật của lớp tổng hợp API trong Kubernetes, so sánh nó với Custom Resource Definitions (CRDs) và operators tiêu chuẩn.

Chuyện gì đã xảy ra

Kvapil giải thích rằng mặc dù hầu hết các phần mở rộng của Kubernetes đều dựa vào CRDs và controllers, phương pháp này có những hạn chế đối với một số trường hợp sử dụng cụ thể. Các operator tiêu chuẩn rất giỏi trong việc đối chiếu trạng thái theo kiểu khai báo (declarative state reconciliation), nhưng gặp khó khăn với logic mệnh lệnh (imperative logic), tạo dữ liệu thời gian thực hoặc các yêu cầu xác thực phức tạp. Để giải quyết những khoảng trống này, nhóm Cozystack đã triển khai một máy chủ API mở rộng tùy chỉnh, tích hợp trực tiếp vào khung API của Kubernetes thông qua lớp tổng hợp.

Trọng tâm của việc triển khai này là đăng ký một đối tượng APIService trong cụm. Việc đăng ký này cho phép máy chủ API chính của Kubernetes chuyển tiếp các yêu cầu cho những nhóm tài nguyên cụ thể đến máy chủ mở rộng bên ngoài. Đối với Cozystack, điều này cho phép nền tảng động hiển thị các loại tài nguyên mới dựa trên các Helm chart có sẵn mà không cần thay đổi mã nguồn hay biên dịch lại. Hệ thống ánh xạ các kind dễ hiểu cho người dùng, chẳng hạn như Postgres hoặc Redis, trực tiếp đến các bản phát hành Helm cơ sở, giúp trừu tượng hóa độ phức tạp khỏi người dùng cuối.

Cách tiếp cận này cũng giải quyết được những thách thức đáng kể về RBAC. Kiểm soát truy cập dựa trên vai trò (Role-Based Access Control) tiêu chuẩn của Kubernetes không thể lọc các thao tác danh sách theo nhãn hoặc các trường spec cụ thể, mà chỉ theo tên tài nguyên. Bằng cách tạo ra các kind tài nguyên riêng biệt cho mỗi loại dịch vụ, Cozystack có thể tận dụng các chính sách RBAC gốc để hạn chế quyền truy cập một cách chính xác. Ngoài ra, máy chủ mở rộng xử lý chuyển đổi hai chiều giữa các kind tùy chỉnh mới và các tài nguyên HelmRelease nội bộ, đảm bảo tính tương thích ngược với các dashboard và công cụ hiện có.

Cách hoạt động

Lớp tổng hợp API đóng vai trò như một proxy trong mặt phẳng điều khiển (control plane) của Kubernetes. Khi người dùng gửi yêu cầu đến API Kubernetes cho một nhóm tài nguyên được phục vụ bởi phần mở rộng, máy chủ API chính sẽ chuyển tiếp yêu cầu đó đến máy chủ API mở rộng. Máy chủ này hoạt động độc lập với các thành phần mặt phẳng điều khiển chính và có thể triển khai logic nghiệp vụ, xác thực và cơ chế lưu trữ riêng.

Figure from the original article: Xây dựng API Kubernetes động mà không cần custom controller
Hình từ bài viết gốc · Kubernetes Blog · CC BY 4.0

Khác với các controller tiêu chuẩn đồng bộ trạng thái vào etcd, một máy chủ API mở rộng có thể tạo phản hồi ngay lập tức. Điều này tương tự như cách metrics-server hoạt động, lấy dữ liệu thời gian thực từ Kubelet thay vì lưu trữ chúng. Trong trường hợp của Cozystack, máy chủ động phát hiện các dịch vụ có sẵn và đăng ký chúng dưới dạng tài nguyên API. Nó xác thực đầu vào, chuyển đổi chúng thành các đối tượng HelmRelease và gửi chúng vào cụm, tất cả trong khi duy trì sự tách biệt rõ ràng giữa API hướng tới người dùng và triển khai nội bộ.

Chi tiết quan trọng

  • Lớp tổng hợp API cho phép các máy chủ mở rộng xử lý logic mệnh lệnh và các subresource như /exec hoặc /log.
  • API mở rộng được đăng ký thông qua đối tượng APIService, định hướng lưu lượng truy cập cho các nhóm API cụ thể đến máy chủ bên ngoài.
  • Khác với CRD, các máy chủ mở rộng không cần lưu trữ trạng thái trong etcd, cho phép tạo dữ liệu thời gian thực và giảm tải lưu trữ.
  • Cozystack sử dụng mô hình này để động ánh xạ các kind dịch vụ như Postgres đến các Helm chart cơ sở mà không cần biên dịch lại mã.
  • Việc triển khai hỗ trợ xác thực phía máy chủ phức tạp và định dạng đầu ra bảng tùy chỉnh vượt quá khả năng của CRD.
  • Các máy chủ mở rộng không ổn định có thể chặn việc xóa namespace hoặc gây ra độ trễ API, vì vậy độ tin cậy là yếu tố then chốt.

Tại sao điều này quan trọng

Đối với các kỹ sư nền tảng, việc hiểu lớp tổng hợp mở ra các mẫu thiết kế khó hoặc không thể thực hiện chỉ với CRD. Nó cho phép tạo ra các API hoạt động giống như tài nguyên Kubernetes gốc nhưng vận hành với logic mệnh lệnh hoặc backend bên ngoài. Điều này đặc biệt hữu ích cho việc tích hợp các hệ thống cũ, hiển thị số liệu đo lường thời gian thực hoặc tạo giao diện đơn giản hóa cho các ứng dụng phức tạp.

Tuy nhiên, sức mạnh này đi kèm với rủi ro vận hành. Nếu một máy chủ API mở rộng trở nên không khả dụng, nó có thể làm suy giảm hiệu suất của toàn bộ cụm. Các thao tác như xóa namespace có thể bị treo trong khi chờ phần mở rộng xác nhận dọn dẹp tài nguyên. Các kỹ sư phải cân nhắc lợi ích của hành vi API tùy chỉnh so với độ phức tạp tăng thêm và tác động tiềm tàng đến sự ổn định khi chạy thêm các máy chủ API.

Bạn có thể làm gì

  • Đánh giá xem trường hợp sử dụng của bạn có yêu cầu logic mệnh lệnh hoặc dữ liệu thời gian thực hay không trước khi chọn giữa CRD và API mở rộng.
  • Sử dụng kubectl get apiservices để kiểm tra các lớp tổng hợp hiện đang được đăng ký trong cụm của bạn.
  • Triển khai các kiểm tra sức khỏe (health checks) và timeout mạnh mẽ cho bất kỳ máy chủ API mở rộng nào để ngăn chặn tình trạng chặn toàn cụm.
  • Tận dụng lớp tổng hợp cho các subresource như log hoặc exec proxy nơi các thao tác CRUD tiêu chuẩn không áp dụng được.
  • Cân nhắc sử dụng các máy chủ mở rộng để hiển thị các cơ sở dữ liệu hoặc dịch vụ bên ngoài dưới dạng tài nguyên Kubernetes gốc nhằm quản lý dễ dàng hơn.
  • Kiểm thử kỹ lưỡng các kịch bản thất bại, đặc biệt là xóa namespace và khám phá API, để đảm bảo sự ổn định của cụm.

Công cụ từ cửa hàng Bytechap

Đọc tiếp

Tất cả bài viết