K8s Q A Horisontal Pod Autoscaler

Материал из noname.com.ua
Версия от 10:29, 9 января 2024; Sirmax (обсуждение | вклад) (Новая страница: «Категория:K8s Категория:K8s_Вопросы_И_Ответы Категория:Требуется форматирование текс...»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к навигацииПерейти к поиску


Знакомство с Kubernetes. Часть 19: HorizontalPodAutoscaler

Jun 12, 2019 08:08 · 918 words · 5 minute read KUBERNETES В этой статье рассмотрим использование HorizontalPodAutoscaler - объектов, предназначенных для автоматического масштабирования количества подов (Pods) в Replication Controller, Replica Set или Deployment, основываясь на использовании CPU (или, при поддержке custom metrics, на других метриках приложения). Давайте разберемся!

Сразу стоит отметить, что HorizontalPodAutoscaler не может быть применен к объектам, которые не предназначены для масштабирования, например DaemonSets. Horizontal Pod Autoscaler состоит из Kubernetes ресурса (объекта) и контроллера, поведение которого описывается ресурсом.

C периодичностью 15 секунд (можно изменить с помощью параметра --horizontal-pod-autoscaler-sync-period), контроллер собирает данные по использованию метрик, определенных в манифесте ресурса HorizontalPodAutoscaler. Метрики собираются или с resource metrics API (метрики использования ресурсов подами) или с custom metrics API (остальные метрики, например, метрики приложения).

Для каждого подконтрольного пода, контроллер собирает метрики (например, использования CPU) с resource metrics API (metrics.k8s.io, предоставляется metrics-server). Далее, происходит вычисление текущего значения использования CPU в процентах от запрошенных ресурсов (resource request) контейнерами каждого пода, после чего это значение сравнивается с “целевым” (target) значением - порогом, после которого количество подов должно быть увеличено.

Рассмотрим конкретный пример. Создадим файл test-hpa.yaml с описанием ресурса HorizontalPodAutoscaler такого содержания:

apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata:

 name: test-hpa

spec:

 scaleTargetRef:
   apiVersion: apps/v1
   kind: Deployment
   name: test-api-deploy
 minReplicas: 10
 maxReplicas: 29
 metrics:
 - type: Resource
   resource:
     name: cpu
     targetAverageUtilization: 80

Создадим данный объект в кластере Kubernetes:

kubectl create -f test-hpa.yaml Проверим наличие объекта:

kubectl get horizontalpodautoscaler NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE test-hpa Deployment/test-api-deploy <unknown>/80% 10 29 0 7s Спустя некоторое время, вместо <unknown>, мы должны увидеть текущее использование CPU подами в деплойменте test-api-deploy, однако в моем случае этого не произошло. Начинаем разбираться - для начала, убедимся, что metrics.k8s.io доступно:

kubectl get --raw "/apis/metrics.k8s.io/" | jq {

 "kind": "APIGroup",
 "apiVersion": "v1",
 "name": "metrics.k8s.io",
 "versions": [
   {
     "groupVersion": "metrics.k8s.io/v1beta1",
     "version": "v1beta1"
   }
 ],
 "preferredVersion": {
   "groupVersion": "metrics.k8s.io/v1beta1",
   "version": "v1beta1"
 }

} Проверим, что метрики использования CPU доступны. Первый вариант:

kubectl top pod | grep test-api-deploy test-api-deploy-5f77b79896-2t9x9 738m 43931Mi test-api-deploy-5f77b79896-fhr7b 643m 43999Mi test-api-deploy-5f77b79896-gcrlc 700m 44028Mi test-api-deploy-5f77b79896-lx24k 666m 44201Mi test-api-deploy-5f77b79896-mzlzb 660m 44048Mi test-api-deploy-5f77b79896-ndjwx 651m 44136Mi test-api-deploy-5f77b79896-q2nvw 654m 44177Mi test-api-deploy-5f77b79896-qmw4t 692m 44051Mi test-api-deploy-5f77b79896-rl4bb 650m 43979Mi test-api-deploy-5f77b79896-xhpbx 752m 44116Mi Второй вариант (метрики только одного конкретного пода):

kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/default/pods/test-api-deploy-5f77b79896-xhpbx | jq {

 "kind": "PodMetrics",
 "apiVersion": "metrics.k8s.io/v1beta1",
 "metadata": {
   "name": "test-api-deploy-5f77b79896-xhpbx",
   "namespace": "default",
   "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/test-api-deploy-5f77b79896-xhpbx",
   "creationTimestamp": "2019-06-11T13:50:00Z"
 },
 "timestamp": "2019-06-11T13:49:41Z",
 "window": "30s",
 "containers": [
   {
     "name": "envoy",
     "usage": {
       "cpu": "489151208n",
       "memory": "45692Ki"
     }
   },
   {
     "name": "test",
     "usage": {
       "cpu": "7125240328n",
       "memory": "45515856Ki"
     }
   }
 ]

} Как видим, метрики доступны. Получим детальное описание нашего HorizontalPodAutoscaler:

kubectl describe hpa test-hpa Name: test-hpa Namespace: default Labels: app.kubernetes.io/managed-by=spinnaker

                                                      app.kubernetes.io/name=test

Annotations: artifact.spinnaker.io/location: default

                                                      artifact.spinnaker.io/name: test-hpa
                                                      artifact.spinnaker.io/type: kubernetes/horizontalpodautoscaler
                                                      kubectl.kubernetes.io/last-applied-configuration:
                                                        {"apiVersion":"autoscaling/v2beta1","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{"artifact.spinnaker.io/location":"default"...
                                                      moniker.spinnaker.io/application: test
                                                      moniker.spinnaker.io/cluster: horizontalpodautoscaler test-hpa

CreationTimestamp: Tue, 11 Jun 2019 11:21:03 +0300 Reference: Deployment/test-api-deploy Metrics: ( current / target )

 resource cpu on pods  (as a percentage of request):  <unknown> / 80%

Min replicas: 10 Max replicas: 29 Deployment pods: 10 current / 10 desired Conditions:

 Type           Status  Reason                   Message
 ----           ------  ------                   -------
 AbleToScale    True    SucceededGetScale        the HPA controller was able to get the target's current scale
 ScalingActive  False   FailedGetResourceMetric  the HPA was unable to compute the replica count: missing request for cpu

Events:

 Type     Reason                        Age                    From                       Message
 ----     ------                        ----                   ----                       -------
 Normal   SuccessfulRescale             7m17s                  horizontal-pod-autoscaler  New size: 10; reason: Current number of replicas below Spec.MinReplicas
 Warning  FailedComputeMetricsReplicas  4m15s (x12 over 7m2s)  horizontal-pod-autoscaler  failed to get cpu utilization: missing request for cpu
 Warning  FailedGetResourceMetric       2m15s (x20 over 7m2s)  horizontal-pod-autoscaler  missing request for cpu

Здесь самое важное - сообщение the HPA was unable to compute the replica count: missing request for cpu. И действительно, в манифесте развертывания (Deployment) не указаны resource requests для одного из контейнеров (с именем envoy):

apiVersion: apps/v1 kind: Deployment metadata:

 annotations:
  1. From https://www.spinnaker.io/reference/providers/kubernetes-v2/#strategy
   strategy.spinnaker.io/use-source-capacity: "true"
 name: test-api-deploy

spec:

  1. replicas: 15
 selector:
   matchLabels:
     deployment: test-api-deploy
 strategy:
   rollingUpdate:
     maxSurge: 0
   type: RollingUpdate
 template:
   metadata:
     labels:
       deployment: test-api-deploy
   spec:
     containers:
     - image: envoyproxy/envoy:v1.10.0
       name: envoy
       ports:
       - containerPort: 8080
         name: http
       volumeMounts:
       - mountPath: /etc/envoy
         name: envoy-config
     - env:
       - name: JAVA_OPTS
         value: -Xms40g -Xmx40g
       image: index.docker.io/ealebed/test:v1
       name: test
       resources:
         limits:
           memory: 55Gi
         requests:
           cpu: "10"
           memory: 55Gi
     volumes:
     - configMap:
         name: envoy-config
       name: envoy-config

Важно! Если не указаны resource request хотя бы для одного из контейнеров в Replication Controller, Replica Set или Deployment, то текущее значение использование CPU подами не может быть корректно определено, и, в результате, HorizontalPodAutoscaler не будет предпринимать никаких действий по масштабированию.

После исправления этой досадной ошибки, HorizontalPodAutoscaler, базируясь на полученных метриках, начинает масштабировать поды в развертывании:

kubectl get horizontalpodautoscaler NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE test-hpa Deployment/test-api-deploy 86%/80% 10 29 29 9m10 Формула, по которой HorizontalPodAutoscaler вычисляет требуемое количество реплик выглядит так:

desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )] Например, если текущее значение метрики (currentMetricValue) равно 200m, а ожидаемое (desiredMetricValue) установлено в 100m, то количество реплик будет удвоено (200.0 / 100.0 == 2.0). Если же текущее значение метрики равно всего лишь 50m, то количество реплик должно быть уменьшено вдвое (50.0 / 100.0 == 0.5). Если соотношение текущего значения метрики к ожидаемому значению достаточно близко к 1, то никаких действий не будет предпринято.

Так как мы указали targetAverageUtilization при описании ресурса HorizontalPodAutoscaler, то текущее значение метрики (currentMetricValue) использования CPU рассчитывается как среднее значение этой метрики для всех подов, контролируемых данным автоскейлером.

После того, как текущее значение использования CPU снизилось и оставалось низким в течении 5 минут (устанавливается с помощью параметра --horizontal-pod-autoscaler-downscale-stabilization), количество реплик было автоматически уменьшено:

kubectl get horizontalpodautoscaler NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE test-hpa Deployment/test-api-deploy 70%/80% 20 29 23 1h На этом все, в одной из следующих статей рассмотрим более сложный вариант автоскейлинга, базирующийся на метриках приложения.