Spara på Kubernetes molnkostnader på AWS

Översättningen av artikeln förbereddes strax före kursstart "Infrastrukturplattform baserad på Kubernetes".

Spara på Kubernetes molnkostnader på AWS

Hur sparar man på molnkostnaderna när man arbetar med Kubernetes? Det finns ingen enskild rätt lösning, men den här artikeln beskriver flera verktyg som kan hjälpa dig att hantera dina resurser mer effektivt och minska dina molnkostnader.

Jag skrev den här artikeln med Kubernetes för AWS i åtanke, men den kommer att gälla (nästan) exakt på samma sätt för andra molnleverantörer. Jag antar att dina kluster redan har konfigurerat automatisk skalning (kluster-autoscaler). Att ta bort resurser och skala ner din distribution kommer bara att spara pengar om det också minskar din flotta av arbetarnoder (EC2-instanser).

Den här artikeln kommer att täcka:

Rensning av oanvända resurser

Att arbeta i en miljö med högt tempo är fantastiskt. Vi vill ha tekniska organisationer accelererad. Snabbare leverans av programvara innebär också fler PR-distributioner, förhandsgranskningsmiljöer, prototyper och analyslösningar. Allt är utplacerat på Kubernetes. Vem har tid att manuellt rensa upp testinstallationer? Det är lätt att glömma bort att ta bort ett vecka gammalt experiment. Molnräkningen kommer att stiga på grund av något vi glömde att stänga:

Spara på Kubernetes molnkostnader på AWS

(Henning Jacobs:
Zhiza:
(citat) Corey Quinn:
Myt: Ditt AWS-konto är en funktion av antalet användare du har.
Fakta: Din AWS-poäng är en funktion av antalet ingenjörer du har.

Ivan Kurnosov (som svar):
Verkligt faktum: Din AWS-poäng är en funktion av antalet saker du glömde att inaktivera/ta bort.)

Kubernetes vaktmästare (kube-janitor) hjälper till att rensa upp ditt kluster. Vaktmästarkonfigurationen är flexibel för både global och lokal användning:

  • Klusteromfattande regler kan definiera den maximala tiden att leva (TTL) för PR/test-distributioner.
  • Enskilda resurser kan annoteras med vaktmästare/ttl, till exempel för att automatiskt ta bort spiken/prototypen efter 7 dagar.

Allmänna regler definieras i YAML-filen. Dess väg passerar genom parametern --rules-file i kube-vaktmästare. Här är en exempelregel att ta bort alla namnrymder med -pr- i namnet efter två dagar:

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

Följande exempel reglerar användningen av applikationsetiketten på Deployment- och StatefulSet-podarna för alla nya Deployments/StatefulSets under 2020, men tillåter samtidigt exekvering av tester utan denna etikett i en vecka:

- 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änsad demo i 30 minuter på ett kluster som kör kube-janitor:

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

En annan källa till ökande kostnader är ihållande volymer (AWS EBS). Att ta bort ett Kubernetes StatefulSet tar inte bort dess beständiga volymer (PVC - PersistentVolumeClaim). Oanvända EBS-volymer kan lätt resultera i kostnader på hundratals dollar per månad. Kubernetes Janitor har en funktion för att rensa upp oanvända PVC-skivor. Till exempel kommer denna regel att ta bort alla PVC som inte är monterade av en modul och som inte refereras av en 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älpa dig att hålla ditt kluster rent och förhindra att kostnaderna för cloud computing långsamt hopar sig. Följ instruktionerna för installation och konfiguration LÄS MIG kube-vaktmästare.

Minska skalning under icke-arbetstid

Test- och mellanstationssystem krävs vanligtvis för drift endast under kontorstid. Vissa produktionsapplikationer, som backoffice/admin-verktyg, kräver också endast begränsad tillgänglighet och kan inaktiveras över natten.

Kubernetes Downscaler (kube-downscaler) tillåter användare och operatörer att skala ner systemet under icke-arbetstid. Implementeringar och StatefulSets kan skalas till noll repliker. CronJobs kan stängas av. Kubernetes Downscaler är konfigurerad för ett helt kluster, en eller flera namnområden eller enskilda resurser. Du kan ställa in antingen "ledig tid" eller, omvänt, "arbetstid". Till exempel för att minska skalningen så mycket som möjligt under nätter och helger:

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

Här är en graf för skalning av klusterarbetarnoder på helger:

Spara på Kubernetes molnkostnader på AWS

Att skala ner från ~13 till 4 arbetarnoder gör verkligen en märkbar skillnad i din AWS-räkning.

Men vad händer om jag behöver arbeta under klustrets "stopptid"? Vissa distributioner kan permanent uteslutas från skalning genom att lägga till nedskalning/exclude: true annotation. Implementeringar kan tillfälligt uteslutas med nedskalning/uteslut-till-kommentaren med en absolut tidsstämpel i formatet ÅÅÅÅ-MM-DD HH:MM (UTC). Om det behövs kan hela klustret skalas tillbaka genom att distribuera en pod med anteckningen downscaler/force-uptime, till exempel genom att starta 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, om du är intresserad av installationsinstruktioner och ytterligare alternativ.

Använd horisontell autoskalning

Många applikationer/tjänster hanterar ett dynamiskt laddningsmönster: ibland är deras moduler inaktiva, och ibland arbetar de med full kapacitet. Att driva en permanent flotta av baljor för att klara maximal toppbelastning är inte ekonomiskt. Kubernetes stöder horisontell automatisk skalning över en resurs HorizontalPodAutoscaler (HPA). CPU-användning är ofta en bra indikator för skalning:

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 skapat en komponent för att enkelt ansluta anpassade mätvärden för skalning: Kube Metrics Adapter (kube-metrics-adapter) är en generisk metrikadapter för Kubernetes som kan samla in och betjäna anpassade och externa mätvärden för horisontell autoskalning av pods. Den stöder skalning baserat på Prometheus-mått, SQS-köer och andra inställningar. Till exempel, för att skala din distribution till ett anpassat mått som representeras av själva applikationen som JSON i /metrics använder du:

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

Konfigurering av horisontell automatisk skalning med HPA bör vara en av standardåtgärderna för att förbättra effektiviteten för tillståndslösa tjänster. Spotify har en presentation med deras erfarenheter och rekommendationer för HPA: skala dina distributioner, inte din plånbok.

Minska överbokning av resurser

Kubernetes-arbetsbelastningar bestämmer deras CPU-/minnesbehov genom "resursbegäranden". CPU-resurser mäts i virtuella kärnor eller mer vanligt i "millicores", till exempel 500m innebär 50% vCPU. Minnesresurser mäts i byte, och vanliga suffix kan användas, till exempel 500Mi, vilket betyder 500 megabyte. Resursbegäran "lås" kapacitet på arbetarnoder, vilket innebär att en pod med en 1000 m CPU-begäran på en nod med 4 vCPU:er lämnar endast 3 vCPU:er tillgängliga för andra pods. [1]

Slack (överskottsreserv) är skillnaden mellan begärda resurser och faktisk användning. Till exempel, en pod som begär 2 GiB minne men bara använder 200 MiB har ~1,8 GiB "överskottsminne". Överskott kostar pengar. Man kan grovt uppskatta att 1 GiB redundant minne kostar ~$10 per månad. [2]

Kubernetes resursrapport (kube-resource-report) visar överskottsreserver och kan hjälpa dig att fastställa besparingspotential:

Spara på Kubernetes molnkostnader på AWS

Kubernetes resursrapport visar överskottet aggregerat efter applikation och kommando. Detta gör att du kan hitta platser där resurskraven kan minskas. Den genererade HTML-rapporten ger bara en ögonblicksbild av resursanvändning. Du bör titta på CPU/minnesanvändning över tid för att fastställa adekvata resursbegäranden. Här är ett Grafana-diagram för en "typisk" CPU-tung tjänst: alla pods använder betydligt mindre än de 3 begärda CPU-kärnorna:

Spara på Kubernetes molnkostnader på AWS

Att minska CPU-begäran från 3000m till ~400m frigör resurser för andra arbetsbelastningar och gör att klustret blir mindre.

"Genomsnittlig CPU-användning av EC2-instanser svävar ofta i det ensiffriga procentintervallet," skriver Corey Quinn. Medan för EC2 att uppskatta rätt storlek kan vara ett dåligt beslutAtt ändra vissa Kubernetes-resursfrågor i en YAML-fil är enkelt och kan ge stora besparingar.

Men vill vi verkligen att folk ändrar värden i YAML-filer? Nej, maskiner kan göra det mycket bättre! Kubernetes Vertical Pod Autoscaler (VPA) gör just det: anpassar resursbegäranden och begränsningar efter arbetsbelastningen. Här är en exempelgraf över Prometheus CPU-förfrågningar (tunn blå linje) anpassad av VPA över tiden:

Spara på Kubernetes molnkostnader på AWS

Zalando använder VPA i alla sina kluster för infrastrukturkomponenter. Icke-kritiska applikationer kan också använda VPA.

goldilocks från Fairwind är ett verktyg som skapar en VPA för varje distribution i ett namnområde och sedan visar en VPA-rekommendation på dess instrumentpanel. Det kan hjälpa utvecklare att ställa in rätt CPU/minnesförfrågningar för sina applikationer:

Spara på Kubernetes molnkostnader på AWS

Jag skrev en liten blogginlägg om VPA 2019, och nyligen in CNCF slutanvändargemenskap diskuterade VPA-frågan.

Använder EC2 Spot-instanser

Sist men inte minst kan AWS EC2-kostnaderna minskas genom att använda Spot-instanser som Kubernetes-arbetsnoder [3]. Spot-instanser är tillgängliga med en rabatt på upp till 90 % jämfört med On-Demand-priser. Att köra Kubernetes på EC2 Spot är en bra kombination: du måste ange flera olika instanstyper för högre tillgänglighet, vilket innebär att du kan få en större nod för samma eller lägre pris, och den ökade kapaciteten kan användas av containeriserade Kubernetes-arbetsbelastningar.

Hur kör man Kubernetes på EC2 Spot? Det finns flera alternativ: använd en tredjepartstjänst som SpotInst (nu kallad "Spot", fråga mig inte varför), eller helt enkelt lägg till en Spot AutoScalingGroup (ASG) till ditt kluster. Till exempel, här är ett CloudFormation-kodavsnitt för en "kapacitetsoptimerad" Spot ASG med flera 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"

Några anteckningar om att använda Spot med Kubernetes:

  • Du behöver hantera Spot-avslutningar, till exempel genom att slå samman noden när instansen stoppas
  • Zalando använder gaffel officiell klusterautoskalning med nodpoolprioriteringar
  • Spot noder kan tvingas acceptera "registreringar" av arbetsbelastningar som ska köras i Spot

Sammanfattning

Jag hoppas att du tycker att några av de verktyg som presenteras är användbara för att minska din molnräkning. Du hittar det mesta av artikelns innehåll också på mitt föredrag på DevOps Gathering 2019 på YouTube och i bilder.

Vilka är dina bästa metoder för att spara molnkostnader på Kubernetes? Vänligen meddela mig kl Twitter (@try_except_).

[1] Faktum är att mindre än 3 vCPU:er förblir användbara eftersom nodens genomströmning reduceras av reserverade systemresurser. Kubernetes skiljer mellan fysisk nodkapacitet och "tillhandahållna" resurser (Nodtilldelningsbar).

[2] Räkneexempel: en m5.stor instans med 8 GiB minne är ~$84 ​​per månad (eu-central-1, On-Demand), dvs. blockering av 1/8-nod är ungefär ~$10/månad.

[3] Det finns många fler sätt att minska din EC2-räkning, såsom reserverade tillfällen, sparplan, etc. - Jag kommer inte att ta upp de ämnena här, men du bör definitivt titta närmare på dem!

Läs mer om kursen.

Källa: will.com

Lägg en kommentar