Làm cách nào để tiết kiệm chi phí đám mây khi làm việc với Kubernetes? Không có giải pháp phù hợp duy nhất nhưng bài viết này mô tả một số công cụ có thể giúp bạn quản lý tài nguyên hiệu quả hơn và giảm chi phí điện toán đám mây.
Tôi đã viết bài viết này với ý tưởng về Kubernetes cho AWS, nhưng nó sẽ áp dụng (gần như) theo cách tương tự cho các nhà cung cấp đám mây khác. Tôi giả sử (các) cụm của bạn đã được định cấu hình tự động định tỷ lệ (bộ chia tỷ lệ tự động theo cụm). Loại bỏ tài nguyên và giảm quy mô triển khai sẽ chỉ giúp bạn tiết kiệm tiền nếu điều đó cũng làm giảm nhóm nút công nhân (phiên bản EC2).
Làm việc trong một môi trường có nhịp độ nhanh là điều tuyệt vời. Chúng tôi muốn các tổ chức công nghệ tăng tốc. Phân phối phần mềm nhanh hơn cũng có nghĩa là triển khai PR, môi trường xem trước, nguyên mẫu và giải pháp phân tích nhiều hơn. Mọi thứ đều được triển khai trên Kubernetes. Ai có thời gian để dọn dẹp quá trình triển khai thử nghiệm theo cách thủ công? Thật dễ dàng để quên việc xóa một thử nghiệm cách đây một tuần. Hóa đơn trên đám mây cuối cùng sẽ tăng do chúng ta quên đóng một số thứ:
(Henning Jacobs:
Ziza:
(trích dẫn) Corey Quinn:
Chuyện lầm tưởng: Tài khoản AWS của bạn phụ thuộc vào số lượng người dùng mà bạn có.
Sự thật: Điểm AWS của bạn phụ thuộc vào số lượng kỹ sư mà bạn có.
Ivan Kurnosov (trả lời):
Sự thật: Điểm AWS của bạn là hàm số của số thứ bạn quên tắt/xóa.)
Người gác cổng Kubernetes (kube-janitor) giúp dọn dẹp cụm của bạn. Cấu hình người gác cổng linh hoạt cho cả mục đích sử dụng toàn cầu và cục bộ:
Các quy tắc trên toàn cụm có thể xác định thời gian tồn tại tối đa (TTL) cho việc triển khai PR/thử nghiệm.
Các tài nguyên riêng lẻ có thể được chú thích bằng janitor/ttl, chẳng hạn như để tự động xóa phần tăng đột biến/nguyên mẫu sau 7 ngày.
Các quy tắc chung được xác định trong tệp YAML. Đường dẫn của nó được truyền qua tham số --rules-file trong kube-janitor. Đây là một quy tắc mẫu để xóa tất cả các không gian tên có -pr- trong tên sau hai ngày:
Ví dụ sau đây quy định việc sử dụng nhãn ứng dụng trên nhóm Triển khai và StatefulSet cho tất cả các Deployments/StatefulSets mới vào năm 2020, nhưng đồng thời cho phép thực hiện các thử nghiệm mà không có nhãn này trong một tuần:
- id: require-application-label
# удалить deployments и statefulsets без метки "application"
resources:
- deployments
- statefulsets
# см. http://jmespath.org/specification.html
jmespath: "!(spec.template.metadata.labels.application) && metadata.creationTimestamp > '2020-01-01'"
ttl: 7d
Chạy bản demo có giới hạn thời gian trong 30 phút trên cụm chạy kube-janitor:
kubectl run nginx-demo --image=nginx
kubectl annotate deploy nginx-demo janitor/ttl=30m
Một nguyên nhân khác làm tăng chi phí là khối lượng cố định (AWS EBS). Việc xóa Kubernetes StatefulSet sẽ không xóa các khối liên tục của nó (PVC - PersistentVolumeClaim). Khối lượng EBS không được sử dụng có thể dễ dàng dẫn đến chi phí hàng trăm đô la mỗi tháng. Kubernetes Janitor có tính năng dọn dẹp các PVC không sử dụng. Ví dụ: quy tắc này sẽ xóa tất cả các PVC không được mô-đun gắn kết và không được StatefulSet hoặc CronJob tham chiếu:
# удалить все PVC, которые не смонтированы и на которые не ссылаются StatefulSets
- id: remove-unused-pvcs
resources:
- persistentvolumeclaims
jmespath: "_context.pvc_is_not_mounted && _context.pvc_is_not_referenced"
ttl: 24h
Kubernetes Janitor có thể giúp bạn giữ cho cụm của mình luôn sạch sẽ và ngăn chi phí điện toán đám mây từ từ tăng lên. Để biết hướng dẫn triển khai và cấu hình, hãy làm theo README kube-người gác cổng.
Giảm tỷ lệ mở rộng trong giờ không làm việc
Hệ thống kiểm tra và dàn dựng thường chỉ được yêu cầu hoạt động trong giờ làm việc. Một số ứng dụng sản xuất, chẳng hạn như các công cụ văn phòng/quản trị viên, cũng chỉ yêu cầu tính khả dụng hạn chế và có thể bị vô hiệu hóa chỉ sau một đêm.
Công cụ hạ thấp Kubernetes (kube-downscaler) cho phép người dùng và người vận hành thu nhỏ hệ thống trong thời gian không làm việc. Triển khai và StatefulSets có thể mở rộng quy mô thành XNUMX bản sao. CronJobs có thể bị đình chỉ. Kubernetes Downscaler được định cấu hình cho toàn bộ cụm, một hoặc nhiều không gian tên hoặc tài nguyên riêng lẻ. Bạn có thể đặt “thời gian nhàn rỗi” hoặc ngược lại, “thời gian làm việc”. Ví dụ: để giảm tỷ lệ mở rộng nhiều nhất có thể vào ban đêm và cuối tuần:
image: hjacobs/kube-downscaler:20.4.3
args:
- --interval=30
# не отключать компоненты инфраструктуры
- --exclude-namespaces=kube-system,infra
# не отключать kube-downscaler, а также оставить Postgres Operator, чтобы исключенными БД можно было управлять
- --exclude-deployments=kube-downscaler,postgres-operator
- --default-uptime=Mon-Fri 08:00-20:00 Europe/Berlin
- --include-resources=deployments,statefulsets,stacks,cronjobs
- --deployment-time-annotation=deployment-time
Dưới đây là biểu đồ để chia tỷ lệ các nút công nhân cụm vào cuối tuần:
Việc giảm quy mô từ ~13 xuống 4 nút công nhân chắc chắn sẽ tạo ra sự khác biệt đáng chú ý trong hóa đơn AWS của bạn.
Nhưng nếu tôi cần làm việc trong thời gian "nghỉ hoạt động" của cụm thì sao? Một số triển khai nhất định có thể được loại trừ vĩnh viễn khỏi việc mở rộng quy mô bằng cách thêm chú thích downscaler/exclude: true. Việc triển khai có thể được loại trừ tạm thời bằng cách sử dụng chú thích giảm tỷ lệ/loại trừ cho đến khi có dấu thời gian tuyệt đối ở định dạng YYYY-MM-DD HH:MM (UTC). Nếu cần, toàn bộ cụm có thể được thu nhỏ lại bằng cách triển khai một nhóm có chú thích downscaler/force-uptime, ví dụ: bằng cách khởi chạy nginx trống:
kubectl run scale-up --image=nginx
kubectl annotate deploy scale-up janitor/ttl=1h # удалить развертывание через час
kubectl annotate pod $(kubectl get pod -l run=scale-up -o jsonpath="{.items[0].metadata.name}") downscaler/force-uptime=true
Sử dụng tính năng tự động chia tỷ lệ theo chiều ngang
Nhiều ứng dụng/dịch vụ xử lý kiểu tải động: đôi khi các mô-đun của chúng không hoạt động và đôi khi chúng hoạt động hết công suất. Việc vận hành một đội tàu cố định để đối phó với tải trọng tối đa vào giờ cao điểm là không kinh tế. Kubernetes hỗ trợ tự động mở rộng quy mô theo chiều ngang trên một tài nguyên HorizontalPodAutoscaler (HPA). Việc sử dụng CPU thường là một chỉ báo tốt để mở rộng quy mô:
Zalando đã tạo một thành phần để dễ dàng kết nối các số liệu tùy chỉnh để mở rộng quy mô: Bộ chuyển đổi số liệu Kube (kube-metrics-adapter) là bộ chuyển đổi số liệu chung dành cho Kubernetes, có thể thu thập và phân phát các số liệu tùy chỉnh và bên ngoài để tự động điều chỉnh theo chiều ngang của các nhóm. Nó hỗ trợ mở rộng quy mô dựa trên số liệu Prometheus, hàng đợi SQS và các cài đặt khác. Ví dụ: để mở rộng quy mô triển khai của bạn thành một số liệu tùy chỉnh được chính ứng dụng biểu thị dưới dạng JSON trong /metrics, hãy sử dụng:
Định cấu hình tự động điều chỉnh theo chiều ngang bằng HPA phải là một trong những hành động mặc định để nâng cao hiệu quả cho các dịch vụ không trạng thái. Spotify có bài thuyết trình về kinh nghiệm và đề xuất của họ đối với HPA: mở rộng quy mô triển khai của bạn, không phải ví của bạn.
Giảm việc đặt trước quá nhiều tài nguyên
Khối lượng công việc Kubernetes xác định nhu cầu CPU/bộ nhớ của họ thông qua “yêu cầu tài nguyên”. Tài nguyên CPU được đo bằng lõi ảo hoặc phổ biến hơn là tính bằng “millcores”, ví dụ 500m ngụ ý 50% vCPU. Tài nguyên bộ nhớ được đo bằng byte và có thể sử dụng các hậu tố phổ biến, chẳng hạn như 500Mi, nghĩa là 500 megabyte. Yêu cầu tài nguyên "khóa" dung lượng trên các nút công nhân, nghĩa là một nhóm có yêu cầu CPU 1000m trên một nút có 4 vCPU sẽ chỉ để lại 3 vCPU cho các nhóm khác. [1]
Slack (dự trữ dư thừa) là sự khác biệt giữa tài nguyên được yêu cầu và mức sử dụng thực tế. Ví dụ: một nhóm yêu cầu 2 GiB bộ nhớ nhưng chỉ sử dụng 200 MiB thì có ~1,8 GiB bộ nhớ “dư thừa”. Quá mức sẽ tốn tiền. Người ta có thể ước tính đại khái rằng 1 GiB bộ nhớ dự phòng có giá ~ 10 USD mỗi tháng. [2]
Báo cáo tài nguyên Kubernetes (kube-resource-report) hiển thị lượng dự trữ vượt mức và có thể giúp bạn xác định tiềm năng tiết kiệm:
Báo cáo tài nguyên Kubernetes hiển thị phần dư thừa được tổng hợp bởi ứng dụng và lệnh. Điều này cho phép bạn tìm những nơi có thể giảm nhu cầu tài nguyên. Báo cáo HTML được tạo chỉ cung cấp ảnh chụp nhanh về việc sử dụng tài nguyên. Bạn nên xem xét mức sử dụng CPU/bộ nhớ theo thời gian để xác định các yêu cầu tài nguyên phù hợp. Đây là biểu đồ Grafana cho dịch vụ sử dụng nhiều CPU "điển hình": tất cả các nhóm đang sử dụng ít hơn đáng kể so với 3 lõi CPU được yêu cầu:
Việc giảm yêu cầu CPU từ 3000m xuống ~400m sẽ giải phóng tài nguyên cho các khối lượng công việc khác và cho phép cụm nhỏ hơn.
“Mức sử dụng CPU trung bình của các phiên bản EC2 thường dao động trong phạm vi phần trăm một chữ số,” viết Corey Quinn. Trong khi đối với EC2 ước tính kích thước phù hợp có thể là một quyết định tồiViệc thay đổi một số truy vấn tài nguyên Kubernetes trong tệp YAML rất dễ dàng và có thể mang lại khoản tiết kiệm rất lớn.
Nhưng chúng ta có thực sự muốn mọi người thay đổi giá trị trong file YAML không? Không, máy móc có thể làm điều đó tốt hơn nhiều! Kubernetes Bộ định vị tự động theo chiều dọc (VPA) chỉ làm điều đó: điều chỉnh các yêu cầu và hạn chế về tài nguyên theo khối lượng công việc. Dưới đây là biểu đồ ví dụ về các yêu cầu CPU Prometheus (đường màu xanh lam mỏng) được VPA điều chỉnh theo thời gian:
thiếu nữ tóc vàng từ Fairwind là một công cụ tạo VPA cho mỗi lần triển khai trong một không gian tên và sau đó hiển thị đề xuất VPA trên trang tổng quan của nó. Nó có thể giúp các nhà phát triển đặt yêu cầu CPU/bộ nhớ chính xác cho ứng dụng của họ:
Cuối cùng nhưng không kém phần quan trọng, có thể giảm chi phí AWS EC2 bằng cách sử dụng phiên bản Spot làm nút công nhân Kubernetes [3]. Phiên bản giao ngay được cung cấp với mức giảm giá lên tới 90% so với giá Theo yêu cầu. Chạy Kubernetes trên EC2 Spot là một sự kết hợp tốt: bạn cần chỉ định một số loại phiên bản khác nhau để có độ sẵn sàng cao hơn, nghĩa là bạn có thể có được nút lớn hơn với cùng mức giá hoặc mức giá thấp hơn và công suất tăng lên có thể được sử dụng cho khối lượng công việc Kubernetes được đóng gói.
Làm cách nào để chạy Kubernetes trên EC2 Spot? Có một số tùy chọn: sử dụng dịch vụ của bên thứ ba như SpotInst (hiện được gọi là "Spot", đừng hỏi tôi tại sao) hoặc chỉ cần thêm Spot AutoScalingGroup (ASG) vào cụm của bạn. Ví dụ: đây là đoạn mã CloudFormation cho Spot ASG "được tối ưu hóa dung lượng" với nhiều loại phiên bản:
Các phương pháp hay nhất để tiết kiệm chi phí đám mây trên Kubernetes là gì? Xin vui lòng cho tôi biết tại Twitter (@try_ngoại trừ_).
[1] Trên thực tế, sẽ vẫn có ít hơn 3 vCPU có thể sử dụng được do thông lượng của nút bị giảm do tài nguyên hệ thống dự trữ. Kubernetes phân biệt giữa dung lượng nút vật lý và tài nguyên "được cung cấp" (Nút có thể phân bổ).
[2] Ví dụ tính toán: một phiên bản m5.large có 8 GiB bộ nhớ là ~$84 mỗi tháng (eu-central-1, Theo yêu cầu), tức là. chặn 1/8 nút là khoảng ~$10/tháng.
[3] Có nhiều cách khác để giảm hóa đơn EC2 của bạn, chẳng hạn như Phiên bản dự trữ, Savings Plan, v.v. - Tôi sẽ không đề cập đến những chủ đề đó ở đây, nhưng bạn chắc chắn nên xem xét chúng!