Ba điểm nghẽn riêng biệt hạn chế khả năng mở rộng của điều khiển Kubernetes
Các cụm Kubernetes thất bại khi mở rộng quy mô do sự biến động của node, trạng thái đối tượng hoặc cường độ ghi, chứ không chỉ dựa vào số lượng node. Các điểm kết nối kiến trúc mới cung cấp giải pháp nhắm mục tiêu cho từng điểm nghẽn.
Được dịch tự động từ bản gốc tiếng Anh.
Những thách thức về khả năng mở rộng của Kubernetes thường bị chẩn đoán sai là giới hạn đơn giản về số lượng node, nhưng các phân tích gần đây cho thấy ba chế độ lỗi riêng biệt: biến động (churn), trạng thái (state) và dung lượng node. Khi các cụm phát triển vượt quá năm nghìn node hoặc xử lý khối lượng công việc agent nặng nề, việc mở rộng ngang theo tiêu chuẩn của máy chủ API có thể làm trầm trọng thêm áp lực bộ nhớ thay vì giảm tải. Việc hiểu rõ những điểm nghẽn cụ thể này cho phép các nhóm hạ tầng áp dụng các biện pháp sửa đổi kiến trúc nhắm mục tiêu bằng cách sử dụng các thành phần upstream tiêu chuẩn.
Chuyện gì đã xảy ra
Nhiều nhóm kỹ thuật giả định rằng việc mở rộng điều khiển Kubernetes là một bài toán tuyến tính được giải quyết bằng cách thêm nhiều máy chủ API. Tuy nhiên, các cụm thực tế trong môi trường sản xuất chứng minh rằng phương pháp này thường thất bại khi nút thắt cổ chai cơ bản không phải là khối lượng yêu cầu mà là thời gian lưu trú trong bộ nhớ hoặc cường độ ghi. Ví dụ, một hạm đội huấn luyện có thể ổn định ở vài nghìn node trước khi nhảy lên mười lăm nghìn, gây ra cảnh báo từ etcd và cạn kiệt bộ nhớ máy chủ API. Ngược lại, một nền tảng agent với chỉ vài nghìn node có thể chịu đựng hàng nghìn lần chuyển đổi đối tượng mỗi phút, tạo ra một cơn bão ghi làm quá tải điều khiển bất kể số lượng node.
Kịch bản thứ ba liên quan đến các cụm nền tảng với hàng trăm operator và hàng chục nghìn đối tượng tĩnh. Ở đây, vấn đề không nằm ở hoạt động mà là trạng thái: mỗi máy chủ API giữ một bản sao của tất cả các đối tượng trong bộ nhớ đệm watch cache của nó. Thêm nhiều máy chủ API trong bối cảnh này sẽ nhân bản toàn bộ bộ nhớ đệm, làm tăng mức sử dụng bộ nhớ mà không cải thiện hiệu suất. Ba kịch bản này—giới hạn bởi node, giới hạn bởi biến động và giới hạn bởi trạng thái—đòi hỏi các giải pháp khác nhau, nhưng hầu hết hướng dẫn công khai chỉ tập trung độc quyền vào số lượng node lên đến năm nghìn.
Việc thiếu các chiến lược được tài liệu hóa cho các cụm lớn hơn hoặc phức tạp hơn khiến các nhóm đưa ra những thay đổi phản tác dụng. Việc thêm máy chủ API vào một cụm bị giới hạn bởi trạng thái làm tăng áp lực bộ nhớ vì mỗi instance mới nhân bản toàn bộ bộ nhớ đệm watch cache. Giải pháp không nằm ở các fork tùy chỉnh mà ở việc hiểu rõ các "điểm kết nối" (seams) của kiến trúc Kubernetes, nơi các thành phần có thể được tách rời và cấu hình độc lập để xử lý các loại tải cụ thể.
Cơ chế hoạt động
Khả năng mở rộng của Kubernetes bị ràng buộc bởi bốn "điểm kết nối" kiến trúc, là các điểm thay thế giữa các thành phần. Điểm kết nối đầu tiên là lưu trữ, xác định backend nào giữ loại tài nguyên nào. Không phải tất cả dữ liệu đều đòi hỏi cùng mức độ bền vững; các mục tạm thời như lease của node và sự kiện có thể được định tuyến ra khỏi cụm etcd chính để giảm tải ghi. Điểm kết nối thứ hai là tình trạng sống của node (node liveness), xử lý cách dữ liệu heartbeat truyền đến điều khiển. Bằng cách hấp thụ các gia hạn lease trong một lớp tiếp cận node hoặc sử dụng làm mới lease trong bộ nhớ tại etcd, các cụm có thể giảm đáng kể QPS ghi được tạo ra bởi hàng nghìn kubelet.
Điểm kết nối thứ ba là phân mảnh (sharding), xác định cách các đối tượng được chia nhỏ giữa các controller và bộ nhớ đệm. Nếu các lớp không thống nhất trên trục phân mảnh, các controller sẽ lãng phí tài nguyên khi cố gắng truy cập các đối tượng ngoài phạm vi của chúng. Điểm kết nối thứ tư là thời gian lưu trú trong bộ nhớ đệm (cache residency), kiểm soát những gì máy chủ API giữ trong bộ nhớ. Một cụm bị giới hạn bởi trạng thái gặp khó khăn vì mỗi máy chủ API lưu trữ mọi đối tượng. Bằng cách hạn chế nội dung bộ nhớ đệm chỉ bao gồm các đối tượng liên quan đến một phân đoạn hoặc vai trò cụ thể, mức sử dụng bộ nhớ có thể được cắt giảm đáng kể, mặc dù một số chi phí cơ bản cho các đối tượng RBAC vẫn không thể tránh khỏi.
Chi tiết chính
- Các cụm bị giới hạn bởi node bị hạn chế bởi heartbeat của kubelet, với các gia hạn lease chiếm khoảng 70% QPS ghi ở quy mô lớn.
- Các cụm bị giới hạn bởi biến động đối mặt với tốc độ ghi cao từ các tài nguyên tùy chỉnh tồn tại ngắn hạn, chẳng hạn như phiên agent, độc lập với số lượng node.
- Các cụm bị giới hạn bởi trạng thái bị ràng buộc bởi mức sử dụng bộ nhớ, vì mỗi máy chủ API nhân bản toàn bộ bộ nhớ đệm watch cache chứa hàng chục nghìn đối tượng.
- KEP-4743 xác định ranh giới giao diện lưu trữ, cho phép định tuyến các loại tài nguyên sang các backend khác nhau thông qua
--etcd-servers-overrides. - KEP-5866 giới thiệu bộ lọc phạm vi hash cho lưu lượng API, đặt nền móng cho việc phân mảnh nhất quán giữa các controller và bộ nhớ đệm.
- Cấu hình Tách Vai trò (Role-Split) tách biệt các pool máy cho việc phục vụ API, lập lịch và etcd, cho phép mở rộng lên đến 20.000 node.
Tại sao điều này quan trọng
Đối với các kỹ sư phần mềm và trưởng nhóm hạ tầng, việc nhận biết loại giới hạn quy mô cụ thể là rất quan trọng để tránh các cấu hình sai tốn kém. Đối xử với một nền tảng agent bị giới hạn bởi biến động như một vấn đề giới hạn bởi node dẫn đến việc cấp quá mức tài nguyên tính toán trong khi bỏ qua nút thắt cổ chai ghi trong etcd. Tương tự, việc thêm máy chủ API vào một cụm nền tảng bị giới hạn bởi trạng thái làm tăng chi phí bộ nhớ mà không cải thiện độ trễ. Bằng cách xác định xem cụm bị giới hạn bởi heartbeat của node, biến động đối tượng hay lưu trú trạng thái, các nhóm có thể áp dụng các biện pháp sửa chữa chính xác thay vì mở rộng quy mô thô bạo.
Những hiểu biết này cũng nhấn mạnh tầm quan trọng của việc sử dụng các thành phần upstream tiêu chuẩn với cấu hình có chủ đích thay vì dựa vào các fork không được tài liệu hóa. "Thang công thức" (recipe ladder) được đề xuất cung cấp một lộ trình từ các thiết lập sẵn sàng cao (high-availability) cổ điển đến các kho lưu trữ phân vùng và lát cắt phân mảnh, tất cả đều được thử nghiệm với tích hợp liên tục (CI). Cách tiếp cận này đảm bảo rằng các chiến lược mở rộng quy mô vẫn hợp lệ qua các phiên bản Kubernetes, vì các lỗi cấu hình được phát hiện sớm trong pipeline CI thay vì trong môi trường sản xuất.
Bạn có thể làm gì
- Xác định điểm nghẽn chính của cụm bằng cách phân tích các nguồn QPS ghi, phân biệt giữa lease của node, biến động tài nguyên tùy chỉnh và trạng thái đối tượng tĩnh.
- Triển khai cấu hình tách vai trò để tách biệt việc phục vụ API, lập lịch và etcd sang các pool máy chuyên dụng cho các cụm lên đến 20.000 node.
- Sử dụng
--etcd-servers-overridesđể định tuyến các tài nguyên tạm thời như sự kiện và lease sang các backend riêng biệt, giảm tải cho cụm etcd chính. - Đánh giá các lớp tiếp cận node để hấp thụ các gia hạn lease và chỉ lan truyền các chuyển đổi trạng thái thực sự, giảm gánh nặng ghi cho điều khiển.
- Đóng góp dữ liệu tốc độ ghi thực tế từ các cụm bị giới hạn bởi biến động cho SIG API Machinery để giúp định hình hỗ trợ tương lai cho cấu hình lưu trữ theo CRD.
- Xem xét các nhánh prototype cho KEP-5866 và các phần mở rộng lưu trú bộ nhớ đệm để chuẩn bị cho các tính năng tối ưu hóa bộ nhớ và phân mảnh sắp tới.



