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).
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:
(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:
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:
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:
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:
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:
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:
Reduktion af CPU-anmodningen fra 3000m til ~400m frigør ressourcer til andre arbejdsbelastninger og tillader klyngen at være mindre.
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:
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:
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:
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!