Hvordan spare skykostnader når du jobber med Kubernetes? Det er ingen enkelt riktig løsning, men denne artikkelen beskriver flere verktøy som kan hjelpe deg med å administrere ressursene dine mer effektivt og redusere kostnadene for skydatabehandling.
Jeg skrev denne artikkelen med Kubernetes for AWS i tankene, men den vil gjelde (nesten) nøyaktig på samme måte for andre skyleverandører. Jeg antar at klyngene dine allerede har konfigurert automatisk skalering (cluster-autoscaler). Fjerning av ressurser og nedskalering av distribusjonen vil bare spare deg for penger hvis det også reduserer flåten av arbeidernoder (EC2-forekomster).
Å jobbe i et hektisk miljø er flott. Vi vil ha teknologiske organisasjoner akselerert. Raskere programvarelevering betyr også flere PR-distribusjoner, forhåndsvisningsmiljøer, prototyper og analyseløsninger. Alt er distribuert på Kubernetes. Hvem har tid til å rydde opp i testdistribusjoner manuelt? Det er lett å glemme å slette et ukegammelt eksperiment. Skyregningen vil ende opp på grunn av noe vi glemte å stenge:
(Henning Jacobs:
Zhiza:
(sitater) Corey Quinn:
Myte: AWS-kontoen din er en funksjon av antall brukere du har.
Fakta: Din AWS-poengsum er en funksjon av antall ingeniører du har.
Ivan Kurnosov (som svar):
Virkelig faktum: AWS-poengsummen din er en funksjon av antall ting du har glemt å deaktivere/slette.)
Kubernetes vaktmester (kube-janitor) hjelper til med å rydde opp i klyngen din. Vaktmesterkonfigurasjonen er fleksibel for både global og lokal bruk:
Regler for hele klyngen kan definere maksimal tid til å leve (TTL) for PR/test-distribusjoner.
Individuelle ressurser kan merkes med vaktmester/ttl, for eksempel for å automatisk fjerne piggen/prototypen etter 7 dager.
Generelle regler er definert i YAML-filen. Banen går gjennom parameteren --rules-file i kube-vaktmester. Her er en eksempelregel for å fjerne alle navneområder med -pr- i navnet etter to dager:
Følgende eksempel regulerer bruken av applikasjonsetiketten på Deployment- og StatefulSet-podene for alle nye Deployments/StatefulSets i 2020, men tillater samtidig utføring av tester uten denne etiketten i en uke:
- 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
Kjør en tidsbegrenset demo i 30 minutter på en klynge som kjører kube-janitor:
kubectl run nginx-demo --image=nginx
kubectl annotate deploy nginx-demo janitor/ttl=30m
En annen kilde til økende kostnader er vedvarende volumer (AWS EBS). Sletting av et Kubernetes StatefulSet sletter ikke dets vedvarende volumer (PVC - PersistentVolumeClaim). Ubrukte EBS-volumer kan lett resultere i kostnader på hundrevis av dollar per måned. Kubernetes Janitor har en funksjon for å rydde opp i ubrukte PVC-er. For eksempel vil denne regelen fjerne alle PVC-er som ikke er montert av en modul og som ikke er referert til av 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 hjelpe deg med å holde klyngen din ren og forhindre at kostnader for nettsky-databehandling langsomt hoper seg opp. Følg instruksjoner for distribusjon og konfigurasjon README kube-vaktmester.
Reduser skalering i ikke-arbeidstid
Test- og iscenesettelsessystemer er vanligvis pålagt å fungere bare i arbeidstiden. Noen produksjonsapplikasjoner, for eksempel backoffice/admin-verktøy, krever også bare begrenset tilgjengelighet og kan bli deaktivert over natten.
Kubernetes Downscaler (kube-downscaler) lar brukere og operatører skalere ned systemet i ikke-arbeidstid. Utrullinger og StatefulSets kan skaleres til null replikaer. CronJobs kan bli suspendert. Kubernetes Downscaler er konfigurert for en hel klynge, ett eller flere navneområder eller individuelle ressurser. Du kan stille inn enten "tomgang" eller omvendt "arbeidstid". For eksempel for å redusere skalering så mye som mulig i løpet av netter og 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
Her er en graf for skalering av klyngearbeidernoder i helgene:
Nedskalering fra ~13 til 4 arbeidernoder gjør absolutt en merkbar forskjell i AWS-regningen din.
Men hva om jeg trenger å jobbe under "nedetid" i klyngen? Enkelte distribusjoner kan ekskluderes permanent fra skalering ved å legge til nedskalering/ekskluder: sann annotering. Implementeringer kan midlertidig ekskluderes ved å bruke nedskalering/ekskluder-inntil-kommentaren med et absolutt tidsstempel i formatet ÅÅÅÅ-MM-DD TT:MM (UTC). Om nødvendig kan hele klyngen skaleres tilbake ved å distribuere en pod med merknaden downscaler/force-uptime, for eksempel ved å 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 interessert i distribusjonsinstruksjoner og tilleggsalternativer.
Bruk horisontal autoskalering
Mange applikasjoner/tjenester håndterer et dynamisk lastemønster: noen ganger er modulene deres inaktive, og noen ganger fungerer de med full kapasitet. Å drive en permanent flåte av pods for å takle maksimal toppbelastning er ikke økonomisk. Kubernetes støtter horisontal automatisk skalering på tvers av en ressurs HorizontalPodAutoscaler (HPA). CPU-bruk er ofte en god indikator for skalering:
Zalando har laget en komponent for enkelt å koble til egendefinerte beregninger for skalering: Kube Metrics Adapter (kube-metrics-adapter) er en generisk metrikkadapter for Kubernetes som kan samle inn og betjene tilpassede og eksterne beregninger for horisontal autoskalering av pods. Den støtter skalering basert på Prometheus-målinger, SQS-køer og andre innstillinger. For å skalere distribusjonen til en egendefinert beregning representert av selve applikasjonen som JSON i /metrics, bruk for eksempel:
Konfigurering av horisontal autoskalering med HPA bør være en av standardhandlingene for å forbedre effektiviteten for statsløse tjenester. Spotify har en presentasjon med deres erfaringer og anbefalinger for HPA: skaler distribusjonene dine, ikke lommeboken.
Reduser ressursoverbooking
Kubernetes-arbeidsbelastninger bestemmer deres CPU-/minnebehov gjennom «ressursforespørsler». CPU-ressurser måles i virtuelle kjerner eller mer vanlig i "millicores", for eksempel innebærer 500m 50 % vCPU. Minneressurser måles i byte, og vanlige suffikser kan brukes, for eksempel 500Mi, som betyr 500 megabyte. Ressurs forespørsler om å "låse" kapasitet på arbeidernoder, noe som betyr at en pod med en 1000m CPU-forespørsel på en node med 4 vCPUer vil la bare 3 vCPUer være tilgjengelige for andre pods. [1]
Slakk (overflødig reserve) er forskjellen mellom forespurte ressurser og faktisk bruk. For eksempel, en pod som ber om 2 GiB minne, men bare bruker 200 MiB, har ~1,8 GiB "overflødig" minne. Overskudd koster penger. Man kan grovt anslå at 1 GiB redundant minne koster ~$10 per måned. [2]
Kubernetes ressursrapport (kube-resource-report) viser overskuddsreserver og kan hjelpe deg med å bestemme sparepotensialet:
Kubernetes ressursrapport viser overskuddet aggregert etter applikasjon og kommando. Dette lar deg finne steder hvor ressursbehovet kan reduseres. Den genererte HTML-rapporten gir bare et øyeblikksbilde av ressursbruken. Du bør se på CPU/minnebruk over tid for å finne tilstrekkelige ressursforespørsler. Her er et Grafana-diagram for en "typisk" CPU-tung tjeneste: alle pods bruker betydelig mindre enn de tre forespurte CPU-kjernene:
Å redusere CPU-forespørselen fra 3000m til ~400m frigjør ressurser for andre arbeidsbelastninger og gjør at klyngen blir mindre.
Men vil vi virkelig at folk skal endre verdier i YAML-filer? Nei, maskiner kan gjøre det mye bedre! Kubernetes Vertical Pod Autoscaler (VPA) gjør nettopp det: tilpasser ressursforespørsler og begrensninger i henhold til arbeidsmengden. Her er en eksempelgraf over Prometheus CPU-forespørsler (tynn blå linje) tilpasset av VPA over tid:
Goldilocks fra Fairwind er et verktøy som oppretter en VPA for hver distribusjon i et navneområde og deretter viser en VPA-anbefaling på dashbordet. Det kan hjelpe utviklere med å angi de riktige CPU-/minneforespørslene for applikasjonene deres:
Sist men ikke minst kan AWS EC2-kostnadene reduseres ved å bruke Spot-instanser som Kubernetes-arbeidernoder [3]. Spot-forekomster er tilgjengelig med en rabatt på opptil 90 % sammenlignet med On-Demand-priser. Å kjøre Kubernetes på EC2 Spot er en god kombinasjon: du må spesifisere flere forskjellige instanstyper for høyere tilgjengelighet, noe som betyr at du kan få en større node for samme eller lavere pris, og den økte kapasiteten kan brukes av containeriserte Kubernetes-arbeidsbelastninger.
Hvordan kjører jeg Kubernetes på EC2 Spot? Det er flere alternativer: bruk en tredjepartstjeneste som SpotInst (nå kalt "Spot", ikke spør meg hvorfor), eller bare legg til en Spot AutoScalingGroup (ASG) til klyngen din. For eksempel, her er en CloudFormation-kodebit for en "kapasitetsoptimalisert" Spot ASG med flere forekomsttyper:
Hva er dine beste fremgangsmåter for å spare skykostnader på Kubernetes? Gi meg beskjed kl Twitter (@try_except_).
[1] Faktisk vil mindre enn 3 vCPUer forbli brukbare ettersom nodens gjennomstrømning reduseres av reserverte systemressurser. Kubernetes skiller mellom fysisk nodekapasitet og "forsynte" ressurser (Node allokerbar).
[2] Regneeksempel: én m5.stor instans med 8 GiB minne er ~$84 per måned (eu-central-1, On-Demand), dvs. blokkering av 1/8 node er omtrent ~$10/måned.
[3] Det er mange flere måter å redusere EC2-regningen på, for eksempel reserverte forekomster, spareplan osv. - Jeg vil ikke dekke disse emnene her, men du bør definitivt se nærmere på dem!