9 điểm bởi outsideris 2022-08-21 | 2 bình luận | Chia sẻ qua WhatsApp

Crossplane do Upbound tạo ra cung cấp cloud control plane trên Kubernetes. Vì vậy, để tương ứng với các tài nguyên đám mây như AWS, Azure, GCP, nó có hàng trăm CRD (Custom Resource Definition). Trong Crossplane, chúng được gọi là MR (Managed Resource).

Ngay cả với người dùng Kubernetes nâng cao, thông thường cũng chỉ vận hành một số lượng CR vừa phải, cỡ vài chục, nhưng với Crossplane thì phải dùng đến hàng trăm MR, nên họ bắt đầu xem xét giới hạn Kubernetes có thể xử lý được bao nhiêu CRD.

Có thể chia vấn đề này thành phía client và phía server.

Vấn đề phía client

  • Ở phía client, vấn đề nằm ở quá trình discovery.
  • Các client như kubectl thực hiện discovery để tìm xem server cung cấp những API nào, và việc này phải duyệt qua toàn bộ các API endpoint một lần.
  • CR được cung cấp dưới dạng API endpoint.
  • Để truy vấn một MR như https://example.org/apis/rds.aws.upbound.io/v1/instances/cool-db, trước hết phải tìm các API group được hỗ trợ tại https://example.org/apis/, sau đó tìm các version được hỗ trợ tại https://example.org/apis/rds.aws.upbound.io, rồi tiếp tục tìm các CR được hỗ trợ tại https://example.org/apis/rds.aws.upbound.io/v1.
  • Các MR của Crossplane dùng để cung cấp cloud provider AWS, Azure, GCP có khoảng 2.000 mục và được chia thành 300 API group và version.
  • Client sẽ gửi 300 HTTP request cho quá trình discovery.
  • Trong điều kiện mạng hiện nay đây không phải vấn đề quá lớn, nhưng vấn đề được phát hiện là rate limit và cache.

Rate limit phía client

  • Có rate limit trung bình 5 request mỗi giây (burst tối đa 100), và cache discovery bị vô hiệu hóa mỗi 10 phút.
  • Có thể giải quyết việc này bằng cách tăng rate limit; hiện vẫn là 5 request mỗi giây mặc định, nhưng đã có thể tăng lên đến 300.
  • Từ kubectl v1.22 đã có issue yêu cầu nâng giới hạn này, và cache discovery cũng được điều chỉnh từ 10 phút lên 5 giờ, nên từ Kubernetes v1.25 có thể tận dụng giới hạn tăng lên ở phía client.

Cache phía client

  • Ngay cả khi tắt rate limit để thử nghiệm, việc truy vấn 300 API group vẫn mất gần 20 giây.
  • Ban đầu tưởng là vấn đề mạng, nhưng sau khi tìm hiểu thì hóa ra vấn đề phát sinh khi truy cập các file cache.
  • Đã được sửa trong Kubernetes 1.25, giúp nhanh hơn 25 lần trên macOS và nhanh gấp 2 lần trên Linux.

Cải tiến client trong tương lai

  • Việc áp rate limit ở phía client là hợp lý, nhưng thực tế không bảo vệ server một cách đầy đủ.
  • API Priority and Fairness (AP&F), được giới thiệu trong Kubernetes 1.20, cung cấp queue và traffic shaping ở phía server để bảo vệ API server.
  • Một HTTP endpoint tổng hợp cho discovery đã được KEP phê duyệt và dự kiến sẽ được hỗ trợ ở mức alpha trong 1.26.

Vấn đề phía server

Tính toán schema OpenAPI

  • Sau khi đăng ký hàng trăm CRD, họ phát hiện hiện tượng các API request bị chậm trong gần một giờ.
  • Qua profiling, họ xác định nguyên nhân là logic tính toán schema OpenAPI v2.
  • Khi thêm hoặc cập nhật CRD, OpenAPI controller sẽ build swagger spec của CR, gộp với swagger của tất cả CR khác thành một spec lớn, rồi serialize sang JSON để cung cấp tại /openapi/v2.
  • Họ đã sửa để /openapi/v2 được tính toán lazy, chỉ tính khi thực sự có request đến endpoint liên quan.
  • Bản sửa này đã vào v1.24.0 và được backport sang 1.20.13, 1.21.7, 1.22.4.

Etcd client

  • Đây là điểm nghẽn mới được phát hiện sau khi giải quyết vấn đề OpenAPI.
  • Họ nhận ra API server sử dụng 4MiB bộ nhớ cho mỗi CRD.
  • Điều này càng là vấn đề lớn hơn trên các Kubernetes managed như GKE, EKS vì CPU và bộ nhớ của API server bị giới hạn. Nếu cần thêm tài nguyên thì API server sẽ tự mở rộng, nhưng đáng tiếc là việc thêm CRD không phải yếu tố dùng để quyết định mở rộng. Vì vậy, trừ khi API server liên tục bị OOM killed, nó sẽ không mở rộng.
  • Khi thử nghiệm trên GKE, AKE, EKS, cơ chế tự phục hồi vẫn hoạt động nhưng API server có thể không dùng được từ 5 giây đến 1 giờ. Cluster không dừng hoàn toàn, nhưng mọi reconciliation đều dừng lại.
  • Qua profiling, họ phát hiện thư viện logging Zap chiếm 20% bộ nhớ.
  • API server tạo một etcd client cho mỗi version của CR, và mỗi etcd client lại tạo một logger Zap.
  • Kết quả là không chỉ bộ nhớ tăng lên do các logger trùng lặp, mà còn phát sinh các TCP connection không cần thiết giữa API server và etcd.
  • Các maintainer cũng đồng ý rằng nên dùng một etcd client cho mọi CR endpoint, nhưng vì bản phát hành Kubernetes 1.25 đã cận kề nên khó sửa toàn bộ, do đó họ thực hiện một thay đổi nhỏ hơn để mọi etcd client cùng chia sẻ một logger.
  • Điều này dự kiến sẽ được đưa vào 1.25 và sẽ được backport sang 1.22, 1.23, 1.24. Nó sẽ giảm 20% mức sử dụng bộ nhớ.

Cải tiến server trong tương lai

  • Họ dự định thay đổi từ việc tạo etcd client cho mỗi version của CR sang tạo một client cho mỗi transport (mỗi etcd cluster).
  • Họ cũng đang phối hợp với các nhóm kỹ sư của GKE, EKS, AKE để xử lý việc cài đặt số lượng lớn crossplane CRD.

2 bình luận

 
roxie 2022-08-21

Miễn phí hóa -> vô hiệu hóa

 
roxie 2022-08-21

cliaing-eonteu -> client