Säästä Kubernetes-pilvikustannuksissa AWS:ssä

Artikkelin käännös valmistettiin kurssin alkamisen aattona "Kubernetesiin perustuva infrastruktuurialusta".

Säästä Kubernetes-pilvikustannuksissa AWS:ssä

Kuinka säästää pilvikustannuksissa, kun työskentelet Kubernetesin kanssa? Ei ole olemassa yhtä oikeaa ratkaisua, mutta tässä artikkelissa kuvataan useita työkaluja, jotka voivat auttaa sinua hallitsemaan resurssejasi tehokkaammin ja vähentämään pilvipalvelun kustannuksia.

Kirjoitin tämän artikkelin Kubernetes for AWS:lle mielessä, mutta se koskee (melkein) täsmälleen samalla tavalla muita pilvipalveluntarjoajia. Oletan, että klustereissasi on jo määritetty automaattinen skaalaus (cluster-autoscaler). Resurssien poistaminen ja käyttöönoton pienentäminen säästää rahaa vain, jos se myös vähentää työntekijöiden solmujen määrää (EC2-esiintymät).

Tämä artikkeli kattaa:

  • käyttämättömien resurssien siivoaminen (kube-siivooja)
  • Vähennä skaalausta työajan ulkopuolella (kube-downscaler)
  • käyttämällä horisontaalista automaattista skaalausta (HPA),
  • liiallisen resurssivarauksen vähentäminen (kube-resurssi-raportti, VPA)
  • Spot-instanssien avulla

Käyttämättömien resurssien siivoaminen

Työskentely nopeatempoisessa ympäristössä on hienoa. Haluamme teknologiaorganisaatioita kiihdytetty. Nopeampi ohjelmistotoimitus tarkoittaa myös enemmän PR-käyttöönottoa, esikatseluympäristöjä, prototyyppejä ja analytiikkaratkaisuja. Kaikki on otettu käyttöön Kubernetesissa. Kenellä on aikaa puhdistaa testikäyttöönotot manuaalisesti? Viikon vanhan kokeilun poistaminen on helppo unohtaa. Pilvilasku nousee lopulta johtuen jostakin, jonka unohdimme sulkea:

Säästä Kubernetes-pilvikustannuksissa AWS:ssä

(Henning Jacobs:
Zhiza:
(lainauksia) Corey Quinn:
Myytti: AWS-tilisi on funktio käyttäjien määrästä.
Fakta: AWS-pisteesi on funktio insinöörien lukumäärästä.

Ivan Kurnosov (vastauksena):
Tosiasia: AWS-pisteesi on funktio niiden asioiden määrästä, jotka unohdit poistaa käytöstä/poistaa.)

Kubernetes talonmies (kube-janitor) auttaa puhdistamaan klusterin. Talonmieskokoonpano on joustava sekä globaaliin että paikalliseen käyttöön:

  • Klusterinlaajuiset säännöt voivat määrittää maksimiajan (TTL) PR/testikäyttöönottoa varten.
  • Yksittäisiä resursseja voidaan merkitä janitor/ttl:llä, esimerkiksi piikki/prototyypin poistamiseksi automaattisesti 7 päivän kuluttua.

Yleiset säännöt on määritelty YAML-tiedostossa. Sen polku kulkee parametrin läpi --rules-file kube-siivoojassa. Tässä on esimerkkisääntö kaikkien nimiavaruuksien poistamiseksi -pr- nimessä kahden päivän kuluttua:

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

Seuraava esimerkki säätelee sovellustunnisteen käyttöä Deployment- ja StatefulSet-tyypeissä kaikissa uusissa Deployments/StatefulSetsissä vuonna 2020, mutta sallii samalla testien suorittamisen ilman tätä tunnistetta viikon ajan:

- 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

Suorita aikarajoitettu demo 30 minuutin ajan klusterissa, jossa on käynnissä kube-janitor:

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

Toinen kustannusten kasvun lähde ovat jatkuvat volyymit (AWS EBS). Kubernetes StatefulSetin poistaminen ei poista sen pysyviä taltioita (PVC - PersistentVolumeClaim). Käyttämättömät EBS-volyymit voivat helposti johtaa satojen dollarien kustannuksiin kuukaudessa. Kubernetes Janitorissa on ominaisuus käyttämättömien PVC:iden puhdistamiseen. Tämä sääntö esimerkiksi poistaa kaikki PVC:t, joita ei ole asennettu moduuliin ja joihin StatefulSet tai CronJob ei viittaa:

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

Kubernetes Janitor voi auttaa sinua pitämään klusterin puhtaana ja ehkäisemään pilvipalveluiden kustannusten hidasta kasaantumista. Katso käyttöönotto- ja määritysohjeet README kube-siivooja.

Vähennä skaalausta työajan ulkopuolella

Testaus- ja vaiheistusjärjestelmien on yleensä toimittava vain virka-aikoina. Jotkut tuotantosovellukset, kuten back office/admin -työkalut, vaativat myös vain rajoitetun saatavuuden, ja ne voidaan poistaa käytöstä yön yli.

Kubernetes Downscaler (kube-downscaler) mahdollistaa käyttäjien ja operaattorien pienentämisen järjestelmän työajan ulkopuolella. Käyttöönotot ja StatefulSets voivat skaalata nollaan replikoihin. CronJobs voidaan jäädyttää. Kubernetes Downscaler on määritetty koko klusteria, yhtä tai useampaa nimiavaruutta tai yksittäisiä resursseja varten. Voit asettaa joko "tyhjäkäyntiajan" tai päinvastoin "työajan". Voit esimerkiksi vähentää hilseilyä niin paljon kuin mahdollista öisin ja viikonloppuisin:

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

Tässä on kaavio klusterin työntekijäsolmujen skaalaamisesta viikonloppuisin:

Säästä Kubernetes-pilvikustannuksissa AWS:ssä

Skaalaus noin 13:sta 4 työntekijäsolmuun tekee varmasti huomattavan eron AWS-laskussasi.

Mutta entä jos minun on työskenneltävä klusterin "seisokkien" aikana? Tietyt käyttöönotot voidaan sulkea pysyvästi pois skaalauksesta lisäämällä downscaler/exclude: true -merkintä. Käyttöönotot voidaan tilapäisesti sulkea pois käyttämällä alennusta/poissulkemis-kunnes -merkintää absoluuttisella aikaleimalla muodossa VVVV-KK-PP TT:MM (UTC). Tarvittaessa koko klusteri voidaan skaalata takaisin ottamalla käyttöön merkintä downscaler/force-uptimeesimerkiksi käynnistämällä 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

Nähdä README kube-downscaler, jos olet kiinnostunut käyttöönotto-ohjeista ja lisävaihtoehdoista.

Käytä vaakasuuntaista automaattista skaalausta

Monet sovellukset/palvelut käsittelevät dynaamista latauskuviota: joskus niiden moduulit ovat tyhjäkäynnillä ja joskus ne toimivat täydellä kapasiteetilla. Pysyvän kaluston käyttäminen suurimman huippukuorman selvittämiseksi ei ole taloudellista. Kubernetes tukee horisontaalista automaattista skaalausta resurssin yli HorizontalPodAutoscaler (HPA). Prosessorin käyttö on usein hyvä skaalausmittari:

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 on luonut komponentin, joka yhdistää helposti mukautettuja mittareita skaalausta varten: Kube Metrics -sovitin (kube-metrics-adapter) on yleinen metriikkasovitin Kubernetesille, joka voi kerätä ja palvella mukautettuja ja ulkoisia mittareita podien vaakasuuntaista automaattista skaalausta varten. Se tukee Prometheus-mittareihin, SQS-jonoihin ja muihin asetuksiin perustuvaa skaalausta. Jos haluat esimerkiksi skaalata käyttöönoton mukautettuun mittariin, jonka sovellus itse edustaa JSON-muodossa /metrics-kohdassa, käytä:

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

Horisontaalisen automaattisen skaalauksen määrittämisen HPA:lla tulisi olla yksi oletustoimista tilattomien palveluiden tehokkuuden parantamiseksi. Spotifylla on esittely heidän kokemuksistaan ​​ja suosituksistaan ​​HPA:lle: skaalata käyttöönottojasi, ei lompakkoasi.

Vähennä resurssien ylivarausta

Kubernetes-työkuormat määrittävät suorittimen/muistin tarpeet "resurssipyyntöjen" kautta. Prosessoriresurssit mitataan virtuaalisilla ytimillä tai yleisemmin "milliytimillä", esimerkiksi 500 m tarkoittaa 50 % vCPU:ta. Muistiresurssit mitataan tavuissa ja voidaan käyttää yleisiä jälkiliitteitä, kuten 500Mi, mikä tarkoittaa 500 megatavua. Resurssipyynnöt "lukitsevat" työntekijäsolmujen kapasiteetin, mikä tarkoittaa, että pod, jossa on 1000 4 metrin prosessoripyyntö solmussa, jossa on 3 vCPU:ta, jättää vain XNUMX vCPU:ta muiden podien käyttöön. [1]

löysä (ylimääräinen varaus) on ero pyydettyjen resurssien ja todellisen käytön välillä. Esimerkiksi pod, joka pyytää 2 GiB muistia mutta käyttää vain 200 MiB, sisältää ~1,8 GiB "ylimääräistä" muistia. Ylimääräinen maksaa rahaa. Voidaan karkeasti arvioida, että 1 GiB redundanttia muistia maksaa ~10 dollaria kuukaudessa. [2]

Kubernetes Resource Report (kube-resource-report) näyttää ylimääräiset varaukset ja voi auttaa sinua määrittämään säästömahdollisuudet:

Säästä Kubernetes-pilvikustannuksissa AWS:ssä

Kubernetes Resource Report näyttää ylijäämän sovelluksen ja komennon mukaan. Näin voit löytää paikkoja, joissa resurssien tarvetta voidaan vähentää. Luotu HTML-raportti tarjoaa vain tilannekuvan resurssien käytöstä. Sinun tulisi tarkastella suorittimen/muistin käyttöä ajan mittaan, jotta voit määrittää riittävät resurssipyynnöt. Tässä on Grafana-kaavio "tyypillisestä" prosessoriraskasta palvelusta: kaikki podit käyttävät huomattavasti vähemmän kuin kolme pyydettyä suorittimen ydintä:

Säästä Kubernetes-pilvikustannuksissa AWS:ssä

Suorittimen pyynnön pienentäminen 3000 400 metristä ~ XNUMX metriin vapauttaa resursseja muihin työkuormiin ja mahdollistaa klusterin pienentymisen.

"EC2-esiintymien keskimääräinen suorittimen käyttö on usein yksinumeroisten prosenttiosuuksien alueella." kirjoittaa Corey Quinn. Vaikka EC2:lle oikean koon arvioiminen voi olla huono päätösJoidenkin Kubernetes-resurssikyselyiden muuttaminen YAML-tiedostossa on helppoa ja voi tuoda valtavia säästöjä.

Mutta haluammeko todella, että ihmiset muuttavat arvoja YAML-tiedostoissa? Ei, koneet voivat tehdä sen paljon paremmin! Kubernetes Vertical Pod Autoscaler (VPA) tekee juuri sen: mukauttaa resurssipyynnöt ja rajoitukset työmäärän mukaan. Tässä on esimerkkikaavio Prometheus-suoritinpyynnöistä (ohut sininen viiva), jotka VPA on mukauttanut ajan myötä:

Säästä Kubernetes-pilvikustannuksissa AWS:ssä

Zalando käyttää VPA:ta kaikissa klustereissaan infrastruktuurikomponenteille. Ei-kriittiset sovellukset voivat myös käyttää VPA:ta.

Kultakutri Fairwindistä on työkalu, joka luo VPA:n jokaiselle käyttöönotolle nimiavaruudessa ja näyttää sitten VPA-suosituksen kojelautassaan. Se voi auttaa kehittäjiä asettamaan oikeat suoritin-/muistipyynnöt sovelluksilleen:

Säästä Kubernetes-pilvikustannuksissa AWS:ssä

Kirjoitin pienen blogikirjoitus VPA:sta vuonna 2019 ja äskettäin CNCF-loppukäyttäjäyhteisö keskusteli VPA-ongelmasta.

EC2-pisteinstanssien käyttäminen

Viimeisenä mutta ei vähäisimpänä, AWS EC2:n kustannuksia voidaan vähentää käyttämällä Spot-esiintymiä Kubernetes-työntekijäsolmuina [3]. Spot-instanssit ovat saatavilla jopa 90 % alennuksella on-Demand-hintoihin verrattuna. Kubernetesin käyttäminen EC2 Spotissa on hyvä yhdistelmä: sinun on määritettävä useita eri ilmentymätyyppejä korkeamman käytettävyyden saavuttamiseksi, mikä tarkoittaa, että voit saada suuremman solmun samalla tai halvemmalla hinnalla, ja lisääntynyttä kapasiteettia voidaan käyttää konteitettuihin Kubernetes-työkuormiin.

Kuinka ajaa Kubernetes EC2 Spotissa? Vaihtoehtoja on useita: käytä kolmannen osapuolen palvelua, kuten SpotInstiä (nyt nimeltään "Spot", älä kysy minulta miksi) tai lisää vain Spot AutoScalingGroup (ASG) klusteriisi. Tässä on esimerkiksi CloudFormation-koodinpätkä "kapasiteettioptimoidulle" Spot ASG:lle, jossa on useita esiintymätyyppejä:

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"

Muutamia huomautuksia Spotin käytöstä Kubernetesin kanssa:

  • Sinun on käsiteltävä Spot-päätyksiä, esimerkiksi yhdistämällä solmu, kun ilmentymä pysäytetään
  • Zalando käyttää haarukka virallinen klusterin automaattinen skaalaus solmuvarannon prioriteeteilla
  • Paikalliset solmut voidaan pakottaa hyväksy työkuormien "rekisteröinnit" suoritettavaksi Spotissa

Yhteenveto

Toivon, että joistakin esitetyistä työkaluista on hyötyä pilvilaskujen vähentämisessä. Löydät suurimman osan artikkelin sisällöstä myös osoitteesta puheeni DevOps Gathering 2019 -tapahtumassa YouTubessa ja dioissa.

Mitkä ovat parhaat käytännöt pilvikulujen säästämiseksi Kubernetesissa? Kerro minulle osoitteessa Twitter (@try_except_).

[1] Itse asiassa alle 3 vCPU:ta jää käyttökelpoiseksi, koska varatut järjestelmäresurssit vähentävät solmun suorituskykyä. Kubernetes tekee eron fyysisen solmukapasiteetin ja "varattujen" resurssien välillä (Solmu allokoitavissa).

[2] Laskuesimerkki: yksi m5.large instanssi 8 GiB muistilla on ~84$ kuukaudessa (eu-central-1, On-Demand), ts. 1/8-solmun estäminen on noin ~10 dollaria/kk.

[3] On monia muita tapoja pienentää EC2-laskuasi, kuten varatut tapaukset, säästösuunnitelma jne. - En käsittele näitä aiheita tässä, mutta sinun tulee ehdottomasti tutustua niihin!

Lue lisää kurssista.

Lähde: will.com

Lisää kommentti