Makatipid sa mga gastos sa cloud ng Kubernetes sa AWS

Ang pagsasalin ng artikulo ay inihanda sa bisperas ng pagsisimula ng kurso "Platform ng imprastraktura batay sa Kubernetes".

Makatipid sa mga gastos sa cloud ng Kubernetes sa AWS

Paano makatipid sa mga gastos sa ulap kapag nagtatrabaho sa Kubernetes? Walang iisang tamang solusyon, ngunit inilalarawan ng artikulong ito ang ilang tool na makakatulong sa iyong pamahalaan nang mas epektibo ang iyong mga mapagkukunan at mabawasan ang iyong mga gastos sa cloud computing.

Isinulat ko ang artikulong ito nang nasa isip ang Kubernetes para sa AWS, ngunit ilalapat ito (halos) nang eksakto sa parehong paraan sa iba pang mga provider ng cloud. Ipinapalagay ko na ang iyong (mga) cluster ay mayroon nang na-configure na autoscaling (cluster-autoscaler). Ang pag-alis ng mga mapagkukunan at pagpapaliit sa iyong deployment ay makakatipid lamang sa iyo ng pera kung babawasan din nito ang iyong fleet ng mga worker node (EC2 instance).

Sasaklawin ng artikulong ito ang:

  • paglilinis ng mga hindi nagamit na mapagkukunan (kube-janitor)
  • Bawasan ang scaling sa mga oras na walang trabaho (kube-downscaler)
  • gamit ang horizontal autoscaling (HPA),
  • pagbawas ng labis na reserbasyon ng mapagkukunan (kube-resource-report, VPA)
  • gamit ang mga instance ng Spot

Nililinis ang mga hindi nagamit na mapagkukunan

Ang pagtatrabaho sa isang mabilis na kapaligiran ay mahusay. Gusto namin ng mga tech na organisasyon pinabilis. Nangangahulugan din ang mas mabilis na paghahatid ng software ng mas maraming PR deployment, preview environment, prototype, at analytics solution. Ang lahat ay naka-deploy sa Kubernetes. Sino ang may oras na manu-manong linisin ang mga deployment ng pagsubok? Madaling kalimutan ang tungkol sa pagtanggal ng isang linggong eksperimento. Tataas ang cloud bill dahil sa isang bagay na nakalimutan naming isara:

Makatipid sa mga gastos sa cloud ng Kubernetes sa AWS

(Henning Jacobs:
Zhiza:
(quotes) Corey Quinn:
Pabula: Ang iyong AWS account ay isang function ng bilang ng mga user na mayroon ka.
Katotohanan: Ang iyong AWS score ay isang function ng bilang ng mga engineer na mayroon ka.

Ivan Kurnosov (bilang tugon):
Tunay na katotohanan: Ang iyong AWS score ay isang function ng bilang ng mga bagay na nakalimutan mong i-disable/delete.)

Kubernetes Janitor (kube-janitor) ay tumutulong sa paglilinis ng iyong kumpol. Ang configuration ng janitor ay flexible para sa parehong global at lokal na paggamit:

  • Maaaring tukuyin ng mga panuntunan sa buong grupo ang maximum time-to-live (TTL) para sa mga deployment ng PR/test.
  • Maaaring i-annotate ang mga indibidwal na mapagkukunan gamit ang janitor/ttl, halimbawa para awtomatikong alisin ang spike/prototype pagkatapos ng 7 araw.

Ang mga pangkalahatang tuntunin ay tinukoy sa YAML file. Ang landas nito ay dumaan sa parameter --rules-file sa kube-janitor. Narito ang isang halimbawang panuntunan para alisin ang lahat ng namespace na may -pr- sa pangalan pagkatapos ng dalawang araw:

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

Kinokontrol ng sumusunod na halimbawa ang paggamit ng label ng application sa Deployment at StatefulSet pod para sa lahat ng bagong Deployment/StatefulSets sa 2020, ngunit sa parehong oras ay nagbibigay-daan sa pagpapatupad ng mga pagsubok nang walang label na ito sa loob ng isang linggo:

- 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

Magpatakbo ng demo na limitado sa oras sa loob ng 30 minuto sa isang cluster na tumatakbo sa kube-janitor:

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

Ang isa pang pinagmumulan ng pagtaas ng mga gastos ay ang mga persistent volume (AWS EBS). Ang pagtanggal ng Kubernetes StatefulSet ay hindi nagtatanggal ng mga patuloy na volume nito (PVC - PersistentVolumeClaim). Ang mga hindi nagamit na volume ng EBS ay madaling magresulta sa mga gastos na daan-daang dolyar bawat buwan. May feature ang Kubernetes Janitor para linisin ang mga hindi nagamit na PVC. Halimbawa, aalisin ng panuntunang ito ang lahat ng PVC na hindi na-mount ng isang module at hindi nire-reference ng isang StatefulSet o CronJob:

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

Matutulungan ka ng Kubernetes Janitor na panatilihing malinis ang iyong cluster at pigilan ang mga gastos sa cloud computing na mabagal na tumaas. Para sa mga tagubilin sa pag-deploy at pagsasaayos, sundin README kube-janitor.

Bawasan ang scaling sa mga oras na walang pasok

Karaniwang kinakailangan ang mga sistema ng pagsubok at pagtatanghal para sa operasyon sa mga oras ng negosyo. Ang ilang mga application sa produksyon, tulad ng mga back office/admin tool, ay nangangailangan lamang ng limitadong kakayahang magamit at maaaring ma-disable sa isang gabi.

Kubernetes Downscaler (kube-downscaler) ay nagbibigay-daan sa mga user at operator na bawasan ang system sa mga oras na hindi nagtatrabaho. Ang Mga Deployment at StatefulSets ay maaaring i-scale sa zero na mga replika. Maaaring masuspinde ang CronJobs. Ang Kubernetes Downscaler ay na-configure para sa isang buong cluster, isa o higit pang namespace, o indibidwal na mapagkukunan. Maaari mong itakda ang alinman sa "oras ng walang ginagawa" o, kabaligtaran, "oras ng trabaho". Halimbawa, upang bawasan ang scaling hangga't maaari sa mga gabi at katapusan ng linggo:

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

Narito ang isang graph para sa pag-scale ng mga cluster worker node sa katapusan ng linggo:

Makatipid sa mga gastos sa cloud ng Kubernetes sa AWS

Ang pag-scale pababa mula ~13 hanggang 4 na worker node ay tiyak na gumagawa ng kapansin-pansing pagkakaiba sa iyong AWS bill.

Ngunit paano kung kailangan kong magtrabaho sa panahon ng cluster na "downtime"? Maaaring permanenteng ibukod sa pag-scale ang ilang partikular na deployment sa pamamagitan ng pagdaragdag ng downscaler/exclude: true annotation. Maaaring pansamantalang ibukod ang mga deployment gamit ang downscaler/exclude-hanggang annotation na may absolute timestamp sa format na YYYY-MM-DD HH:MM (UTC). Kung kinakailangan, ang buong cluster ay maaaring i-scale pabalik sa pamamagitan ng pag-deploy ng pod na may anotasyon downscaler/force-uptime, halimbawa, sa pamamagitan ng paglulunsad ng 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

Tingnan README kube-downscaler, kung interesado ka sa mga tagubilin sa pag-deploy at karagdagang mga opsyon.

Gumamit ng pahalang na autoscaling

Maraming mga application/serbisyo ang nakikitungo sa isang dynamic na pattern ng paglo-load: kung minsan ang kanilang mga module ay idle, at kung minsan ay gumagana ang mga ito sa buong kapasidad. Ang pagpapatakbo ng isang permanenteng fleet ng mga pod upang makayanan ang maximum na peak load ay hindi matipid. Sinusuportahan ng Kubernetes ang pahalang na awtomatikong pag-scale sa isang mapagkukunan HorizontalPodAutoscaler (HPA). Ang paggamit ng CPU ay madalas na isang mahusay na tagapagpahiwatig para sa pag-scale:

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

Gumawa si Zalando ng isang bahagi upang madaling ikonekta ang mga custom na sukatan para sa pag-scale: Kube Metrics Adapter Ang (kube-metrics-adapter) ay isang generic na metrics adapter para sa Kubernetes na maaaring mangolekta at maghatid ng mga custom at external na sukatan para sa horizontal autoscaling ng mga pod. Sinusuportahan nito ang pag-scale batay sa mga sukatan ng Prometheus, mga pila ng SQS, at iba pang mga setting. Halimbawa, upang i-scale ang iyong deployment sa isang custom na sukatan na kinakatawan ng mismong application bilang JSON sa /metrics gamitin:

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

Ang pag-configure ng pahalang na autoscaling gamit ang HPA ay dapat isa sa mga default na pagkilos upang mapabuti ang kahusayan para sa mga walang estado na serbisyo. May presentasyon ang Spotify kasama ang kanilang karanasan at mga rekomendasyon para sa HPA: sukatin ang iyong mga deployment, hindi ang iyong wallet.

Bawasan ang overbooking ng mapagkukunan

Tinutukoy ng mga workload ng Kubernetes ang kanilang mga pangangailangan sa CPU/memory sa pamamagitan ng "mga kahilingan sa mapagkukunan." Ang mga mapagkukunan ng CPU ay sinusukat sa mga virtual na core o mas karaniwan sa "millicore", halimbawa, ang 500m ay nagpapahiwatig ng 50% vCPU. Ang mga mapagkukunan ng memorya ay sinusukat sa mga byte, at maaaring gamitin ang mga karaniwang suffix, gaya ng 500Mi, na nangangahulugang 500 megabytes. Ang resource ay humihiling ng kapasidad na "lock" sa mga worker node, ibig sabihin, ang isang pod na may 1000m CPU request sa isang node na may 4 na vCPU ay mag-iiwan lamang ng 3 vCPU na available sa iba pang pod. [1]

Slack (labis na reserba) ay ang pagkakaiba sa pagitan ng mga hiniling na mapagkukunan at aktwal na paggamit. Halimbawa, ang isang pod na humihiling ng 2 GiB ng memory ngunit gumagamit lamang ng 200 MiB ay may ~1,8 GiB ng "labis" na memorya. Ang labis ay nagkakahalaga ng pera. Maaaring tantiyahin ng isa na ang 1 GiB ng redundant memory ay nagkakahalaga ng ~$10 bawat buwan. [2]

Ulat sa Mapagkukunan ng Kubernetes Ang (kube-resource-report) ay nagpapakita ng mga labis na reserba at makakatulong sa iyo na matukoy ang potensyal ng pagtitipid:

Makatipid sa mga gastos sa cloud ng Kubernetes sa AWS

Ulat sa Mapagkukunan ng Kubernetes nagpapakita ng labis na pinagsama-sama ng aplikasyon at utos. Nagbibigay-daan ito sa iyo na makahanap ng mga lugar kung saan maaaring mabawasan ang mga hinihingi ng mapagkukunan. Ang nabuong ulat ng HTML ay nagbibigay lamang ng snapshot ng paggamit ng mapagkukunan. Dapat mong tingnan ang paggamit ng CPU/memory sa paglipas ng panahon upang matukoy ang sapat na mga kahilingan sa mapagkukunan. Narito ang isang Grafana chart para sa isang "karaniwang" CPU-heavy na serbisyo: lahat ng pod ay gumagamit ng mas kaunti kaysa sa 3 hiniling na CPU core:

Makatipid sa mga gastos sa cloud ng Kubernetes sa AWS

Ang pagbabawas ng kahilingan ng CPU mula 3000m hanggang ~400m ay nagpapalaya ng mga mapagkukunan para sa iba pang mga workload at nagbibigay-daan sa cluster na maging mas maliit.

"Ang average na paggamit ng CPU ng mga instance ng EC2 ay madalas na nagho-hover sa isang-digit na hanay ng porsyento," isinulat ni Corey Quinn. Habang para sa EC2 ang pagtatantya ng tamang sukat ay maaaring isang masamang desisyonAng pagpapalit ng ilang Kubernetes resource query sa isang YAML file ay madali at maaaring magdulot ng malaking tipid.

Ngunit gusto ba talaga nating baguhin ng mga tao ang mga halaga sa mga file ng YAML? Hindi, mas magagawa ito ng mga makina! Kubernetes Vertical Pod Autoscaler (VPA) ay ganoon lang: inaangkop ang mga kahilingan sa mapagkukunan at mga hadlang ayon sa workload. Narito ang isang halimbawang graph ng mga kahilingan ng Prometheus CPU (manipis na asul na linya) na inangkop ng VPA sa paglipas ng panahon:

Makatipid sa mga gastos sa cloud ng Kubernetes sa AWS

Ginagamit ng Zalando ang VPA sa lahat ng mga cluster nito para sa mga bahagi ng imprastraktura. Ang mga hindi kritikal na application ay maaari ding gumamit ng VPA.

Goldilocks mula sa Fairwind ay isang tool na lumilikha ng VPA para sa bawat deployment sa isang namespace at pagkatapos ay nagpapakita ng rekomendasyon ng VPA sa dashboard nito. Makakatulong ito sa mga developer na itakda ang tamang mga kahilingan sa CPU/memory para sa kanilang mga application:

Makatipid sa mga gastos sa cloud ng Kubernetes sa AWS

Sumulat ako ng maliit blogpost tungkol sa VPA noong 2019, at kamakailan noong Tinalakay ng Komunidad ng End User ng CNCF ang isyu sa VPA.

Paggamit ng EC2 Spot Instances

Panghuli ngunit hindi bababa sa, ang mga gastos sa AWS EC2 ay maaaring mabawasan sa pamamagitan ng paggamit ng mga instance ng Spot bilang mga node ng manggagawa sa Kubernetes [3]. Available ang mga spot instance sa diskwento na hanggang 90% kumpara sa On-Demand na mga presyo. Ang pagpapatakbo ng Kubernetes sa EC2 Spot ay isang magandang kumbinasyon: kailangan mong tumukoy ng ilang iba't ibang uri ng instance para sa mas mataas na availability, ibig sabihin ay makakakuha ka ng mas malaking node para sa pareho o mas mababang presyo, at ang tumaas na kapasidad ay magagamit ng mga containerized na Kubernetes workload.

Paano patakbuhin ang Kubernetes sa EC2 Spot? Mayroong ilang mga opsyon: gumamit ng isang third party na serbisyo tulad ng SpotInst (tinatawag na ngayong "Spot", huwag itanong sa akin kung bakit), o magdagdag lamang ng Spot AutoScalingGroup (ASG) sa iyong cluster. Halimbawa, narito ang isang CloudFormation snippet para sa Spot ASG na "naka-optimize sa kapasidad" na may maraming uri ng instance:

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"

Ilang tala sa paggamit ng Spot sa Kubernetes:

  • Kailangan mong pangasiwaan ang mga pagwawakas ng Spot, halimbawa sa pamamagitan ng pagsasama ng node kapag huminto ang instance
  • Ginagamit ni Zalando tinidor opisyal na cluster autoscaling na may mga priyoridad sa node pool
  • Mga spot node pwedeng pilitin tanggapin ang "mga pagpaparehistro" ng mga workload na tatakbo sa Spot

Buod

Sana ay makita mo ang ilan sa mga tool na ipinakita na kapaki-pakinabang sa pagbawas ng iyong cloud bill. Mahahanap mo rin ang karamihan sa mga nilalaman ng artikulo sa ang aking pahayag sa DevOps Gathering 2019 sa YouTube at sa mga slide.

Ano ang iyong mga pinakamahusay na kagawian para makatipid ng mga gastos sa cloud sa Kubernetes? Mangyaring ipaalam sa akin sa Twitter (@try_except_).

[1] Sa katunayan, wala pang 3 vCPU ang mananatiling magagamit dahil ang throughput ng node ay nababawasan ng mga nakalaan na mapagkukunan ng system. Tinutukoy ng Kubernetes ang pagitan ng kapasidad ng pisikal na node at "provisioned" na mapagkukunan (Node Allocatable).

[2] Halimbawa ng pagkalkula: isang m5.large instance na may 8 GiB ng memory ay ~$84 ​​​​bawat buwan (eu-central-1, On-Demand), i.e. ang pagharang sa 1/8 node ay humigit-kumulang ~$10/buwan.

[3] Marami pang paraan para bawasan ang iyong EC2 bill, gaya ng Reserved Instances, Savings Plan, atbp. - Hindi ko tatalakayin ang mga paksang iyon dito, ngunit dapat mong tingnan ang mga ito!

Matuto pa tungkol sa kurso.

Pinagmulan: www.habr.com

Magdagdag ng komento