Спестете от разходите за облак Kubernetes на AWS

Преводът на статията беше подготвен в навечерието на началото на курса „Инфраструктурна платформа, базирана на Kubernetes“.

Спестете от разходите за облак Kubernetes на AWS

Как да спестите разходи за облак, когато работите с Kubernetes? Няма едно правилно решение, но тази статия описва няколко инструмента, които могат да ви помогнат да управлявате ресурсите си по-ефективно и да намалите разходите си за облачни изчисления.

Написах тази статия с предвид Kubernetes за AWS, но тя ще се прилага (почти) по същия начин за други доставчици на облак. Предполагам, че вашият клъстер(и) вече има конфигурирано автоматично мащабиране (cluster-autoscaler). Премахването на ресурси и намаляването на вашето внедряване ще ви спести пари само ако намали и вашия флот от работни възли (EC2 инстанции).

Тази статия ще обхване:

  • почистване на неизползвани ресурси (кубе-портиер)
  • Намалете мащабирането в неработно време (kube-downscaler)
  • използване на хоризонтално автоматично мащабиране (HPA),
  • намаляване на прекомерното резервиране на ресурси (kube-resource-report, VPA)
  • използване на екземпляри на Spot

Почистване на неизползвани ресурси

Работата в забързана среда е страхотна. Искаме технологични организации ускорено. По-бързата доставка на софтуер също означава повече внедрявания на PR, среди за предварителен преглед, прототипи и решения за анализ. Всичко е внедрено в Kubernetes. Кой има време да изчисти ръчно тестови внедрявания? Лесно е да забравите за изтриването на едноседмични експерименти. Сметката за облака в крайна сметка ще се повиши поради нещо, което сме забравили да затворим:

Спестете от разходите за облак Kubernetes на AWS

(Хенинг Джейкъбс:
Жиза:
(кавички) Кори Куин:
Мит: Вашият акаунт в AWS е функция на броя потребители, които имате.
Факт: Вашият AWS резултат е функция на броя инженери, които имате.

Иван Курносов (в отговор):
Истински факт: Вашият AWS резултат е функция на броя неща, които сте забравили да деактивирате/изтриете.)

Портиер на Kubernetes (kube-janitor) помага за почистването на вашия клъстер. Конфигурацията на портиера е гъвкава както за глобална, така и за локална употреба:

  • Правилата за целия клъстер могат да определят максималното време за живот (TTL) за PR/тестово внедряване.
  • Индивидуалните ресурси могат да бъдат анотирани с janitor/ttl, например за автоматично премахване на шипа/прототипа след 7 дни.

Общите правила са дефинирани в YAML файла. Пътят му се предава през параметъра --rules-file в кубе-портиер. Ето едно примерно правило за премахване на всички пространства от имена -pr- на име след два дни:

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

Следният пример регулира използването на етикета на приложението в модулите 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) позволява на потребителите и операторите да намаляват мащаба на системата в извънработно време. Внедряванията и 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. Внедряванията могат да бъдат временно изключени с помощта на анотацията за намаляване/изключване-до с абсолютен времеви печат във формат ГГГГ-ММ-ДД ЧЧ:ММ (UTC). Ако е необходимо, целият клъстер може да бъде намален чрез внедряване на група с анотацията downscaler/force-uptime, например чрез стартиране на 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

виждам 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 определят техните нужди от процесор/памет чрез „заявки за ресурси“. CPU ресурсите се измерват във виртуални ядра или по-често в „милиядра“, например 500m предполага 50% vCPU. Ресурсите на паметта се измерват в байтове и могат да се използват общи суфикси, като 500Mi, което означава 500 мегабайта. Заявките за ресурси „заключват“ капацитета на работните възли, което означава, че под с 1000m CPU заявка на възел с 4 vCPU ще остави само 3 vCPU достъпни за други подове. [1]

Застой (излишен резерв) е разликата между заявените ресурси и действителното използване. Например, под, който изисква 2 GiB памет, но използва само 200 MiB, има ~1,8 GiB „излишна“ памет. Излишъкът струва пари. Може грубо да се изчисли, че 1 GiB излишна памет струва ~$10 на месец. [2]

Доклад за ресурси на Kubernetes (kube-resource-report) показва излишните резерви и може да ви помогне да определите потенциала за спестяване:

Спестете от разходите за облак Kubernetes на AWS

Доклад за ресурси на Kubernetes показва излишъка, агрегиран по приложение и команда. Това ви позволява да намерите места, където нуждите от ресурси могат да бъдат намалени. Генерираният HTML отчет предоставя само моментна снимка на използването на ресурсите. Трябва да разгледате използването на процесора/паметта във времето, за да определите адекватни заявки за ресурси. Ето диаграма на Grafana за "типична" услуга с голямо натоварване на процесора: всички модули използват значително по-малко от 3-те заявени процесорни ядра:

Спестете от разходите за облак Kubernetes на AWS

Намаляването на заявката за CPU от 3000m на ~400m освобождава ресурси за други натоварвания и позволява на клъстера да бъде по-малък.

„Средното използване на процесора на екземплярите на EC2 често се движи в едноцифрен процентен диапазон,“ пише Кори Куин. Докато за EC2 определянето на правилния размер може да е лошо решениеПромяната на някои заявки за ресурси на Kubernetes в YAML файл е лесна и може да донесе огромни спестявания.

Но наистина ли искаме хората да променят стойностите в YAML файловете? Не, машините го правят много по-добре! Kubernetes Автоматичен скалер за вертикален под (VPA) прави точно това: адаптира заявките за ресурси и ограниченията според натоварването. Ето примерна графика на заявките за CPU на Prometheus (тънка синя линия), адаптирани от VPA с течение на времето:

Спестете от разходите за облак Kubernetes на AWS

Zalando използва VPA във всички свои клъстери за инфраструктурни компоненти. Некритичните приложения също могат да използват VPA.

лютиче от Fairwind е инструмент, който създава VPA за всяко внедряване в пространство от имена и след това показва VPA препоръка на своето табло за управление. Може да помогне на разработчиците да зададат правилните заявки за CPU/памет за своите приложения:

Спестете от разходите за облак Kubernetes на AWS

Написах малък публикация в блога за VPA през 2019 г., а наскоро през Общността на крайните потребители на CNCF обсъди проблема с VPA.

Използване на EC2 Spot инстанции

Не на последно място, разходите за AWS EC2 могат да бъдат намалени чрез използване на Spot инстанции като работни възли на Kubernetes [3]. Спот екземплярите се предлагат с до 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

Обобщение

Надявам се да намерите някои от представените инструменти за полезни за намаляване на сметката ви за облак. Можете да намерите по-голямата част от съдържанието на статията и на моята реч на DevOps Gathering 2019 в YouTube и в слайдове.

Какви са вашите най-добри практики за спестяване на разходи за облак на Kubernetes? Моля, уведомете ме на Twitter (@try_except_).

[1] Всъщност по-малко от 3 vCPU ще останат използваеми, тъй като пропускателната способност на възела е намалена от резервирани системни ресурси. Kubernetes прави разлика между капацитет на физически възел и „осигурени“ ресурси (Разпределяем възел).

[2] Пример за изчисление: един екземпляр m5.large с 8 GiB памет е ~$84 ​​​​на месец (eu-central-1, On-Demand), т.е. блокиране на 1/8 възел е приблизително ~$10/месец.

[3] Има много други начини да намалите сметката си за EC2, като например резервирани екземпляри, спестяващ план и т.н. - няма да разглеждам тези теми тук, но определено трябва да ги разгледате!

Научете повече за курса.

Източник: www.habr.com

Добавяне на нов коментар