Economisiți costurile cloud Kubernetes pe AWS

Traducerea articolului a fost pregătită în ajunul începerii cursului „Platformă de infrastructură bazată pe Kubernetes”.

Economisiți costurile cloud Kubernetes pe AWS

Cum să economisiți costurile cloud când lucrați cu Kubernetes? Nu există o singură soluție potrivită, dar acest articol descrie mai multe instrumente care vă pot ajuta să vă gestionați resursele mai eficient și să vă reduceți costurile de cloud computing.

Am scris acest articol având în vedere Kubernetes pentru AWS, dar se va aplica (aproape) exact în același mod și altor furnizori de cloud. Presupun că clusterele dvs. au deja configurată scalarea automată (cluster-autoscaler). Eliminarea resurselor și reducerea implementării dvs. vă vor economisi bani doar dacă vă reduce și flota de noduri de lucru (instanțe EC2).

Acest articol va acoperi:

Curățarea resurselor neutilizate

Lucrul într-un mediu cu ritm rapid este grozav. Vrem organizații tehnologice accelerat. Livrarea mai rapidă a software-ului înseamnă, de asemenea, mai multe implementări de PR, medii de previzualizare, prototipuri și soluții de analiză. Totul este implementat pe Kubernetes. Cine are timp să curețe manual implementările de testare? Este ușor să uiți de ștergerea unui experiment vechi de o săptămână. Factura de nor va ajunge să crească din cauza a ceva ce am uitat să închidem:

Economisiți costurile cloud Kubernetes pe AWS

(Henning Jacobs:
Zhiza:
(citate) Corey Quinn:
Mit: contul dvs. AWS este o funcție a numărului de utilizatori pe care îi aveți.
Realitate: scorul dvs. AWS este o funcție de numărul de ingineri pe care îi aveți.

Ivan Kurnosov (ca răspuns):
Fapt real: scorul dvs. AWS este o funcție a numărului de lucruri pe care ați uitat să le dezactivați/ștergeți.)

Serviciul Kubernetes (kube-janitor) vă ajută să vă curățați clusterul. Configurația janitor este flexibilă atât pentru uz global, cât și local:

  • Regulile la nivel de cluster pot defini durata maximă de viață (TTL) pentru implementările PR/test.
  • Resursele individuale pot fi adnotate cu janitor/ttl, de exemplu pentru a elimina automat vârful/prototipul după 7 zile.

Regulile generale sunt definite în fișierul YAML. Calea sa este trecută prin parametru --rules-file în kube-janitor. Iată un exemplu de regulă cu care să eliminați toate spațiile de nume -pr- în numele după două zile:

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

Următorul exemplu reglementează utilizarea etichetei aplicației pe podurile Deployment și StatefulSet pentru toate implementările/StatefulSets noi în 2020, dar în același timp permite executarea de teste fără această etichetă timp de o săptămână:

- 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

Rulați o demonstrație limitată în timp timp de 30 de minute pe un cluster care rulează kube-janitor:

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

O altă sursă de creștere a costurilor sunt volumele persistente (AWS EBS). Ștergerea unui Kubernetes StatefulSet nu șterge volumele sale persistente (PVC - PersistentVolumeClaim). Volumele EBS neutilizate pot duce cu ușurință la costuri de sute de dolari pe lună. Kubernetes Janitor are o funcție pentru curățarea PVC-urilor nefolosite. De exemplu, această regulă va elimina toate PVC-urile care nu sunt montate de un modul și care nu sunt referite de un StatefulSet sau CronJob:

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

Kubernetes Janitor vă poate ajuta să vă mențineți clusterul curat și să împiedicați creșterea lent a costurilor de cloud computing. Pentru instrucțiuni de instalare și configurare, urmați CITEȘTE-MĂ kube-janitor.

Reduceți decalarea în timpul orelor de lucru

Sistemele de testare și staging sunt de obicei necesare pentru funcționare numai în timpul programului de lucru. Unele aplicații de producție, cum ar fi instrumentele de back office/administrare, necesită, de asemenea, doar o disponibilitate limitată și pot fi dezactivate peste noapte.

Kubernetes Downscaler (kube-downscaler) permite utilizatorilor și operatorilor să reducă sistemul în timpul orelor de lucru. Implementările și StatefulSets se pot scala la zero replici. CronJobs poate fi suspendat. Kubernetes Downscaler este configurat pentru un întreg cluster, unul sau mai multe spații de nume sau resurse individuale. Puteți seta fie „timp inactiv”, fie, dimpotrivă, „timp de lucru”. De exemplu, pentru a reduce scalarea cât mai mult posibil în timpul nopții și în weekend:

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

Iată un grafic pentru scalarea nodurilor de lucru ale clusterului în weekend:

Economisiți costurile cloud Kubernetes pe AWS

Reducerea de la ~13 la 4 noduri de lucru face cu siguranță o diferență notabilă în factura dvs. AWS.

Dar ce se întâmplă dacă trebuie să lucrez în timpul „pausului” al clusterului? Anumite implementări pot fi excluse definitiv de la scalare prin adăugarea de downscaler/exclude: adnotare adevărată. Implementările pot fi excluse temporar utilizând adnotarea downscaler/exclude-until cu un marcaj temporal absolut în formatul AAAA-LL-ZZ HH:MM (UTC). Dacă este necesar, întregul cluster poate fi redus prin implementarea unui pod cu adnotarea downscaler/force-uptime, de exemplu, lansând 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

vedea README kube-downscaler, dacă sunteți interesat de instrucțiuni de implementare și opțiuni suplimentare.

Utilizați scalarea automată orizontală

Multe aplicații/servicii se confruntă cu un model de încărcare dinamică: uneori modulele lor sunt inactive, iar uneori funcționează la capacitate maximă. Operarea unei flote permanente de poduri pentru a face față sarcinii maxime de vârf nu este economică. Kubernetes acceptă scalarea automată orizontală într-o resursă HorizontalPodAutoscaler (HPA). Utilizarea procesorului este adesea un indicator bun pentru scalare:

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 a creat o componentă pentru a conecta cu ușurință valorile personalizate pentru scalare: Adaptor pentru metrici Kube (kube-metrics-adapter) este un adaptor de valori generice pentru Kubernetes care poate colecta și difuza valori personalizate și externe pentru scalarea automată orizontală a podurilor. Acceptă scalarea bazată pe valorile Prometheus, cozile SQS și alte setări. De exemplu, pentru a scala implementarea la o valoare personalizată reprezentată de aplicația însăși ca JSON în /metrics:

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

Configurarea autoscalingului orizontal cu HPA ar trebui să fie una dintre acțiunile implicite pentru a îmbunătăți eficiența serviciilor fără stat. Spotify are o prezentare cu experiența și recomandările lor pentru HPA: scalați-vă implementările, nu portofelul.

Reduceți suprarezervarea resurselor

Sarcinile de lucru Kubernetes își determină nevoile de CPU/memorie prin „cereri de resurse”. Resursele CPU sunt măsurate în nuclee virtuale sau, mai frecvent, în „milicore”, de exemplu 500m implică 50% vCPU. Resursele de memorie sunt măsurate în octeți și pot fi utilizate sufixe comune, cum ar fi 500Mi, ceea ce înseamnă 500 de megaocteți. Solicitările de resurse „blochează” capacitatea pe nodurile de lucru, ceea ce înseamnă că un pod cu o solicitare CPU de 1000 m pe un nod cu 4 vCPU-uri va lăsa doar 3 vCPU-uri disponibile altor poduri. [1]

Slack (rezervă în exces) este diferența dintre resursele solicitate și utilizarea reală. De exemplu, un pod care solicită 2 GiB de memorie, dar utilizează doar 200 MiB are ~1,8 GiB de memorie „în exces”. Excesul costă bani. Se poate estima aproximativ că 1 GiB de memorie redundantă costă ~10 USD pe lună. [2]

Raportul resurselor Kubernetes (kube-resource-report) afișează rezervele în exces și vă poate ajuta să determinați potențialul de economisire:

Economisiți costurile cloud Kubernetes pe AWS

Raportul resurselor Kubernetes arată excesul agregat după aplicație și comandă. Acest lucru vă permite să găsiți locuri în care cererile de resurse pot fi reduse. Raportul HTML generat oferă doar o imagine instantanee a utilizării resurselor. Ar trebui să vă uitați la utilizarea CPU/memoriei de-a lungul timpului pentru a determina cererile adecvate de resurse. Iată o diagramă Grafana pentru un serviciu „tipic” de CPU greoi: toate podurile folosesc semnificativ mai puțin decât cele 3 nuclee CPU solicitate:

Economisiți costurile cloud Kubernetes pe AWS

Reducerea cererii CPU de la 3000m la ~400m eliberează resurse pentru alte sarcini de lucru și permite cluster-ului să fie mai mic.

„Utilizarea medie a CPU a instanțelor EC2 se situează adesea în intervalul procentual de o singură cifră”, scrie Corey Quinn. În timp ce pentru EC2 estimarea dimensiunii corecte poate fi o decizie proastăModificarea unor interogări de resurse Kubernetes într-un fișier YAML este ușoară și poate aduce economii uriașe.

Dar vrem cu adevărat ca oamenii să schimbe valorile în fișierele YAML? Nu, mașinile o pot face mult mai bine! Kubernetes Autoscaler vertical Pod (VPA) face exact asta: adaptează cererile de resurse și constrângerile în funcție de volumul de muncă. Iată un exemplu de grafic al solicitărilor CPU Prometheus (linie albastră subțire) adaptate de VPA de-a lungul timpului:

Economisiți costurile cloud Kubernetes pe AWS

Zalando folosește VPA în toate clusterele sale pentru componentele infrastructurii. Aplicațiile necritice pot folosi și VPA.

Goldilocks de la Fairwind este un instrument care creează un VPA pentru fiecare implementare într-un spațiu de nume și apoi afișează o recomandare VPA pe tabloul de bord. Poate ajuta dezvoltatorii să stabilească cererile corecte pentru CPU/memorie pentru aplicațiile lor:

Economisiți costurile cloud Kubernetes pe AWS

Am scris un mic postare pe blog despre VPA în 2019, iar recent în Comunitatea utilizatorilor finali CNCF a discutat problema VPA.

Utilizarea instanțelor EC2 Spot

Nu în ultimul rând, costurile AWS EC2 pot fi reduse prin utilizarea instanțelor Spot ca noduri de lucru Kubernetes [3]. Instanțele spot sunt disponibile cu o reducere de până la 90% în comparație cu prețurile la cerere. Rularea Kubernetes pe EC2 Spot este o combinație bună: trebuie să specificați mai multe tipuri de instanțe diferite pentru o disponibilitate mai mare, ceea ce înseamnă că puteți obține un nod mai mare la același preț sau mai mic, iar capacitatea crescută poate fi utilizată de încărcăturile de lucru Kubernetes containerizate.

Cum să rulezi Kubernetes pe EC2 Spot? Există mai multe opțiuni: utilizați un serviciu terță parte, cum ar fi SpotInst (numit acum „Spot”, nu mă întrebați de ce) sau pur și simplu adăugați un Spot AutoScalingGroup (ASG) la clusterul dvs. De exemplu, iată un fragment CloudFormation pentru un Spot ASG „optimizat în funcție de capacitate” cu mai multe tipuri de instanțe:

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"

Câteva note despre utilizarea Spot cu Kubernetes:

  • Trebuie să gestionați terminările Spot, de exemplu prin îmbinarea nodului când instanța este oprită
  • Zalando folosește furculiţă scalarea automată a clusterului oficial cu prioritățile pool-ului de noduri
  • Spot noduri poate fi forțat acceptați „înregistrări” de sarcini de lucru pentru a rula în Spot

Rezumat

Sper să găsiți utile unele dintre instrumentele prezentate pentru a vă reduce factura de cloud. Puteți găsi majoritatea conținutului articolului și la discursul meu de la DevOps Gathering 2019 pe YouTube și în slide-uri.

Care sunt cele mai bune practici ale tale pentru economisirea costurilor cloud pe Kubernetes? Vă rog să-mi spuneți la Twitter (@try_except_).

[1] De fapt, mai puțin de 3 vCPU-uri vor rămâne utilizabile, deoarece debitul nodului este redus de resursele de sistem rezervate. Kubernetes face distincție între capacitatea nodului fizic și resursele „provizionate” (Nod alocabil).

[2] Exemplu de calcul: o instanță m5.large cu 8 GiB de memorie este de ~84 USD pe lună (eu-central-1, la cerere), adică. blocarea nodului 1/8 este de aproximativ ~10 USD/lună.

[3] Există multe alte modalități de a vă reduce factura EC2, cum ar fi Instanțele rezervate, Planul de economii etc. - Nu voi acoperi aceste subiecte aici, dar ar trebui neapărat să le analizați!

Aflați mai multe despre curs.

Sursa: www.habr.com

Adauga un comentariu