Cloud & hạ tầng

Giới hạn tài nguyên trong Kubernetes: Cân bằng giữa tính dự đoán và hiệu quả

Một phân tích năm 2023 lập luận rằng việc thiết lập giới hạn CPU và bộ nhớ trong Kubernetes giúp cải thiện tính dự đoán của hiệu suất, ngay cả khi điều đó làm giảm hiệu quả tổng thể của cụm.

Một chiếc cân thăng bằng giữa một con chip vi xử lý và một chiếc đồng hồ trên giá đỡ máy chủ.
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 Blog Kubernetes vào tháng 11 năm 2023, Milan Plžík từ Grafana Labs đã trình bày một lập luận chi tiết về việc sử dụng các giới hạn tài nguyên trong điều phối container. Trong khi nhiều kỹ sư ủng hộ việc loại bỏ giới hạn CPU để tăng tốc độ, quan điểm này nhấn mạnh cách các giới hạn cung cấp sự ổn định và khả năng dự đoán cần thiết cho các hệ thống sản xuất.

Điều gì đã xảy ra

Cộng đồng kỹ thuật đã chứng kiến sự gia tăng các lời khuyên cho rằng người dùng Kubernetes nên ngừng đặt giới hạn CPU cho các pod của họ. Những người ủng hộ quan điểm này lập luận rằng các giới hạn kìm hãm hiệu suất một cách nhân tạo và lãng phí sức mạnh tính toán đã trả tiền mà lẽ ra có thể được tận dụng trong các khoảng thời gian nhàn rỗi. Các bài viết như "Vì Chúa, hãy ngừng sử dụng Giới hạn CPU trên Kubernetes" đã phổ biến ý tưởng rằng việc loại bỏ những ràng buộc này cho phép các dịch vụ chạy nhanh hơn bằng cách mượn các chu kỳ không sử dụng từ các khối lượng công việc lân cận.

Plžík, một Kỹ sư Độ tin cậy Trang web (Site Reliability Engineer) tại Grafana Labs, đã thách thức quan điểm thịnh hành này bằng cách tập trung vào các rủi ro vận hành của việc tiêu thụ tài nguyên không giới hạn. Ông lưu ý rằng mặc dù việc loại bỏ các giới hạn có thể cải thiện các chỉ số hiệu suất tức thì, nhưng nó lại gây ra sự khó lường đáng kể. Khi các pod cạnh tranh tài nguyên nút chia sẻ mà không có ranh giới xác định, hành vi của chúng trở nên phụ thuộc rất nhiều vào sự kết hợp cụ thể của các ứng dụng khác đang chạy trên cùng một máy. Sự biến động này khiến việc đảm bảo mức độ dịch vụ nhất quán trở nên khó khăn, đặc biệt là trong các đợt tăng đột biến lưu lượng truy cập hoặc thay đổi cơ sở hạ tầng.

Lõi của lập luận là chi phí ẩn của tài nguyên bổ sung là sự thiếu hụt khả năng quan sát và kiểm soát. Nếu không có các giới hạn, gần như không thể xác định chính xác dung lượng mà một pod có sẵn tại bất kỳ thời điểm nào. Sự không chắc chắn này làm phức tạp hóa việc lập kế hoạch dung lượng cho các sự kiện có lưu lượng truy cập cao như Black Friday, nơi dữ liệu lịch sử có thể không phản ánh các ràng buộc trong tương lai nếu cách đóng gói bin-packing của các pod thay đổi. Do đó, những gì trông giống như sử dụng tài nguyên hiệu quả có thể nhanh chóng biến thành các lỗi dây chuyền khi dung lượng dự phòng biến mất.

Cách hoạt động

Kubernetes quản lý tài nguyên thông qua các yêu cầu (requests) và giới hạn (limits). Một yêu cầu chỉ định số lượng tối thiểu CPU hoặc bộ nhớ mà một pod cần để chạy, trong khi một giới hạn xác định số lượng tối đa mà nó có thể sử dụng. Khi các giới hạn bị loại bỏ hoặc được đặt ở mức rất cao, các pod hoạt động ở chế độ nỗ lực tốt nhất (best-effort) liên quan đến các ngưỡng trên. Chúng có thể tiêu thụ bất kỳ tài nguyên miễn phí nào trên nút, nhưng điều này tạo ra kịch bản "bông tuyết đặc biệt" (special snowflake), nơi hiệu suất của mỗi pod phụ thuộc hoàn toàn vào tải hiện tại của các pod lân cận.

Hình từ bài viết gốc: Kubernetes resource limits: balancing predictability and efficiency
Hình từ bài viết gốc · Kubernetes Blog · CC BY 4.0

Nếu một pod vượt quá tài nguyên vật lý của nút chứa nó, nó sẽ đối mặt với tình trạng throttling (giảm tốc) hoặc bị giết do hết bộ nhớ (OOM kills), tương tự như khi chạm tới một giới hạn đã cấu hình. Tuy nhiên, nếu không có các giới hạn rõ ràng, những sự kiện này khó dự đoán và gỡ lỗi hơn. Hệ thống thiếu các tín hiệu rõ ràng về thời điểm một khối lượng công việc đang tiến gần đến điểm gãy vì nó liên tục hấp thụ các lượng dung lượng dự phòng biến đổi. Điều này khiến việc lập hồ sơ và tinh chỉnh hiệu suất trở nên khó khăn, vì các mẫu dữ liệu có thể không nắm bắt được những đợt tăng đột biến hiếm gặp nhưng quan trọng trong việc sử dụng tài nguyên.

Để khôi phục tính dự đoán, Plžík đề xuất hai chiến lược cấu hình chính. Chiến lược đầu tiên là "dự phòng theo tỷ lệ cố định" (fixed-fraction headroom), trong đó các giới hạn được đặt ở mức cao hơn một chút so với các yêu cầu. Điều này cho phép một số khả năng bùng nổ (burstability) trong khi vẫn giới hạn tỷ lệ overcommit trên mỗi nút. Chiến lược thứ hai là đặt yêu cầu bằng với giới hạn. Điều này đưa pod vào lớp Chất lượng Dịch vụ Được Đảm bảo (Guaranteed Quality of Service - QoS), đảm bảo nó nhận được tài nguyên chuyên dụng và chỉ bị trục xuất sau các pod có ưu tiên thấp hơn. Cả hai phương pháp đều hy sinh một phần hiệu quả tiềm năng để đạt được các đặc tính hiệu suất ổn định và có thể tái tạo.

Chi tiết chính

  • Các pod không có giới hạn tiêu thụ tài nguyên nút bổ sung, khiến hiệu suất của chúng phụ thuộc vào tải không thể dự đoán của các pod lân cận.
  • Khả năng quan sát bị ảnh hưởng vì rất khó để theo dõi chính xác lượng dung lượng dự phòng mà một pod đã sử dụng tại bất kỳ thời điểm cụ thể nào mà không cần khai thác dữ liệu sâu rộng.
  • Dữ liệu hiệu suất lịch sử từ các pod không giới hạn có thể gây hiểu lầm cho việc lập kế hoạch dung lượng nếu cách đóng gói bin-packing của cụm thay đổi trong các sự kiện có lưu lượng truy cập cao.
  • Việc đặt yêu cầu bằng với giới hạn gán lớp QoS Guaranteed, bảo vệ các pod khỏi bị trục xuất cho đến khi các pod BestEffort và Burstable bị loại bỏ.
  • Dự phòng theo tỷ lệ cố định cho phép bùng nổ có giới hạn trong khi giữ mức overcommit trên mỗi nút trong một phạm vi đã biết, giảm bớt sự biến động hiệu suất.
  • Việc loại bỏ các giới hạn triệt tiêu động lực để các nhóm sản phẩm tối ưu hóa mã của họ, vì họ dựa vào tài nguyên dự phòng miễn phí thay vì thiết kế hiệu quả.

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

Đối với các kỹ sư phần mềm và nhóm nền tảng, quyết định sử dụng các giới hạn là sự đánh đổi giữa hiệu quả thô và độ tin cậy vận hành. Mặc dù việc loại bỏ các giới hạn có thể vắt kiệt thêm giá trị từ phần cứng bằng cách tận dụng các chu kỳ nhàn rỗi, nhưng nó chuyển giao rủi ro về sự cạnh tranh tài nguyên sang tầng ứng dụng. Điều này có thể dẫn đến các đợt tăng đột biến độ trễ bất ngờ hoặc các lần giết OOM khi cụm chịu áp lực, đòi hỏi phải tăng dung lượng khẩn cấp và phản ứng. Ngược lại, việc thiết lập các giới hạn cung cấp một lưới an toàn buộc các khối lượng công việc phải hoạt động trong các tham số đã biết, giúp việc chẩn đoán và ngăn ngừa sự cố dễ dàng hơn.

Cách tiếp cận này cũng tác động đến mô hình kinh tế của cơ sở hạ tầng đám mây. Khi các nhóm có quyền truy cập vào tài nguyên dự phòng không giới hạn, họ có thể bỏ bê các nỗ lực tối ưu hóa, dẫn đến các dịch vụ phình to hoạt động kém trong các điều kiện bị ràng buộc. Bằng cách thực thi các giới hạn, các tổ chức khuyến khích các nhà phát triển kích thước đúng (right-size) ứng dụng của họ và xử lý sự khan hiếm tài nguyên một cách khéo léo. Kỷ luật này giúp duy trì các thỏa thuận mức độ dịch vụ (SLA) và đảm bảo rằng hiệu suất vẫn nhất quán bất kể trạng thái cụm xung quanh.

Hơn nữa, việc sử dụng tài nguyên dự đoán đơn giản hóa công việc của các kỹ sư độ tin cậy trang web. Thay vì gỡ lỗi các tương tác phức tạp giữa các pod cạnh tranh, họ có thể dựa vào các ranh giới được xác định để cô lập các vấn đề. Sự rõ ràng này rất quan trọng trong các đợt nâng cấp lớn hoặc sự kiện mở rộng quy mô, nơi sự cạnh tranh tài nguyên bất ngờ có thể gây ra gián đoạn diện rộng. Cuối cùng, mục tiêu không chỉ là tiết kiệm chi phí tính toán, mà còn xây dựng một hệ thống bền vững hoạt động nhất quán dưới áp lực.

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

  • Kiểm toán các khối lượng công việc Kubernetes hiện tại của bạn để xác định các pod chạy mà không có giới hạn CPU hoặc bộ nhớ.
  • Triển khai dự phòng theo tỷ lệ cố định bằng cách đặt các giới hạn cao hơn một chút so với các yêu cầu cho các dịch vụ cần khả năng bùng nổ thỉnh thoảng.
  • Cấu hình các dịch vụ quan trọng, nhạy cảm với độ trễ với yêu cầu bằng giới hạn để đảm bảo QoS Guaranteed và ưu tiên khi chịu áp lực tài nguyên.
  • Xem xét dữ liệu giám sát lịch sử để phát hiện xem các cải thiện hiệu suất là do tối ưu hóa thực sự hay chỉ đơn thuần là do truy cập vào tài nguyên nút dự phòng.
  • Thiết lập các hướng dẫn cho các nhóm sản phẩm để kích thước đúng các yêu cầu tài nguyên dựa trên các mẫu sử dụng thực tế thay vì các giả định trường hợp xấu nhất.
  • Sử dụng các công cụ tự động như Karpenter hoặc node auto-provisioning để cải thiện hiệu quả đóng gói bin-packing khi sử dụng các cấu hình request-limit nghiêm ngặt.

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

Đọc tiếp

Tất cả bài viết