Risparmia sui costi del cloud Kubernetes su AWS

La traduzione dell'articolo è stata preparata alla vigilia dell'inizio del corso "Piattaforma infrastrutturale basata su Kubernetes".

Risparmia sui costi del cloud Kubernetes su AWS

Come risparmiare sui costi del cloud quando si lavora con Kubernetes? Non esiste un'unica soluzione giusta, ma questo articolo descrive diversi strumenti che possono aiutarti a gestire le tue risorse in modo più efficace e a ridurre i costi del cloud computing.

Ho scritto questo articolo pensando a Kubernetes per AWS, ma si applicherà (quasi) esattamente allo stesso modo ad altri provider cloud. Presumo che i tuoi cluster abbiano già configurato la scalabilità automatica (scalabilità automatica del cluster). La rimozione delle risorse e la riduzione della distribuzione ti faranno risparmiare denaro solo se ridurranno anche la tua flotta di nodi di lavoro (istanze EC2).

Questo articolo tratterà:

  • ripulire le risorse inutilizzate (kube-custode)
  • Ridurre il ridimensionamento durante le ore non lavorative (kube-downscaler)
  • utilizzando la scalabilità automatica orizzontale (HPA),
  • riduzione della prenotazione eccessiva di risorse (kube-resource-report, VPA)
  • utilizzando le istanze Spot

Ripulire le risorse inutilizzate

Lavorare in un ambiente frenetico è fantastico. Vogliamo organizzazioni tecnologiche accelerato. Una distribuzione più rapida del software significa anche più implementazioni di PR, ambienti di anteprima, prototipi e soluzioni di analisi. Tutto è distribuito su Kubernetes. Chi ha il tempo per ripulire manualmente le distribuzioni di test? È facile dimenticare di eliminare un esperimento vecchio di una settimana. La bolletta del cloud finirà per aumentare a causa di qualcosa che abbiamo dimenticato di chiudere:

Risparmia sui costi del cloud Kubernetes su AWS

(Henning Jacobs:
Ziza:
(citazioni) Corey Quinn:
Mito: il tuo account AWS dipende dal numero di utenti che hai.
Fatto: il tuo punteggio AWS dipende dal numero di ingegneri che hai.

Ivan Kurnosov (in risposta):
Fatto reale: il tuo punteggio AWS è una funzione del numero di cose che hai dimenticato di disabilitare/eliminare.)

Inserviente Kubernetes (kube-janitor) aiuta a ripulire il tuo cluster. La configurazione del bidello è flessibile sia per l'uso globale che locale:

  • Le regole a livello di cluster possono definire il time-to-live (TTL) massimo per le distribuzioni PR/test.
  • Le singole risorse possono essere annotate con janitor/ttl, ad esempio per rimuovere automaticamente lo spike/prototipo dopo 7 giorni.

Le regole generali sono definite nel file YAML. Il suo percorso viene passato attraverso il parametro --rules-file in kube-bidello. Ecco una regola di esempio con cui rimuovere tutti gli spazi dei nomi -pr- nel nome dopo due giorni:

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

L'esempio seguente regola l'utilizzo dell'etichetta dell'applicazione sui pod Deployment e StatefulSet per tutti i nuovi Deployment/StatefulSet nel 2020, ma allo stesso tempo consente l'esecuzione di test senza tale etichetta per una settimana:

- 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

Esegui una demo a tempo limitato per 30 minuti su un cluster che esegue kube-janitor:

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

Un’altra fonte di aumento dei costi sono i volumi persistenti (AWS EBS). L'eliminazione di un Kubernetes StatefulSet non elimina i suoi volumi persistenti (PVC - PersistentVolumeClaim). I volumi EBS inutilizzati possono facilmente comportare costi di centinaia di dollari al mese. Kubernetes Janitor ha una funzionalità per ripulire i PVC inutilizzati. Ad esempio, questa regola rimuoverà tutti i PVC che non sono montati da un modulo e a cui non fa riferimento uno StatefulSet o un CronJob:

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

Kubernetes Janitor può aiutarti a mantenere il tuo cluster pulito e a evitare che i costi del cloud computing si accumulino lentamente. Per le istruzioni di distribuzione e configurazione, seguire LEGGIMI kube-janitor.

Ridurre il ridimensionamento durante le ore non lavorative

I sistemi di test e di gestione temporanea devono in genere funzionare solo durante l'orario lavorativo. Anche alcune applicazioni di produzione, come gli strumenti di back office/amministrazione, richiedono solo una disponibilità limitata e potrebbero essere disabilitate dall'oggi al domani.

Downscaler Kubernetes (kube-downscaler) consente agli utenti e agli operatori di ridimensionare il sistema durante gli orari non lavorativi. Le distribuzioni e gli StatefulSet possono scalare fino a zero repliche. CronJobs potrebbe essere sospeso. Kubernetes Downscaler è configurato per un intero cluster, uno o più spazi dei nomi o singole risorse. È possibile impostare il "tempo di inattività" o, al contrario, il "tempo di lavoro". Ad esempio, per ridurre il più possibile il ridimensionamento durante le ore notturne e nei fine settimana:

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

Ecco un grafico per il dimensionamento dei nodi di lavoro del cluster nei fine settimana:

Risparmia sui costi del cloud Kubernetes su AWS

La riduzione da circa 13 a 4 nodi di lavoro fa sicuramente una notevole differenza nella fattura AWS.

Ma cosa succede se devo lavorare durante i "tempi di inattività" del cluster? Alcune distribuzioni possono essere escluse permanentemente dalla scalabilità aggiungendo l'annotazione downscaler/exclude: true. Le distribuzioni possono essere temporaneamente escluse utilizzando l'annotazione downscaler/exclude-until con un timestamp assoluto nel formato AAAA-MM-GG HH:MM (UTC). Se necessario, l'intero cluster può essere ridotto distribuendo un pod con l'annotazione downscaler/force-uptime, ad esempio, avviando 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

vedere README kube-downscaler, se sei interessato alle istruzioni di distribuzione e alle opzioni aggiuntive.

Utilizza la scalabilità automatica orizzontale

Molte applicazioni/servizi hanno un modello di caricamento dinamico: a volte i loro moduli sono inattivi, a volte funzionano a pieno regime. Gestire una flotta permanente di pod per far fronte ai picchi di carico massimi non è economico. Kubernetes supporta la scalabilità automatica orizzontale in una risorsa OrizzontalePodAutoscaler (HPA). L'utilizzo della CPU è spesso un buon indicatore della scalabilità:

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 ha creato un componente per connettere facilmente le metriche personalizzate per lo scaling: Adattatore per metriche Kube (kube-metrics-adapter) è un adattatore di parametri generico per Kubernetes in grado di raccogliere e fornire parametri personalizzati ed esterni per la scalabilità automatica orizzontale dei pod. Supporta il ridimensionamento basato su parametri Prometheus, code SQS e altre impostazioni. Ad esempio, per adattare la distribuzione a un parametro personalizzato rappresentato dall'applicazione stessa come JSON in /metrics utilizzare:

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

La configurazione della scalabilità automatica orizzontale con HPA dovrebbe essere una delle azioni predefinite per migliorare l'efficienza dei servizi stateless. Spotify ha una presentazione con la loro esperienza e consigli per HPA: scala le tue implementazioni, non il tuo portafoglio.

Riduci l'overbooking delle risorse

I carichi di lavoro Kubernetes determinano le proprie esigenze di CPU/memoria tramite "richieste di risorse". Le risorse della CPU sono misurate in core virtuali o più comunemente in “millicore”, ad esempio 500m implica il 50% di vCPU. Le risorse di memoria sono misurate in byte e possono essere utilizzati suffissi comuni, come 500Mi, che significa 500 megabyte. Le richieste di risorse "bloccano" la capacità sui nodi di lavoro, il che significa che un pod con una richiesta di 1000 m di CPU su un nodo con 4 vCPU lascerà solo 3 vCPU disponibili per gli altri pod. ,

Lasco (riserva in eccesso) è la differenza tra le risorse richieste e l'utilizzo effettivo. Ad esempio, un pod che richiede 2 GiB di memoria ma utilizza solo 200 MiB ha circa 1,8 GiB di memoria "in eccesso". L’eccesso costa denaro. Si può stimare approssimativamente che 1 GiB di memoria ridondante costi circa $ 10 al mese. ,

Rapporto sulle risorse Kubernetes (kube-resource-report) mostra le riserve in eccesso e può aiutarti a determinare il potenziale di risparmio:

Risparmia sui costi del cloud Kubernetes su AWS

Rapporto sulle risorse Kubernetes mostra l'eccedenza aggregata per applicazione e comando. Ciò consente di trovare luoghi in cui è possibile ridurre la richiesta di risorse. Il report HTML generato fornisce solo un'istantanea dell'utilizzo delle risorse. Dovresti esaminare l'utilizzo della CPU/memoria nel tempo per determinare le richieste di risorse adeguate. Ecco un grafico Grafana per un servizio "tipico" con uso intensivo della CPU: tutti i pod utilizzano molto meno dei 3 core CPU richiesti:

Risparmia sui costi del cloud Kubernetes su AWS

La riduzione della richiesta di CPU da 3000 a circa 400 milioni libera risorse per altri carichi di lavoro e consente al cluster di essere più piccolo.

"L'utilizzo medio della CPU delle istanze EC2 spesso si aggira nell'intervallo percentuale a una cifra," scrive Corey Quinn. Mentre per EC2 stimare la taglia giusta potrebbe essere una decisione sbagliataLa modifica di alcune query sulle risorse Kubernetes in un file YAML è semplice e può comportare enormi risparmi.

Ma vogliamo davvero che le persone cambino i valori nei file YAML? No, le macchine possono farlo molto meglio! Kubernetes Scalatore automatico pod verticale (VPA) fa proprio questo: adatta le richieste e i vincoli delle risorse in base al carico di lavoro. Ecco un grafico di esempio delle richieste della CPU Prometheus (sottile linea blu) adattato da VPA nel tempo:

Risparmia sui costi del cloud Kubernetes su AWS

Zalando utilizza VPA in tutti i suoi cluster per i componenti dell'infrastruttura. Anche le applicazioni non critiche possono utilizzare VPA.

Goldilocks di Fairwind è uno strumento che crea un VPA per ogni distribuzione in uno spazio dei nomi e quindi visualizza una raccomandazione VPA sulla sua dashboard. Può aiutare gli sviluppatori a impostare le richieste corrette di CPU/memoria per le loro applicazioni:

Risparmia sui costi del cloud Kubernetes su AWS

Ho scritto un piccolo post sul blog su VPA nel 2019 e recentemente nel La comunità degli utenti finali CNCF ha discusso della questione VPA.

Utilizzo delle istanze Spot EC2

Ultimo ma non meno importante, i costi di AWS EC2 possono essere ridotti utilizzando le istanze Spot come nodi di lavoro Kubernetes ,. Le istanze Spot sono disponibili con uno sconto fino al 90% rispetto ai prezzi on-demand. L'esecuzione di Kubernetes su EC2 Spot è una buona combinazione: è necessario specificare diversi tipi di istanze per una maggiore disponibilità, il che significa che è possibile ottenere un nodo più grande allo stesso prezzo o a un prezzo inferiore e la maggiore capacità può essere utilizzata dai carichi di lavoro Kubernetes containerizzati.

Come eseguire Kubernetes su EC2 Spot? Esistono diverse opzioni: utilizzare un servizio di terze parti come SpotInst (ora chiamato "Spot", non chiedermi perché) o semplicemente aggiungere uno Spot AutoScalingGroup (ASG) al tuo cluster. Ad esempio, ecco uno snippet di CloudFormation per un ASG Spot "ottimizzato in termini di capacità" con più tipi di istanza:

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"

Alcune note sull'utilizzo di Spot con Kubernetes:

  • È necessario gestire le terminazioni Spot, ad esempio unendo il nodo quando l'istanza viene arrestata
  • Zalando utilizza forchetta scalabilità automatica ufficiale del cluster con priorità del pool di nodi
  • Nodi individuati può essere forzato accettare "registrazioni" di carichi di lavoro da eseguire in Spot

Riassunto

Spero che troverai alcuni degli strumenti presentati utili per ridurre la bolletta del cloud. Puoi trovare la maggior parte dei contenuti dell'articolo anche su il mio intervento al DevOps Gathering 2019 su YouTube e in diapositive.

Quali sono le vostre best practice per risparmiare sui costi del cloud su Kubernetes? Per favore fatemelo sapere a Twitter (@provare_eccetto_).

, Rimarranno infatti utilizzabili meno di 3 vCPU poiché il throughput del nodo viene ridotto dalle risorse di sistema riservate. Kubernetes distingue tra capacità del nodo fisico e risorse "provisionate" (Nodo allocabile).

, Esempio di calcolo: un'istanza m5.large con 8 GiB di memoria costa ~$84 ​​​​al mese (eu-central-1, On-Demand), ovvero bloccare 1/8 di nodo costa circa ~$10 al mese.

, Esistono molti altri modi per ridurre la bolletta EC2, come le Istanze riservate, il Piano di risparmio, ecc. - Non tratterò questi argomenti qui, ma dovresti assolutamente esaminarli!

Scopri di più sul corso.

Fonte: habr.com

Aggiungi un commento