Jimat kos awan Kubernetes pada AWS

Terjemahan artikel telah disediakan pada malam permulaan kursus "Platform infrastruktur berdasarkan Kubernetes".

Jimat kos awan Kubernetes pada AWS

Bagaimana untuk menjimatkan kos awan apabila bekerja dengan Kubernetes? Tiada penyelesaian tunggal yang betul, tetapi artikel ini menerangkan beberapa alat yang boleh membantu anda mengurus sumber anda dengan lebih berkesan dan mengurangkan kos pengkomputeran awan anda.

Saya menulis artikel ini dengan Kubernetes untuk AWS dalam fikiran, tetapi ia akan digunakan (hampir) dengan cara yang sama kepada pembekal awan lain. Saya mengandaikan kluster anda sudah mempunyai autoscaling yang dikonfigurasikan (cluster-autoscaler). Mengalih keluar sumber dan mengecilkan penggunaan anda hanya akan menjimatkan wang anda jika ia turut mengurangkan kumpulan nod pekerja anda (kejadian EC2).

Artikel ini akan merangkumi:

  • membersihkan sumber yang tidak digunakan (kube-janitor)
  • Kurangkan penskalaan semasa waktu tidak bekerja (kube-downscaler)
  • menggunakan penskalaan automatik mendatar (HPA),
  • pengurangan tempahan sumber yang berlebihan (laporan-sumber-kube, VPA)
  • menggunakan contoh Spot

Membersihkan sumber yang tidak digunakan

Bekerja dalam persekitaran pantas adalah bagus. Kami mahu organisasi teknologi dipercepatkan. Penghantaran perisian yang lebih pantas juga bermakna lebih banyak penggunaan PR, persekitaran pratonton, prototaip dan penyelesaian analitik. Semuanya digunakan pada Kubernetes. Siapa yang mempunyai masa untuk membersihkan penggunaan ujian secara manual? Sangat mudah untuk melupakan memadamkan percubaan selama seminggu. Bil awan akhirnya akan meningkat disebabkan oleh sesuatu yang kami terlupa tutup:

Jimat kos awan Kubernetes pada AWS

(Henning Jacobs:
Zhiza:
(petikan) Corey Quinn:
Mitos: Akaun AWS anda ialah fungsi bilangan pengguna yang anda miliki.
Fakta: Skor AWS anda ialah fungsi bilangan jurutera yang anda miliki.

Ivan Kurnosov (sebagai tindak balas):
Fakta sebenar: Skor AWS anda ialah fungsi bilangan perkara yang anda terlupa untuk lumpuhkan/padam.)

Janitor Kubernetes (kube-janitor) membantu membersihkan kluster anda. Konfigurasi janitor adalah fleksibel untuk kegunaan global dan tempatan:

  • Peraturan seluruh kluster boleh menentukan masa untuk hidup (TTL) maksimum untuk pelaksanaan PR/ujian.
  • Sumber individu boleh diberi anotasi dengan janitor/ttl, contohnya untuk mengalih keluar spike/prototaip secara automatik selepas 7 hari.

Peraturan am ditakrifkan dalam fail YAML. Laluannya dilalui melalui parameter --rules-file dalam kube-janitor. Berikut ialah contoh peraturan untuk mengalih keluar semua ruang nama dengan -pr- atas nama selepas dua hari:

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

Contoh berikut mengawal selia penggunaan label aplikasi pada pod Deployment dan StatefulSet untuk semua Deployments/StatefulSets baharu pada tahun 2020, tetapi pada masa yang sama membenarkan pelaksanaan ujian 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 terhad masa selama 30 minit pada kluster yang menjalankan kube-janitor:

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

Satu lagi punca peningkatan kos ialah volum berterusan (AWS EBS). Memadamkan Kubernetes StatefulSet tidak memadamkan volum berterusannya (PVC - PersistentVolumeClaim). Jumlah EBS yang tidak digunakan dengan mudah boleh mengakibatkan kos ratusan dolar sebulan. Kubernetes Janitor mempunyai ciri untuk membersihkan PVC yang tidak digunakan. Sebagai contoh, peraturan ini akan mengalih keluar semua PVC yang tidak dipasang oleh modul dan yang tidak dirujuk 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 boleh membantu anda memastikan kluster anda bersih dan mengelakkan kos pengkomputeran awan daripada meningkat secara perlahan. Untuk arahan penggunaan dan konfigurasi, ikuti README kube-janitor.

Kurangkan penskalaan semasa waktu tidak bekerja

Sistem ujian dan pementasan biasanya diperlukan untuk operasi hanya semasa waktu perniagaan. Sesetengah aplikasi pengeluaran, seperti alat pejabat belakang/pentadbir, juga memerlukan ketersediaan terhad dan mungkin dilumpuhkan dalam sekelip mata.

Kubernetes Downscaler (kube-downscaler) membolehkan pengguna dan pengendali mengecilkan sistem semasa waktu tidak bekerja. Deployments dan StatefulSets boleh menskalakan kepada replika sifar. CronJobs mungkin digantung. Kubernetes Downscaler dikonfigurasikan untuk keseluruhan kluster, satu atau lebih ruang nama atau sumber individu. Anda boleh menetapkan sama ada "masa terbiar" atau, sebaliknya, "masa kerja". Contohnya, untuk mengurangkan penskalaan sebanyak mungkin pada waktu malam dan hujung minggu:

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 ialah graf untuk menskalakan nod pekerja kelompok pada hujung minggu:

Jimat kos awan Kubernetes pada AWS

Penurunan skala daripada ~13 kepada 4 nod pekerja sudah tentu membuat perbezaan yang ketara dalam bil AWS anda.

Tetapi bagaimana jika saya perlu bekerja semasa "masa henti" kelompok? Arahan tertentu boleh dikecualikan secara kekal daripada penskalaan dengan menambahkan penskala bawah/kecualikan: anotasi benar. Alokasi boleh dikecualikan buat sementara waktu menggunakan penskala bawah/kecualikan-hingga anotasi dengan cap masa mutlak dalam format YYYY-MM-DD HH:MM (UTC). Jika perlu, keseluruhan kluster boleh dikecilkan semula dengan menggunakan pod dengan anotasi downscaler/force-uptime, sebagai contoh, dengan melancarkan 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 berminat dengan arahan penggunaan dan pilihan tambahan.

Gunakan penskalaan automatik mendatar

Banyak aplikasi/perkhidmatan berurusan dengan corak pemuatan dinamik: kadangkala modulnya melahu, dan kadangkala ia berfungsi pada kapasiti penuh. Mengendalikan kumpulan pod kekal untuk menampung beban puncak maksimum adalah tidak menjimatkan. Kubernetes menyokong penskalaan automatik mendatar merentas sumber HorizontalPodAutoscaler (HPA). Penggunaan CPU selalunya merupakan penunjuk 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 mencipta komponen untuk menyambungkan metrik tersuai dengan mudah untuk penskalaan: Penyesuai Metrik Kube (kube-metrics-adapter) ialah penyesuai metrik generik untuk Kubernetes yang boleh mengumpul dan menyampaikan metrik tersuai dan luaran untuk penskalaan auto mendatar pod. Ia menyokong penskalaan berdasarkan metrik Prometheus, baris gilir SQS dan tetapan lain. Contohnya, untuk menskalakan penggunaan anda kepada metrik tersuai yang diwakili oleh aplikasi itu sendiri sebagai JSON dalam /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

Mengkonfigurasi penskalaan automatik mendatar dengan HPA harus menjadi salah satu tindakan lalai untuk meningkatkan kecekapan untuk perkhidmatan tanpa kewarganegaraan. Spotify mempunyai persembahan dengan pengalaman dan cadangan mereka untuk HPA: skalakan penggunaan anda, bukan dompet anda.

Kurangkan lebihan tempahan sumber

Beban kerja Kubernetes menentukan keperluan CPU/memori mereka melalui "permintaan sumber". Sumber CPU diukur dalam teras maya atau lebih biasa dalam "milicore", contohnya 500m membayangkan 50% vCPU. Sumber memori diukur dalam bait, dan akhiran biasa boleh digunakan, seperti 500Mi, yang bermaksud 500 megabait. Sumber meminta kapasiti "mengunci" pada nod pekerja, bermakna pod dengan permintaan CPU 1000m pada nod dengan 4 vCPU akan meninggalkan hanya 3 vCPU tersedia untuk pod lain. [1]

Slack (lebihan rizab) ialah perbezaan antara sumber yang diminta dan penggunaan sebenar. Contohnya, pod yang meminta 2 GiB memori tetapi hanya menggunakan 200 MiB mempunyai ~1,8 GiB memori "berlebihan". Lebihan memerlukan wang. Seseorang boleh menganggarkan bahawa 1 GiB memori berlebihan berharga ~$10 sebulan. [2]

Laporan Sumber Kubernetes (kube-resource-report) memaparkan lebihan rizab dan boleh membantu anda menentukan potensi simpanan:

Jimat kos awan Kubernetes pada AWS

Laporan Sumber Kubernetes menunjukkan lebihan yang diagregatkan oleh aplikasi dan arahan. Ini membolehkan anda mencari tempat di mana permintaan sumber boleh dikurangkan. Laporan HTML yang dihasilkan hanya menyediakan gambaran penggunaan sumber. Anda harus melihat penggunaan CPU/memori dari semasa ke semasa untuk menentukan permintaan sumber yang mencukupi. Berikut ialah carta Grafana untuk perkhidmatan berat CPU "biasa": semua pod menggunakan kurang ketara daripada 3 teras CPU yang diminta:

Jimat kos awan Kubernetes pada AWS

Mengurangkan permintaan CPU daripada 3000m kepada ~400m membebaskan sumber untuk beban kerja lain dan membolehkan kluster menjadi lebih kecil.

"Purata penggunaan CPU bagi kejadian EC2 sering berlegar dalam julat peratusan satu digit," tulis Corey Quinn. Manakala bagi EC2 menganggarkan saiz yang betul mungkin merupakan keputusan yang tidak baikMenukar beberapa pertanyaan sumber Kubernetes dalam fail YAML adalah mudah dan boleh membawa penjimatan yang besar.

Tetapi adakah kita benar-benar mahu orang mengubah nilai dalam fail YAML? Tidak, mesin boleh melakukannya dengan lebih baik! Kubernetes Autoscaler Pod Menegak (VPA) berbuat demikian: menyesuaikan permintaan sumber dan kekangan mengikut beban kerja. Berikut ialah graf contoh permintaan CPU Prometheus (garisan biru nipis) yang disesuaikan oleh VPA dari semasa ke semasa:

Jimat kos awan Kubernetes pada AWS

Zalando menggunakan VPA dalam semua kelompoknya untuk komponen infrastruktur. Aplikasi tidak kritikal juga boleh menggunakan VPA.

Goldilocks daripada Fairwind ialah alat yang mencipta VPA untuk setiap penggunaan dalam ruang nama dan kemudian memaparkan pengesyoran VPA pada papan pemukanya. Ia boleh membantu pembangun menetapkan permintaan CPU/memori yang betul untuk aplikasi mereka:

Jimat kos awan Kubernetes pada AWS

Saya menulis kecil blogpost tentang VPA pada 2019, dan baru-baru ini pada Komuniti Pengguna Akhir CNCF membincangkan isu VPA.

Menggunakan Instans Spot EC2

Akhir sekali, kos AWS EC2 boleh dikurangkan dengan menggunakan contoh Spot sebagai nod pekerja Kubernetes [3]. Contoh spot tersedia pada diskaun sehingga 90% berbanding harga Atas Permintaan. Menjalankan Kubernetes pada EC2 Spot ialah gabungan yang baik: anda perlu menentukan beberapa jenis contoh yang berbeza untuk ketersediaan yang lebih tinggi, bermakna anda boleh mendapatkan nod yang lebih besar untuk harga yang sama atau lebih rendah, dan kapasiti yang meningkat boleh digunakan oleh beban kerja Kubernetes dalam bekas.

Bagaimana untuk menjalankan Kubernetes pada EC2 Spot? Terdapat beberapa pilihan: gunakan perkhidmatan pihak ketiga seperti SpotInst (kini dipanggil "Spot", jangan tanya saya mengapa), atau cuma tambah Spot AutoScalingGroup (ASG) pada kelompok anda. Sebagai contoh, berikut ialah coretan CloudFormation untuk Spot ASG "dioptimumkan kapasiti" dengan berbilang jenis tika:

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 nota tentang menggunakan Spot dengan Kubernetes:

  • Anda perlu mengendalikan penamatan Spot, contohnya dengan menggabungkan nod apabila kejadian dihentikan
  • Zalando menggunakan garpu penskalaan automatik kelompok rasmi dengan keutamaan kumpulan nod
  • Nod titik boleh paksa menerima "pendaftaran" beban kerja untuk dijalankan di Spot

Ringkasan

Saya harap anda mendapati beberapa alatan yang dibentangkan berguna dalam mengurangkan bil awan anda. Anda boleh menemui kebanyakan kandungan artikel juga di ceramah saya di DevOps Gathering 2019 di YouTube dan dalam slaid.

Apakah amalan terbaik anda untuk menjimatkan kos awan pada Kubernetes? Sila beritahu saya di Twitter (@try_except_).

[1] Malah, kurang daripada 3 vCPU akan kekal boleh digunakan kerana daya pengeluaran nod dikurangkan oleh sumber sistem terpelihara. Kubernetes membezakan antara kapasiti nod fizikal dan sumber "diperuntukkan" (Nod Boleh Diperuntukkan).

[2] Contoh pengiraan: satu contoh m5.besar dengan 8 GiB memori ialah ~$84 ​​​​sebulan (eu-central-1, Atas Permintaan), i.e. menyekat 1/8 nod adalah lebih kurang ~$10/bulan.

[3] Terdapat banyak lagi cara untuk mengurangkan bil EC2 anda, seperti Contoh Terpelihara, Pelan Simpanan, dsb. - Saya tidak akan membincangkan topik tersebut di sini, tetapi anda pasti perlu melihatnya!

Ketahui lebih lanjut tentang kursus.

Sumber: www.habr.com

Tambah komen