Menghemat biaya cloud Kubernetes di AWS

Terjemahan artikel disiapkan pada malam dimulainya kursus "Platform infrastruktur berdasarkan Kubernetes".

Menghemat biaya cloud Kubernetes di AWS

Bagaimana cara menghemat biaya cloud saat bekerja dengan Kubernetes? Tidak ada satu solusi yang tepat, namun artikel ini menjelaskan beberapa alat yang dapat membantu Anda mengelola sumber daya dengan lebih efektif dan mengurangi biaya komputasi awan.

Saya menulis artikel ini dengan mempertimbangkan Kubernetes untuk AWS, tetapi artikel ini akan berlaku (hampir) sama persis dengan penyedia cloud lainnya. Saya berasumsi cluster Anda sudah memiliki konfigurasi penskalaan otomatis (penskala otomatis cluster). Menghapus sumber daya dan mengurangi penerapan Anda hanya akan menghemat uang jika hal ini juga mengurangi armada node pekerja Anda (instans EC2).

Artikel ini akan mencakup:

Membersihkan sumber daya yang tidak digunakan

Bekerja di lingkungan yang serba cepat adalah hal yang bagus. Kami menginginkan organisasi teknologi dipercepat. Pengiriman perangkat lunak yang lebih cepat juga berarti lebih banyak penerapan PR, lingkungan pratinjau, prototipe, dan solusi analitik. Semuanya diterapkan di Kubernetes. Siapa yang punya waktu untuk membersihkan penerapan pengujian secara manual? Sangat mudah untuk melupakan penghapusan eksperimen yang berumur seminggu. Tagihan cloud akan naik karena sesuatu yang lupa kita tutup:

Menghemat biaya cloud Kubernetes di AWS

(Henning Jacobs:
Zhiza:
(kutipan) Corey Quinn:
Mitos: Akun AWS Anda adalah fungsi dari jumlah pengguna yang Anda miliki.
Fakta: Skor AWS Anda merupakan fungsi dari jumlah insinyur yang Anda miliki.

Ivan Kurnosov (sebagai tanggapan):
Fakta sebenarnya: Skor AWS Anda adalah fungsi dari jumlah hal yang lupa Anda nonaktifkan/hapus.)

Petugas Kebersihan Kubernetes (kube-janitor) membantu membersihkan cluster Anda. Konfigurasi petugas kebersihan fleksibel untuk penggunaan global dan lokal:

  • Aturan di seluruh klaster dapat menentukan waktu hidup maksimum (TTL) untuk penerapan PR/pengujian.
  • Sumber daya individual dapat dianotasi dengan petugas kebersihan/ttl, misalnya untuk menghapus lonjakan/prototipe secara otomatis setelah 7 hari.

Aturan umum ditentukan dalam file YAML. Jalurnya melewati parameter --rules-file di kube-petugas kebersihan. Berikut adalah contoh aturan untuk menghapus semua namespace -pr- atas nama setelah dua hari:

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

Contoh berikut mengatur penggunaan label aplikasi pada pod Deployment dan StatefulSet untuk semua Deployment/StatefulSet baru pada tahun 2020, namun pada saat yang sama memungkinkan pelaksanaan pengujian tanpa label ini selama seminggu:

- 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

Jalankan demo berbatas waktu selama 30 menit pada cluster yang menjalankan kube-janitor:

kubectl run nginx-demo --image=nginx
kubectl annotate deploy nginx-demo janitor/ttl=30m

Sumber lain peningkatan biaya adalah volume persisten (AWS EBS). Menghapus StatefulSet Kubernetes tidak menghapus volume persistennya (PVC - PersistentVolumeClaim). Volume EBS yang tidak terpakai dapat dengan mudah menimbulkan biaya ratusan dolar per bulan. Kubernetes Janitor memiliki fitur untuk membersihkan PVC yang tidak terpakai. Misalnya, aturan ini akan menghapus semua PVC yang tidak dipasang oleh modul dan tidak direferensikan oleh StatefulSet atau CronJob:

# удалить все PVC, которые не смонтированы и на которые не ссылаются StatefulSets
- id: remove-unused-pvcs
  resources:
  - persistentvolumeclaims
  jmespath: "_context.pvc_is_not_mounted && _context.pvc_is_not_referenced"
  ttl: 24h

Kubernetes Janitor dapat membantu Anda menjaga cluster Anda tetap bersih dan mencegah biaya komputasi awan menumpuk secara perlahan. Untuk petunjuk penerapan dan konfigurasi, ikuti README kube-petugas kebersihan.

Kurangi penskalaan di luar jam kerja

Sistem pengujian dan pementasan biasanya diharuskan beroperasi hanya selama jam kerja. Beberapa aplikasi produksi, seperti alat back office/admin, juga hanya memerlukan ketersediaan terbatas dan mungkin dinonaktifkan dalam semalam.

Penurunan Skala Kubernetes (kube-downscaler) memungkinkan pengguna dan operator untuk memperkecil skala sistem di luar jam kerja. Deployment dan StatefulSets dapat menskalakan hingga nol replika. CronJobs mungkin ditangguhkan. Kubernetes Downscaler dikonfigurasi untuk seluruh cluster, satu atau lebih namespace, atau sumber daya individual. Anda dapat mengatur “waktu menganggur” atau, sebaliknya, “waktu kerja”. Misalnya, untuk mengurangi penskalaan sebanyak mungkin pada malam hari dan akhir pekan:

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

Berikut adalah grafik untuk menskalakan node pekerja cluster pada akhir pekan:

Menghemat biaya cloud Kubernetes di AWS

Mengurangi skala dari ~13 menjadi 4 node pekerja tentu saja membuat perbedaan nyata pada tagihan AWS Anda.

Namun bagaimana jika saya harus bekerja selama "waktu henti" cluster? Penerapan tertentu dapat dikecualikan secara permanen dari penskalaan dengan menambahkan anotasi downscaler/exclude: true. Penerapan dapat dikecualikan untuk sementara menggunakan anotasi downscaler/exclude-until dengan stempel waktu absolut dalam format YYYY-MM-DD HH:MM (UTC). Jika perlu, seluruh cluster dapat diperkecil dengan men-deploy pod yang dilengkapi anotasi downscaler/force-uptime, misalnya dengan meluncurkan nginx blank:

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

Lihat README kube-downscaler, jika Anda tertarik dengan petunjuk penerapan dan opsi tambahan.

Gunakan penskalaan otomatis horizontal

Banyak aplikasi/layanan menghadapi pola pemuatan dinamis: terkadang modulnya menganggur, dan terkadang bekerja pada kapasitas penuh. Mengoperasikan armada pod permanen untuk mengatasi beban puncak maksimum tidaklah ekonomis. Kubernetes mendukung penskalaan otomatis horizontal di seluruh sumber daya Penskala OtomatisPod Horisontal (HPA). Penggunaan CPU sering kali merupakan indikator yang baik untuk penskalaan:

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 telah membuat komponen untuk dengan mudah menghubungkan metrik khusus untuk penskalaan: Adaptor Metrik Kube (kube-metrics-adapter) adalah adaptor metrik umum untuk Kubernetes yang dapat mengumpulkan dan menyajikan metrik khusus dan eksternal untuk penskalaan otomatis pod secara horizontal. Ini mendukung penskalaan berdasarkan metrik Prometheus, antrian SQS, dan pengaturan lainnya. Misalnya, untuk menskalakan penerapan Anda ke metrik khusus yang diwakili oleh aplikasi itu sendiri sebagai JSON di /metrics gunakan:

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

Mengonfigurasi penskalaan otomatis horizontal dengan HPA harus menjadi salah satu tindakan default untuk meningkatkan efisiensi layanan tanpa kewarganegaraan. Spotify memiliki presentasi dengan pengalaman dan rekomendasi mereka untuk HPA: skalakan penerapan Anda, bukan dompet Anda.

Mengurangi pemesanan sumber daya yang berlebihan

Beban kerja Kubernetes menentukan kebutuhan CPU/memorinya melalui “permintaan sumber daya”. Sumber daya CPU diukur dalam inti virtual atau lebih umum dalam “milicore”, misalnya 500m berarti 50% vCPU. Sumber daya memori diukur dalam byte, dan sufiks umum dapat digunakan, seperti 500Mi, yang berarti 500 megabita. Permintaan sumber daya "mengunci" kapasitas pada node pekerja, yang berarti sebuah pod dengan permintaan CPU 1000m pada sebuah node dengan 4 vCPU hanya akan menyisakan 3 vCPU yang tersedia untuk pod lain. [1]

Slack (kelebihan cadangan) adalah perbedaan antara sumber daya yang diminta dan penggunaan sebenarnya. Misalnya, sebuah pod yang meminta memori sebesar 2 GiB namun hanya menggunakan 200 MiB memiliki memori “kelebihan” sebesar ~1,8 GiB. Kelebihan membutuhkan uang. Secara kasar dapat diperkirakan bahwa 1 GiB memori redundant berharga ~$10 per bulan. [2]

Laporan Sumber Daya Kubernetes (kube-resource-report) menampilkan kelebihan cadangan dan dapat membantu Anda menentukan potensi penghematan:

Menghemat biaya cloud Kubernetes di AWS

Laporan Sumber Daya Kubernetes menunjukkan kelebihan yang dikumpulkan berdasarkan aplikasi dan perintah. Hal ini memungkinkan Anda menemukan tempat di mana kebutuhan sumber daya dapat dikurangi. Laporan HTML yang dihasilkan hanya memberikan gambaran singkat penggunaan sumber daya. Anda harus melihat penggunaan CPU/memori dari waktu ke waktu untuk menentukan permintaan sumber daya yang memadai. Berikut adalah diagram Grafana untuk layanan "khas" yang banyak menggunakan CPU: semua pod menggunakan kurang dari 3 inti CPU yang diminta:

Menghemat biaya cloud Kubernetes di AWS

Mengurangi permintaan CPU dari 3000m menjadi ~400m akan membebaskan sumber daya untuk beban kerja lain dan memungkinkan cluster menjadi lebih kecil.

“Rata-rata penggunaan CPU pada instans EC2 sering kali berada pada kisaran persentase satu digit,” tulis Corey Quinn. Sedangkan untuk EC2 memperkirakan ukuran yang tepat mungkin merupakan keputusan yang burukMengubah beberapa kueri sumber daya Kubernetes dalam file YAML sangatlah mudah dan dapat memberikan penghematan besar.

Tapi apakah kita benar-benar ingin orang mengubah nilai dalam file YAML? Tidak, mesin bisa melakukannya dengan lebih baik! Kubernet Penskala Otomatis Pod Vertikal (VPA) melakukan hal itu: mengadaptasi permintaan dan batasan sumber daya sesuai dengan beban kerja. Berikut ini contoh grafik permintaan CPU Prometheus (garis biru tipis) yang diadaptasi oleh VPA dari waktu ke waktu:

Menghemat biaya cloud Kubernetes di AWS

Zalando menggunakan VPA di semua clusternya untuk komponen infrastruktur. Aplikasi non-kritis juga dapat menggunakan VPA.

Goldilocks dari Fairwind adalah alat yang membuat VPA untuk setiap penerapan di namespace dan kemudian menampilkan rekomendasi VPA di dasbornya. Ini dapat membantu pengembang mengatur permintaan CPU/memori yang benar untuk aplikasi mereka:

Menghemat biaya cloud Kubernetes di AWS

Saya menulis kecil posting blog tentang VPA pada tahun 2019, dan baru-baru ini pada Komunitas Pengguna Akhir CNCF membahas masalah VPA.

Menggunakan Instans Spot EC2

Yang terakhir, biaya AWS EC2 dapat dikurangi dengan menggunakan instans Spot sebagai node pekerja Kubernetes [3]. Instans spot tersedia dengan diskon hingga 90% dibandingkan harga Sesuai Permintaan. Menjalankan Kubernetes di EC2 Spot adalah kombinasi yang baik: Anda perlu menentukan beberapa jenis instans berbeda untuk ketersediaan yang lebih tinggi, yang berarti Anda bisa mendapatkan node yang lebih besar dengan harga yang sama atau lebih rendah, dan peningkatan kapasitas tersebut dapat digunakan oleh beban kerja Kubernetes yang terkontainer.

Bagaimana cara menjalankan Kubernetes di EC2 Spot? Ada beberapa opsi: gunakan layanan pihak ketiga seperti SpotInst (sekarang disebut "Spot", jangan tanya kenapa), atau cukup tambahkan Spot AutoScalingGroup (ASG) ke cluster Anda. Misalnya, berikut cuplikan CloudFormation untuk ASG Spot yang "dioptimalkan kapasitas" dengan beberapa jenis instans:

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"

Beberapa catatan tentang penggunaan Spot dengan Kubernetes:

  • Anda perlu menangani penghentian Spot, misalnya dengan menggabungkan node ketika instance dihentikan
  • Zalando menggunakan garpu penskalaan otomatis cluster resmi dengan prioritas kumpulan node
  • Node titik bisa dipaksakan menerima “pendaftaran” beban kerja untuk dijalankan di Spot

Ringkasan

Saya harap beberapa alat yang disajikan bermanfaat bagi Anda dalam mengurangi tagihan cloud Anda. Anda juga dapat menemukan sebagian besar isi artikel di ceramah saya di DevOps Gathering 2019 di YouTube dan dalam slide.

Apa praktik terbaik Anda untuk menghemat biaya cloud di Kubernetes? Tolong beritahu saya di Twitter (@coba_kecuali_).

[1] Faktanya, kurang dari 3 vCPU akan tetap dapat digunakan karena throughput node dikurangi dengan sumber daya sistem yang dicadangkan. Kubernetes membedakan antara kapasitas node fisik dan sumber daya yang "disediakan" (Node Dapat Dialokasikan).

[2] Contoh perhitungan: satu instance m5.large dengan memori 8 GiB adalah ~$84 ​​​​per bulan (eu-central-1, On-Demand), mis. memblokir 1/8 node kira-kira ~$10/bulan.

[3] Masih banyak lagi cara untuk mengurangi tagihan EC2 Anda, seperti Reserved Instances, Savings Plan, dll. - Saya tidak akan membahas topik tersebut di sini, namun Anda harus memperhatikannya!

Pelajari lebih lanjut tentang kursus ini.

Sumber: www.habr.com

Tambah komentar