Tiết kiệm chi phí đám mây Kubernetes trên AWS

Bản dịch của bài báo đã được chuẩn bị vào đêm trước khi bắt đầu khóa học "Nền tảng cơ sở hạ tầng dựa trên Kubernetes".

Tiết kiệm chi phí đám mây Kubernetes trên AWS

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).

Bài viết này sẽ bao gồm:

  • dọn dẹp các tài nguyên không sử dụng (người gác cổng kube)
  • Giảm tỷ lệ trong giờ không làm việc (kube-downscaler)
  • sử dụng tính năng tự động điều chỉnh theo chiều ngang (HPA),
  • giảm việc dự trữ tài nguyên quá mức (kube-tài nguyên-báo cáo, VPA)
  • sử dụng phiên bản Spot

Dọn dẹp các tài nguyên không sử dụng

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ứ:

Tiết kiệm chi phí đám mây Kubernetes trên AWS

(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:

- id: cleanup-resources-from-pull-requests
  resources:
    - namespaces
  jmespath: "contains(metadata.name, '-pr-')"
  ttl: 2d

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:

Tiết kiệm chi phí đám mây Kubernetes trên AWS

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

thấy Công cụ thu nhỏ kube README, nếu bạn quan tâm đến hướng dẫn triển khai và các tùy chọn bổ sung.

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ô:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        averageUtilization: 100
        type: Utilization

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:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
  annotations:
    # metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
    metric-config.pods.requests-per-second.json-path/json-key: "$.http_server.rps"
    metric-config.pods.requests-per-second.json-path/path: /metrics
    metric-config.pods.requests-per-second.json-path/port: "9090"
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Pods
    pods:
      metric:
        name: requests-per-second
      target:
        averageValue: 1k
        type: AverageValue

Đị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:

Tiết kiệm chi phí đám mây Kubernetes trên AWS

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:

Tiết kiệm chi phí đám mây Kubernetes trên AWS

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:

Tiết kiệm chi phí đám mây Kubernetes trên AWS

Zalando sử dụng VPA trong tất cả các cụm của mình cho các thành phần cơ sở hạ tầng. Các ứng dụng không quan trọng cũng có thể sử dụng VPA.

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ọ:

Tiết kiệm chi phí đám mây Kubernetes trên AWS

Tôi đã viết một cái nhỏ bài viết blog về VPA vào năm 2019 và gần đây là vào Cộng đồng người dùng cuối CNCF đã thảo luận về vấn đề VPA.

Sử dụng phiên bản Spot EC2

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:

MySpotAutoScalingGroup:
 Properties:
   HealthCheckGracePeriod: 300
   HealthCheckType: EC2
   MixedInstancesPolicy:
     InstancesDistribution:
       OnDemandPercentageAboveBaseCapacity: 0
       SpotAllocationStrategy: capacity-optimized
     LaunchTemplate:
       LaunchTemplateSpecification:
         LaunchTemplateId: !Ref LaunchTemplate
         Version: !GetAtt LaunchTemplate.LatestVersionNumber
       Overrides:
         - InstanceType: "m4.2xlarge"
         - InstanceType: "m4.4xlarge"
         - InstanceType: "m5.2xlarge"
         - InstanceType: "m5.4xlarge"
         - InstanceType: "r4.2xlarge"
         - InstanceType: "r4.4xlarge"
   LaunchTemplate:
     LaunchTemplateId: !Ref LaunchTemplate
     Version: !GetAtt LaunchTemplate.LatestVersionNumber
   MinSize: 0
   MaxSize: 100
   Tags:
   - Key: k8s.io/cluster-autoscaler/node-template/label/aws.amazon.com/spot
     PropagateAtLaunch: true
     Value: "true"

Một số lưu ý khi sử dụng Spot với Kubernetes:

  • Bạn cần xử lý việc chấm dứt Spot, chẳng hạn như bằng cách hợp nhất nút khi phiên bản bị dừng
  • Zalando sử dụng cái nĩa tự động điều chỉnh quy mô cụm chính thức với mức độ ưu tiên của nhóm nút
  • Nút điểm có thể bị ép buộc chấp nhận “đăng ký” khối lượng công việc để chạy Spot

Tóm tắt thông tin

Tôi hy vọng bạn thấy một số công cụ được trình bày hữu ích trong việc giảm hóa đơn đám mây của mình. Bạn có thể tìm thấy hầu hết nội dung của bài viết tại bài nói chuyện của tôi tại DevOps Gathering 2019 trên YouTube và trong các slide.

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!

Tìm hiểu thêm về khóa học.

Nguồn: www.habr.com

Thêm một lời nhận xét