Spar på Kubernetes cloud-omkostninger på AWS

Oversættelsen af ​​artiklen blev udarbejdet på tærsklen til kursets start "Infrastrukturplatform baseret på Kubernetes".

Spar på Kubernetes cloud-omkostninger på AWS

Hvordan sparer man på skyomkostninger, når man arbejder med Kubernetes? Der er ingen enkelt rigtig løsning, men denne artikel beskriver flere værktøjer, der kan hjælpe dig med at administrere dine ressourcer mere effektivt og reducere dine cloud computing-omkostninger.

Jeg skrev denne artikel med Kubernetes til AWS i tankerne, men den vil gælde (næsten) nøjagtig på samme måde for andre cloud-udbydere. Jeg antager, at din/dine klynge allerede har konfigureret autoskalering (cluster-autoscaler). Fjernelse af ressourcer og nedskalering af din implementering vil kun spare dig penge, hvis det også reducerer din flåde af arbejdernoder (EC2-forekomster).

Denne artikel vil dække:

  • oprydning af ubrugte ressourcer (kube-pedel)
  • Reducer skalering i ikke-arbejdstid (kube-downscaler)
  • ved hjælp af horisontal autoskalering (HPA),
  • reduktion af overdreven ressourcereservation (kube-ressource-rapport, VPA)
  • ved hjælp af Spot-forekomster

Oprydning af ubrugte ressourcer

At arbejde i et tempofyldt miljø er fantastisk. Vi vil have teknologiske organisationer accelereret. Hurtigere softwarelevering betyder også flere PR-implementeringer, preview-miljøer, prototyper og analyseløsninger. Alt er installeret på Kubernetes. Hvem har tid til manuelt at rydde op i testinstallationer? Det er nemt at glemme at slette et ugegammelt eksperiment. Skyregningen vil ende med at stige på grund af noget, vi har glemt at lukke:

Spar på Kubernetes cloud-omkostninger på AWS

(Henning Jacobs:
Zhiza:
(citater) Corey Quinn:
Myte: Din AWS-konto er en funktion af antallet af brugere, du har.
Fakta: Din AWS-score er en funktion af antallet af ingeniører, du har.

Ivan Kurnosov (som svar):
Virkelig kendsgerning: Din AWS-score er en funktion af antallet af ting, du har glemt at deaktivere/slette.)

Kubernetes pedel (kube-janitor) hjælper med at rydde op i din klynge. Pedelkonfigurationen er fleksibel til både global og lokal brug:

  • Regler for hele klyngen kan definere den maksimale time-to-live (TTL) for PR/test-implementeringer.
  • Individuelle ressourcer kan annoteres med vicevært/ttl, for eksempel for automatisk at fjerne spidsen/prototypen efter 7 dage.

Generelle regler er defineret i YAML-filen. Dens vej føres gennem parameteren --rules-file i kube-pedel. Her er en eksempelregel til at fjerne alle navnerum med -pr- i navnet efter to dage:

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

Følgende eksempel regulerer brugen af ​​applikationsetiketten på Deployment og StatefulSet pods for alle nye Deployments/StatefulSets i 2020, men tillader samtidig udførelse af test uden denne etiket i en uge:

- 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

Kør en tidsbegrænset demo i 30 minutter på en klynge, der kører kube-janitor:

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

En anden kilde til stigende omkostninger er vedvarende volumener (AWS EBS). Sletning af et Kubernetes StatefulSet sletter ikke dets vedvarende volumener (PVC - PersistentVolumeClaim). Ubrugte EBS-volumener kan nemt resultere i omkostninger på hundredvis af dollars om måneden. Kubernetes Janitor har en funktion til at rense ubrugte PVC'er. For eksempel vil denne regel fjerne alle PVC'er, der ikke er monteret af et modul, og som ikke er refereret til af et StatefulSet eller CronJob:

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

Kubernetes Janitor kan hjælpe dig med at holde din klynge ren og forhindre, at omkostningerne til cloud computing langsomt hober sig op. Følg instruktionerne for installation og konfiguration README kube-pedel.

Reducer skalering i ikke-arbejdstid

Test- og iscenesættelsessystemer er typisk forpligtet til kun at fungere i arbejdstiden. Nogle produktionsapplikationer, såsom backoffice/admin-værktøjer, kræver også kun begrænset tilgængelighed og kan blive deaktiveret natten over.

Kubernetes Downscaler (kube-downscaler) giver brugere og operatører mulighed for at nedskalere systemet i ikke-arbejdstid. Implementeringer og StatefulSets kan skaleres til nul replikaer. CronJobs kan blive suspenderet. Kubernetes Downscaler er konfigureret til en hel klynge, et eller flere navneområder eller individuelle ressourcer. Du kan indstille enten "tomtid" eller omvendt "arbejdstid". For eksempel for at reducere skalering så meget som muligt i løbet af nætter og weekender:

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

Her er en graf til skalering af klyngearbejderknudepunkter i weekenden:

Spar på Kubernetes cloud-omkostninger på AWS

Nedskalering fra ~13 til 4 arbejdernoder gør helt sikkert en mærkbar forskel på din AWS-regning.

Men hvad hvis jeg har brug for at arbejde under klyngen "nedetid"? Visse implementeringer kan permanent udelukkes fra skalering ved at tilføje nedskalering/ekskluder: sand annotering. Implementeringer kan midlertidigt udelukkes ved at bruge nedskalering/ekskluder-indtil-annoteringen med et absolut tidsstempel i formatet ÅÅÅÅ-MM-DD TT:MM (UTC). Om nødvendigt kan hele klyngen skaleres tilbage ved at implementere en pod med annoteringen downscaler/force-uptime, for eksempel ved at starte 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

se README kube-downscaler, hvis du er interesseret i installationsinstruktioner og yderligere muligheder.

Brug vandret autoskalering

Mange applikationer/tjenester håndterer et dynamisk indlæsningsmønster: Nogle gange er deres moduler inaktive, og nogle gange arbejder de med fuld kapacitet. Det er ikke økonomisk at drive en permanent flåde af pods for at klare maksimal spidsbelastning. Kubernetes understøtter horisontal automatisk skalering på tværs af en ressource HorizontalPodAutoscaler (HPA). CPU-brug er ofte en god indikator for skalering:

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 har oprettet en komponent til nemt at forbinde tilpassede metrics til skalering: Kube Metrics Adapter (kube-metrics-adapter) er en generisk metric-adapter til Kubernetes, der kan indsamle og betjene brugerdefinerede og eksterne metrics til horisontal autoskalering af pods. Det understøtter skalering baseret på Prometheus-metrics, SQS-køer og andre indstillinger. For at skalere din implementering til en brugerdefineret metric repræsenteret af selve applikationen som JSON i /metrics skal du f.eks. bruge:

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

Konfiguration af horisontal autoskalering med HPA bør være en af ​​standardhandlingerne for at forbedre effektiviteten for statsløse tjenester. Spotify har en præsentation med deres erfaringer og anbefalinger til HPA: skaler dine implementeringer, ikke din tegnebog.

Reducer ressourceoverbooking

Kubernetes-arbejdsbelastninger bestemmer deres CPU/hukommelsesbehov gennem "ressourceanmodninger." CPU-ressourcer måles i virtuelle kerner eller mere almindeligt i "millicores", for eksempel indebærer 500m 50% vCPU. Hukommelsesressourcer måles i bytes, og almindelige suffikser kan bruges, såsom 500Mi, hvilket betyder 500 megabyte. Ressourceanmodninger "lås" kapacitet på arbejdernoder, hvilket betyder, at en pod med en 1000m CPU-anmodning på en node med 4 vCPU'er kun vil efterlade 3 vCPU'er tilgængelige for andre pods. [1]

Slack (overskydende reserve) er forskellen mellem anmodede ressourcer og faktisk brug. For eksempel har en pod, der anmoder om 2 GiB hukommelse, men kun bruger 200 MiB, ~1,8 GiB "overskydende" hukommelse. Overskud koster penge. Man kan groft anslå, at 1 GiB redundant hukommelse koster ~$10 pr. måned. [2]

Kubernetes ressourcerapport (kube-resource-report) viser overskydende reserver og kan hjælpe dig med at bestemme besparelsespotentiale:

Spar på Kubernetes cloud-omkostninger på AWS

Kubernetes ressourcerapport viser overskuddet aggregeret efter applikation og kommando. Dette giver dig mulighed for at finde steder, hvor ressourcekrav kan reduceres. Den genererede HTML-rapport giver kun et øjebliksbillede af ressourceforbrug. Du bør se på CPU/hukommelsesforbrug over tid for at bestemme tilstrækkelige ressourceanmodninger. Her er et Grafana-diagram for en "typisk" CPU-tung service: alle pods bruger væsentligt mindre end de 3 anmodede CPU-kerner:

Spar på Kubernetes cloud-omkostninger på AWS

Reduktion af CPU-anmodningen fra 3000m til ~400m frigør ressourcer til andre arbejdsbelastninger og tillader klyngen at være mindre.

"Gennemsnitlig CPU-brug af EC2-instanser svæver ofte i det encifrede procentområde," skriver Corey Quinn. Mens til EC2 at estimere den rigtige størrelse kan være en dårlig beslutningDet er nemt at ændre nogle Kubernetes-ressourceforespørgsler i en YAML-fil og kan medføre enorme besparelser.

Men ønsker vi virkelig, at folk ændrer værdier i YAML-filer? Nej, maskiner kan gøre det meget bedre! Kubernetes Vertical Pod Autoscaler (VPA) gør netop det: tilpasser ressourceanmodninger og begrænsninger i henhold til arbejdsbyrden. Her er et eksempel på en graf over Prometheus CPU-anmodninger (tynd blå linje) tilpasset af VPA over tid:

Spar på Kubernetes cloud-omkostninger på AWS

Zalando bruger VPA i alle sine klynger til infrastrukturkomponenter. Ikke-kritiske applikationer kan også bruge VPA.

Guldlok fra Fairwind er et værktøj, der opretter en VPA for hver implementering i et navneområde og derefter viser en VPA-anbefaling på dets dashboard. Det kan hjælpe udviklere med at indstille de korrekte CPU/hukommelsesanmodninger til deres applikationer:

Spar på Kubernetes cloud-omkostninger på AWS

Jeg skrev en lille blogindlæg om VPA i 2019 og for nylig i CNCF-slutbrugerfællesskabet diskuterede VPA-spørgsmål.

Brug af EC2 Spot Instances

Sidst, men ikke mindst, kan AWS EC2-omkostninger reduceres ved at bruge Spot-instanser som Kubernetes-arbejderknudepunkter [3]. Spot-forekomster er tilgængelige med en rabat på op til 90 % sammenlignet med On-Demand-priser. At køre Kubernetes på EC2 Spot er en god kombination: du skal angive flere forskellige instanstyper for højere tilgængelighed, hvilket betyder, at du kan få en større node til samme eller lavere pris, og den øgede kapacitet kan bruges af containeriserede Kubernetes-arbejdsbelastninger.

Hvordan kører man Kubernetes på EC2 Spot? Der er flere muligheder: Brug en tredjepartstjeneste som SpotInst (nu kaldet "Spot", spørg mig ikke hvorfor), eller tilføj blot en Spot AutoScalingGroup (ASG) til din klynge. For eksempel er her et CloudFormation-uddrag til en "kapacitetsoptimeret" Spot ASG med flere instanstyper:

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"

Nogle bemærkninger om brug af Spot med Kubernetes:

  • Du skal håndtere Spot-afslutninger, for eksempel ved at flette noden, når instansen er stoppet
  • Zalando bruger gaffel officiel klyngeautoskalering med nodepuljeprioriteter
  • Spot noder kan tvinges acceptere "registreringer" af arbejdsbelastninger til at køre i Spot

Resumé

Jeg håber, du finder nogle af de præsenterede værktøjer nyttige til at reducere din cloud-regning. Du kan også finde det meste af artiklens indhold på mit foredrag ved DevOps Gathering 2019 på YouTube og i slides.

Hvad er din bedste praksis for at spare cloud-omkostninger på Kubernetes? Giv mig venligst besked kl Twitter (@try_except_).

[1] Faktisk vil mindre end 3 vCPU'er forblive brugbare, da nodens gennemløb reduceres af reserverede systemressourcer. Kubernetes skelner mellem fysisk nodekapacitet og "leverede" ressourcer (Node allokerbar).

[2] Beregningseksempel: en m5.stor instans med 8 GiB hukommelse er ~$84 ​​pr. måned (eu-central-1, On-Demand), dvs. blokering af 1/8 node er cirka ~$10/måned.

[3] Der er mange flere måder at reducere din EC2-regning på, såsom reserverede forekomster, spareplan osv. - Jeg vil ikke dække disse emner her, men du bør helt sikkert kigge nærmere på dem!

Lær mere om kurset.

Kilde: www.habr.com

Tilføj en kommentar