Эканомім на хмарных выдатках Kubernetes на AWS

Пераклад артыкула падрыхтаваны напярэдадні старту курса "Інфраструктурная платформа на аснове Kubernetes".

Эканомім на хмарных выдатках Kubernetes на AWS

Як зэканоміць на хмарных выдатках пры працы з Kubernetes? Адзіна правільнага рашэння не існуе, але ў гэтым артыкуле апісана некалькі інструментаў, якія дапамогуць вам больш эфектыўна кіраваць рэсурсамі і скараціць выдаткі на хмарныя вылічэнні.

Я напісаў гэты артыкул з аглядкай на Kubernetes для AWS, але яна будзе дастасавальная (амаль) сапраўды гэтак жа і для іншых хмарных правайдэраў. Я мяркую, што ваш кластар(ы) ужо мае настроенае аўтаматычнае маштабаванне (cluster-autoscaler). Выдаленне рэсурсаў і памяншэнне маштабу разгортвання дазволіць зэканоміць толькі ў тым выпадку, калі гэта таксама скароціць ваш парк працоўных вузлоў (EC2 інстансаў).

У гэтым артыкуле будуць разгледжаны:

  • ачыстка невыкарыстоўваных рэсурсаў (kube-janitor)
  • памяншэнне маштабавання ў непрацоўны час (kube-downscaler)
  • выкарыстанне гарызантальнага аўтамаштабавання (HPA),
  • памяншэнне залішняга рэзервавання рэсурсаў (kube-resource-report, VPA)
  • выкарыстанне Spot інстансаў

Ачыстка невыкарыстоўваных рэсурсаў

Праца ў хутка якое змяняецца асяроддзі - гэта выдатна. Мы хочам, каб тэхнічныя арганізацыі паскараліся. Больш хуткая дастаўка праграмнага забеспячэння таксама азначае большую колькасць PR-разгортванняў, асяроддзяў папярэдняга прагляду, прататыпаў і аналітычных рашэнняў. Усё разгортваецца на Kubernetes. У каго ёсць час, каб чысціць тэставыя разгортванні ўручную? Лёгка забыцца аб выдаленні эксперыменту тыднёвай даўнасці. Рахунак за воблака ў канчатковым выніку будзе расці з-за таго, што мы забыліся закрыць:

Эканомім на хмарных выдатках Kubernetes на AWS

(Хеннінг Джэйкабс:
Жыза:
(цытуе) Коры Куін:
Міф: Ваш AWS рахунак - гэта функцыя залежнасці ад колькасці вашых карыстальнікаў.
Факт: Ваш AWS рахунак - гэта функцыя залежнасці ад колькасці вашых інжынераў.

Іван Курносаў (у адказ):
Сапраўдны факт: Ваш AWS рахунак - гэта функцыя залежнасці ад колькасці рэчаў, якія вы забыліся адключыць/выдаліць.)

Kubernetes Janitor (kube-janitor) дапамагае ачысціць ваш кластар. Канфігурацыя janitor з'яўляецца гнуткай як для глабальнага, так і для лакальнага выкарыстання:

  • Агульныя правілы для ўсяго кластара могуць вызначаць максімальны час жыцця (TTL - time-to-live) для PR/тэставых разгортванняў.
  • Асобныя рэсурсы могуць быць анатаваны з дапамогай janitor/ttl, напрыклад, для аўтаматычнага выдалення spike/прататыпа праз 7 дзён.

Агульныя правілы вызначаюцца ў YAML файле. Яго шлях перадаецца праз параметр --rules-file у kube-janitor. Вось прыклад правілы для выдалення ўсіх прастор імёнаў з -pr- у імені праз два дні:

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

Наступны прыклад рэгламентуе выкарыстанні пазнакі application на Deployment і StatefulSet подах для ўсіх новых Deployments/StatefulSet у 2020 году, але ў той жа час дазваляе выкананне тэстаў без гэтай пазнакі на працягу тыдня:

- 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

Запуск абмежаванага па часе дэма на працягу 30 хвілін у кластары, дзе працуе kube-janitor:

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

Яшчэ адной крыніцай растучых выдаткаў з'яўляюцца пастаянныя тамы (AWS EBS). Пры выдаленні Kubernetes StatefulSet не выдаляюцца яго сталыя тамы (PVC - PersistentVolumeClaim). Нявыкарыстаныя аб'ёмы EBS могуць лёгка прывесці да выдаткаў у сотні даляраў у месяц. Kubernetes Janitor мае функцыю для ачысткі нявыкарыстаных PVC. Напрыклад, гэтае правіла выдаліць усе PVC, якія не змантаваныя модулем і на якія не спасылаецца StatefulSet або CronJob:

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

Kubernetes Janitor можа дапамагчы вам захаваць ваш кластар у «чысціні» і прадухіліць павольна назапашваюцца выдаткі на хмарныя вылічэнні. За інструкцыямі па разгортванні і наладзе прытрымлівайцеся ў README kube-janitor.

Памяншэнне маштабавання ў непрацоўны час

Тэставыя і прамежкавыя сістэмы звычайна патрабуюцца для працы толькі ў працоўны час. Некаторыя вытворчыя прыкладанні, такія як бэк-офіс / інструменты адміністратара, таксама патрабуюць толькі абмежаванай даступнасці і могуць быць адключаныя ноччу.

Kubernetes Downscaler (kube-downscaler) дазваляе карыстальнікам і аператарам памяншаць маштаб сістэмы ў непрацоўны час. Deployments і StatefulSets можна маштабаваць да нулявых рэплік. CronJobs могуць быць прыпынены. Kubernetes Downscaler наладжваецца для ўсяго кластара, аднаго або некалькіх прастор імёнаў ці асобных рэсурсаў. Можна ўсталяваць або "час прастою", або наадварот "час працы". Напрыклад, каб максімальна паменшыць маштабаванне на працягу ночы і выходных:

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

Вось графік маштабавання працоўных вузлоў кластара ў выходныя дні:

Эканомім на хмарных выдатках Kubernetes на AWS

Памяншэнне маштабу з ~13 да 4 працоўных вузлоў, безумоўна, дае адчувальную розніцу ў AWS рахунку.

Але што калі мне трэба працаваць падчас прастаю кластара? Вызначаныя разгортванні можна назаўжды выключыць з маштабавання, дадаўшы анатацыю downscaler/exclude: true. Разгортванні могуць быць часова выключаны з дапамогай анатацыі downscaler/exclude-until з абсалютным таймстэмпам ў фармаце ГГГГ-ММ-ДД ЧЧ: ММ (UTC). Пры неабходнасці ўвесь кластар можа быць маштабаваны назад шляхам разгортвання пода з анатацыяй downscaler/force-uptime, напрыклад, шляхам запуску nginx даўбешкі:

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

Глядзіце README kube-downscaler, калі вас цікавіць інструкцыя па разгортванні і дадатковыя опцыі.

Выкарыстоўвайце гарызантальнае аўтамаштабаванне

Многія прыкладанні/сэрвісы маюць справу з дынамічнай схемай загрузкі: часам іх модулі прастойваюць, а часам яны працуюць на поўную магутнасць. Праца з пастаянным паркам подаў, каб справіцца з максімальнай пікавай нагрузкай, не эканамічная. Kubernetes падтрымлівае гарызантальнае аўтаматычнае маштабаванне праз рэсурс HorizontalPodAutoscaler (HPA). Выкарыстанне ЦП часта з'яўляецца добрым паказчыкам для маштабавання:

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 стварыў кампанент для простага падлучэння карыстацкіх метрык для маштабавання: Kube Metrics Adapter (kube-metrics-adapter) - гэта ўніверсальны адаптар метрык для Kubernetes, які можа збіраць і абслугоўваць карыстацкія і вонкавыя метрыкі для гарызантальнага аўтамаштабавання подаў. Ён падтрымлівае маштабаванне на аснове метрык Prometheus, чэргаў SQS і іншых налад. Напрыклад, каб маштабаваць разгортванне для карыстацкай метрыкі, прадстаўленай самім дадаткам у выглядзе JSON у /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

Настройка гарызантальнага аўтамаштабавання з дапамогай HPA павінна быць адным з дзеянняў па змаўчанні для павышэння эфектыўнасці для службаў без уліку стану. У Spotify ёсць прэзентацыя з іх досведам і рэкамендацыямі для HPA: маштабуйце свае разгортванні, а не свой кашалёк.

Памяншэнне залішняга рэзервавання рэсурсаў

Працоўныя нагрузкі Kubernetes вызначаюць іх запатрабаванні ў ЦП/памяці праз "запыты рэсурсаў" (resource requests). Рэсурсы ЦП вымяраюцца ў віртуальных ядрах або часцей у "мілікорах" (millicores), напрыклад, 500m мае на ўвазе 50% vCPU. Рэсурсы памяці вымяраюцца ў байтах, і можна выкарыстоўваць звычайныя суфіксы, напрыклад, 500Mi, што азначае 500 мегабайт. Запыты рэсурсаў "блакуюць" аб'ём на працоўных вузлах, гэта значыць модуль з запытам ЦП у 1000m на вузле з 4 віртуальнымі ЦП пакіне толькі 3 віртуальных ЦП даступнымі для іншых модуляў. [1]

Slack (лішак рэзерву) - Гэта розніца паміж рэсурсамі і рэальным выкарыстаннем. Напрыклад, пад, які запытвае 2 GiB памяці, але выкарыстоўвае толькі 200 MiB, мае ~ 1,8 GiB "залішняй" памяці. Лішак каштуе грошай. Можна груба ацаніць, што 1 GiB залішняй памяці каштуе ~ 10 даляраў у месяц. [2]

Kubernetes Resource Report (kube-resource-report) адлюстроўвае залішнія рэзервы і можа дапамагчы вам вызначыць патэнцыял эканоміі:

Эканомім на хмарных выдатках Kubernetes на AWS

Kubernetes Resource Report паказвае лішак, агрэгаваны дадаткам і камандай. Гэта дазваляе знайсці месцы, дзе запыты рэсурсаў могуць быць паніжаныя. Згенераваны HTML справаздачу дае толькі снапшот выкарыстання рэсурсу. Вы павінны глядзець на выкарыстанне працэсара/памяці з цягам часу, каб вызначыць адэкватныя запыты рэсурсаў. Вось дыяграма Grafana для "тыповай" службы з вялікай нагрузкай на ЦП: усе поды выкарыстоўваюць значна менш 3 запытаных ядраў ЦП:

Эканомім на хмарных выдатках Kubernetes на AWS

Скарачэнне запыту ЦП з 3000m да ~400m вызваляе рэсурсы для іншых працоўных нагрузак і дазваляе паменшыць кластар.

"Сярэдняе выкарыстанне ЦП EC2 інстанс часта вагаецца ў дыяпазоне адназначных працэнтаў", – піша Коры Куін. У той час як для EC2 ацэнка правільнага памеру можа быць дрэнным рашэннем, Змена некаторых запытаў рэсурсаў Kubernetes ў YAML файле выконваецца лёгка і можа прынесці вялікую эканомію.

Але ці сапраўды мы хочам, каб людзі мянялі значэння ў YAML файлах? Не, машыны могуць зрабіць гэта нашмат лепш! Kubernetes Vertical Pod Autoscaler (VPA) якраз гэтым і займаецца: адаптуе запыты рэсурсаў і абмежаванні ў адпаведнасці з працоўнай нагрузкай. Вось прыклад графіка запытаў ЦП Prometheus (тонкая сіняя лінія), адаптаваных VPA з цягам часу:

Эканомім на хмарных выдатках Kubernetes на AWS

Zalando выкарыстоўвае VPA ва ўсіх сваіх кластарах для кампанентаў інфраструктуры. Некрытычныя прыкладанні таксама могуць выкарыстоўваць VPA.

Goldilocks ад Fairwind - гэта прылада, які стварае VPA для кожнага разгортвання ў прасторы імёнаў, а затым адлюстроўвае рэкамендацыю VPA на сваёй інфармацыйнай панэлі. Ён можа дапамагчы распрацоўнікам усталяваць правільныя запыты працэсара/памяці для сваіх прыкладанняў:

Эканомім на хмарных выдатках Kubernetes на AWS

Я напісаў невялікі блогпост аб VPA у 2019 годзе, і нядаўна ў CNCF End User Community абмяркоўвалася пытанне VPA.

Выкарыстанне EC2 Spot інстансаў

Нарэшце, што не менш важна, выдаткі AWS EC2 можна зменшыць, выкарыстоўваючы Spot інстансы ў якасці працоўных вузлоў Kubernetes [3]. Spot інстансы даступныя са зніжкай да 90% у параўнанні з коштамі па патрабаванні. Запуск Kubernetes на EC2 Spot - добрая камбінацыя: вам трэба паказаць некалькі розных тыпаў інстансаў для больш высокай даступнасці, гэта значыць вы можаце атрымаць большы вузел за тую ж або больш нізкую цану, а павялічаная ёмістасць можа быць выкарыстана кантэйнернымі працоўнымі нагрузкамі Kubernetes.

Як запусціць Kubernetes на EC2 Spot? Існуе некалькі варыянтаў: выкарыстоўваць іншы сэрвіс, такі як SpotInst (зараз ён называецца «Spot», не пытайце мяне, чаму), ці проста дадаць Spot AutoScalingGroup (ASG) у ваш кластар. Напрыклад, вось фрагмент CloudFormation для "аптымізаванай па ёмістасці" Spot ASG з некалькімі тыпамі асобнікаў:

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"

Некаторыя заўвагі па выкарыстанні Spot з Kubernetes:

  • Вам трэба апрацоўваць завяршэння Spot, напрыклад шляхам зліву вузла на прыпынку інстанса
  • Zalando выкарыстоўвае відэлец афіцыйнага аўтамаштабавання кластара з прыярытэтамі пула вузлоў
  • Вузлы Spot можна прымусіць прымаць "рэгістрацыі" працоўных нагрузак для запуску ў Spot

Рэзюмэ

Я спадзяюся, што вы знойдзеце некаторыя з прадстаўленых інструментаў карыснымі для скарачэння вашага рахунку за хмарныя вылічэнні. Вы можаце знайсці большую частку змесціва артыкула таксама ў маім выступленні на DevOps Gathering 2019 на YouTube і ў выглядзе слайдаў.

Якія вашыя лепшыя практыкі для эканоміі хмарных выдаткаў на Kubernetes? Калі ласка, дайце ведаць у Twitter (@try_except_).

[1] Фактычна менш за 3 віртуальныя ЦП застануцца прыдатнымі для выкарыстання, паколькі прапускная здольнасць вузла памяншаецца за кошт зарэзерваваных сістэмных рэсурсаў. Kubernetes адрознівае фізічную ёмістасць вузла і "выдзяляюцца" рэсурсы (Node Allocatable).

[2] Прыклад разліку: адзін асобнік m5.large з 8 GiB памяці складае ~84 даляра ЗША у месяц (eu-central-1, On-Demand), г.зн. блакіроўка 1/8 вузла складае прыкладна ~10 даляраў ЗША ў месяц.

[3] Ёсць яшчэ шмат спосабаў паменшыць ваш EC2 рахунак, напрыклад, зарэзерваваныя асобнікі, план зберажэнняў і т. д. — я не буду асвятляць гэтыя тэмы тут, але вы абавязкова павінны пра іх даведацца!

Даведацца падрабязней аб курсе.

Крыніца: habr.com

Дадаць каментар