Привет, Хабр!
Сегодня микросервисы требуют постоянного стремления к автоматизации и оптимизации. В этой статье рассмотрим такой инструмент в Kubernetes, как Horizontal Pod Autoscaler или сокращенно HPA.
Развертывание микросервиса
Развернем простое приложение в Kubernetes. Будем использовать стандартный подход через Deployment и Service:
apiVersion: apps/v1 kind: Deployment metadata: name: my-microservice spec: replicas: 1 # Начинаем с одного пода selector: matchLabels: app: my-microservice template: metadata: labels: app: my-microservice spec: containers: - name: my-microservice image: nginx:latest # Используем NGINX для простоты resources: requests: cpu: 100m # Ресурсы по умолчанию memory: 256Mi limits: cpu: 200m memory: 512Mi ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-microservice-service spec: selector: app: my-microservice ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP
Манифест описывает простое приложение NGINX, которое будем использовать для тестирования HPA. Создаем Deployment с одним подом и устанавливаем базовые требования к ресурсам.
kubectl apply -f my-microservice.yaml
Теперь есть базовый микросервис, готовый к автоскейлингу.
Теперь настроим HPA. Он автоматически увеличивает или уменьшает количество подов в зависимости от нагрузки на CPU.
kubectl autoscale deployment my-microservice --cpu-percent=50 --min=1 --max=10
Команда создаёт HPA, который будет отслеживать загрузку CPU и масштабировать Deployment в пределах от 1 до 10 подов, пытаясь поддерживать среднюю загрузку CPU на уровне 50%.
Что здесь важно:
-
—cpu-percent=50: цель автоскейлинга — поддерживать загрузку CPU на уровне 50%.
-
—min=1 и —max=10: минимум один под, максимум десять. Эти параметры зависят от приложения и ресурсов кластера.
Для более детальной настройки HPA можно использовать YAML-манифест:
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: my-microservice-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: my-microservice minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 # Цель по CPU
Этот манифест можно применить командой:
kubectl apply -f my-microservice-hpa.yaml
После настройки HPA убедимся, что он работает корректно. Для этого можно использовать несколько команд, например:
kubectl get hpa
Можно увидеть что-то вроде:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE my-microservice-hpa Deployment/my-microservice 30%/50% 1 10 2 5m
Этот вывод показывает:
-
TARGETS: текущая загрузка CPU (в нашем случае 30%) относительно цели (50%).
-
REPLICAS: Текущее количество подов (в данном примере 2).
Чтобы протестировать, как работает автоскейлер, можно сгенерировать нагрузку на приложение. Один из способов — запустить контейнер, который будет постоянно отправлять запросы на микросервис:
kubectl run -i --tty load-generator --image=busybox --restart=Never -- /bin/sh while true; do wget -q -O- http://my-microservice-service; done
Через некоторое время, можно снова проверить статус HPA:
kubectl get hpa
Можно увидеть, как количество подов увеличивается по мере роста загрузки CPU.
Для остановки нагрузки, можно нажать Ctrl + C в терминале, где запущен load-generator.
Кастомные метрики
Для настройки кастомных метрик потребуется интеграция с системой мониторинга, например, Prometheus, которая будет собирать данные метрик и предоставлять их для HPA через API.
Допустим, нужно масштабировать приложение на основе количества HTTP-запросов в секунду. Для этого сначала необходимо экспортировать соответствующие метрики из приложения в Prometheus. Пример метрики:
httpRequestsTotal := prometheus.NewCounter( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total number of HTTP requests processed.", }, )
Код на Go экспортирует метрику http_requests_total, которую можно собрать и использовать для автоскейлинга.
Теперь нужно настроить Prometheus Adapter для работы с этой метрикой. Например, можно добавить следующую конфигурацию в values.yaml для Prometheus Adapter:
rules: custom: - seriesQuery: 'http_requests_total{namespace="default"}' resources: overrides: namespace: resource: namespace pod: resource: pod name: matches: "^(.*)_total" as: "${1}_per_second" metricsQuery: 'rate(http_requests_total{<<.LabelMatchers>>}[2m])'
Этот конфиг преобразует метрику http_requests_total в http_requests_per_second, которую можно использовать для автоскейлинга.
Теперь создадим манифест HPA, который будет масштабировать поды на основе количества запросов в секунду:
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: my-microservice-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: my-microservice minReplicas: 2 maxReplicas: 10 metrics: - type: Pods pods: metric: name: http_requests_per_second target: type: AverageValue averageValue: "100"
Этот манифест говорит Kubernetes масштабировать микросервис, если среднее количество HTTP-запросов превышает 100 запросов в секунду на под.
Настройка HPA с кастомными метриками — это тонкий процесс. Вот несколько советов, которые помогут вам избежать подводных камней и оптимизировать производительность автоскейлера.
Избегание частого масштабирования
Thrashing — это ситуация, когда автоскейлер часто меняет количество подов из-за слишком агрессивных или неправильно настроенных порогов. Чтобы этого избежать:
-
Установите адекватные пороговые значения и периоды ожидания. Например, можно настроить задержку между скейлингом с помощью параметра
--horizontal-pod-autoscaler-sync-period. -
Еще можно использовать плавные метрики, такие как
rate()для запросов, которые вычисляют средние значения за определённый интервал времени, чтобы избежать резких изменений.
HPA по умолчанию синхронизируется каждые 15 секунд. Этот интервал можно изменить, чтобы снизить нагрузку на систему или ускорить реакцию на изменения нагрузки:
httpRequestsTotal := prometheus.NewCounter( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total number of HTTP requests processed.", }, )
Увеличение периода синхронизации может снизить частоту изменений, но может задерживать реакцию на резкие скачки нагрузки.
Для более точного контроля за автоскейлингом можно использовать комбинацию метрик, например, CPU и кастомные метрики одновременно:
metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60 - type: Pods pods: metric: name: http_requests_per_second target: type: AverageValue averageValue: "100"
Здесь HPA будет одновременно учитывать загрузку CPU и количество запросов в секунду при масштабировании.
Больше актуальных навыков по инфраструктуре, архитектуре и разработке приложений вы можете получить в рамках практических онлайн-курсов от экспертов отрасли.
ссылка на оригинал статьи https://habr.com/ru/articles/838364/
Добавить комментарий