Як зэканоміць на хмарных выдатках пры працы з Kubernetes? Адзіна правільнага рашэння не існуе, але ў гэтым артыкуле апісана некалькі інструментаў, якія дапамогуць вам больш эфектыўна кіраваць рэсурсамі і скараціць выдаткі на хмарныя вылічэнні.
Я напісаў гэты артыкул з аглядкай на Kubernetes для AWS, але яна будзе дастасавальная (амаль) сапраўды гэтак жа і для іншых хмарных правайдэраў. Я мяркую, што ваш кластар(ы) ужо мае настроенае аўтаматычнае маштабаванне (cluster-autoscaler). Выдаленне рэсурсаў і памяншэнне маштабу разгортвання дазволіць зэканоміць толькі ў тым выпадку, калі гэта таксама скароціць ваш парк працоўных вузлоў (EC2 інстансаў).
Праца ў хутка якое змяняецца асяроддзі - гэта выдатна. Мы хочам, каб тэхнічныя арганізацыі паскараліся. Больш хуткая дастаўка праграмнага забеспячэння таксама азначае большую колькасць PR-разгортванняў, асяроддзяў папярэдняга прагляду, прататыпаў і аналітычных рашэнняў. Усё разгортваецца на Kubernetes. У каго ёсць час, каб чысціць тэставыя разгортванні ўручную? Лёгка забыцца аб выдаленні эксперыменту тыднёвай даўнасці. Рахунак за воблака ў канчатковым выніку будзе расці з-за таго, што мы забыліся закрыць:
(Хеннінг Джэйкабс:
Жыза:
(цытуе) Коры Куін:
Міф: Ваш AWS рахунак - гэта функцыя залежнасці ад колькасці вашых карыстальнікаў.
Факт: Ваш AWS рахунак - гэта функцыя залежнасці ад колькасці вашых інжынераў.
Іван Курносаў (у адказ):
Сапраўдны факт: Ваш AWS рахунак - гэта функцыя залежнасці ад колькасці рэчаў, якія вы забыліся адключыць/выдаліць.)
Kubernetes Janitor (kube-janitor) дапамагае ачысціць ваш кластар. Канфігурацыя janitor з'яўляецца гнуткай як для глабальнага, так і для лакальнага выкарыстання:
Агульныя правілы для ўсяго кластара могуць вызначаць максімальны час жыцця (TTL - time-to-live) для PR/тэставых разгортванняў.
Асобныя рэсурсы могуць быць анатаваны з дапамогай janitor/ttl, напрыклад, для аўтаматычнага выдалення spike/прататыпа праз 7 дзён.
Агульныя правілы вызначаюцца ў YAML файле. Яго шлях перадаецца праз параметр --rules-file у kube-janitor. Вось прыклад правілы для выдалення ўсіх прастор імёнаў з -pr- у імені праз два дні:
Наступны прыклад рэгламентуе выкарыстанні пазнакі 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
Вось графік маштабавання працоўных вузлоў кластара ў выходныя дні:
Памяншэнне маштабу з ~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). Выкарыстанне ЦП часта з'яўляецца добрым паказчыкам для маштабавання:
Zalando стварыў кампанент для простага падлучэння карыстацкіх метрык для маштабавання: Kube Metrics Adapter (kube-metrics-adapter) - гэта ўніверсальны адаптар метрык для Kubernetes, які можа збіраць і абслугоўваць карыстацкія і вонкавыя метрыкі для гарызантальнага аўтамаштабавання подаў. Ён падтрымлівае маштабаванне на аснове метрык Prometheus, чэргаў SQS і іншых налад. Напрыклад, каб маштабаваць разгортванне для карыстацкай метрыкі, прадстаўленай самім дадаткам у выглядзе JSON у /metrics выкарыстайце:
Настройка гарызантальнага аўтамаштабавання з дапамогай 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 Resource Report паказвае лішак, агрэгаваны дадаткам і камандай. Гэта дазваляе знайсці месцы, дзе запыты рэсурсаў могуць быць паніжаныя. Згенераваны HTML справаздачу дае толькі снапшот выкарыстання рэсурсу. Вы павінны глядзець на выкарыстанне працэсара/памяці з цягам часу, каб вызначыць адэкватныя запыты рэсурсаў. Вось дыяграма Grafana для "тыповай" службы з вялікай нагрузкай на ЦП: усе поды выкарыстоўваюць значна менш 3 запытаных ядраў ЦП:
Скарачэнне запыту ЦП з 3000m да ~400m вызваляе рэсурсы для іншых працоўных нагрузак і дазваляе паменшыць кластар.
"Сярэдняе выкарыстанне ЦП EC2 інстанс часта вагаецца ў дыяпазоне адназначных працэнтаў", – піша Коры Куін. У той час як для EC2 ацэнка правільнага памеру можа быць дрэнным рашэннем, Змена некаторых запытаў рэсурсаў Kubernetes ў YAML файле выконваецца лёгка і можа прынесці вялікую эканомію.
Але ці сапраўды мы хочам, каб людзі мянялі значэння ў YAML файлах? Не, машыны могуць зрабіць гэта нашмат лепш! Kubernetes Vertical Pod Autoscaler (VPA) якраз гэтым і займаецца: адаптуе запыты рэсурсаў і абмежаванні ў адпаведнасці з працоўнай нагрузкай. Вось прыклад графіка запытаў ЦП Prometheus (тонкая сіняя лінія), адаптаваных VPA з цягам часу:
Goldilocks ад Fairwind - гэта прылада, які стварае VPA для кожнага разгортвання ў прасторы імёнаў, а затым адлюстроўвае рэкамендацыю VPA на сваёй інфармацыйнай панэлі. Ён можа дапамагчы распрацоўнікам усталяваць правільныя запыты працэсара/памяці для сваіх прыкладанняў:
Нарэшце, што не менш важна, выдаткі AWS EC2 можна зменшыць, выкарыстоўваючы Spot інстансы ў якасці працоўных вузлоў Kubernetes [3]. Spot інстансы даступныя са зніжкай да 90% у параўнанні з коштамі па патрабаванні. Запуск Kubernetes на EC2 Spot - добрая камбінацыя: вам трэба паказаць некалькі розных тыпаў інстансаў для больш высокай даступнасці, гэта значыць вы можаце атрымаць большы вузел за тую ж або больш нізкую цану, а павялічаная ёмістасць можа быць выкарыстана кантэйнернымі працоўнымі нагрузкамі Kubernetes.
Як запусціць Kubernetes на EC2 Spot? Існуе некалькі варыянтаў: выкарыстоўваць іншы сэрвіс, такі як SpotInst (зараз ён называецца «Spot», не пытайце мяне, чаму), ці проста дадаць Spot AutoScalingGroup (ASG) у ваш кластар. Напрыклад, вось фрагмент CloudFormation для "аптымізаванай па ёмістасці" Spot ASG з некалькімі тыпамі асобнікаў:
Якія вашыя лепшыя практыкі для эканоміі хмарных выдаткаў на 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 рахунак, напрыклад, зарэзерваваныя асобнікі, план зберажэнняў і т. д. — я не буду асвятляць гэтыя тэмы тут, але вы абавязкова павінны пра іх даведацца!