K8s Q A Horisontal Pod Autoscaler: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
(Новая страница: «Категория:K8s Категория:K8s_Вопросы_И_Ответы Категория:Требуется форматирование текс...»)
 
Строка 3: Строка 3:
 
[[Категория:Требуется форматирование текста]]
 
[[Категория:Требуется форматирование текста]]
   
Знакомство с Kubernetes. Часть 19: HorizontalPodAutoscaler
+
=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) значением - порогом, после которого количество подов должно быть увеличено.
 
   
 
В этой статье рассмотрим использование HorizontalPodAutoscaler - объектов, предназначенных для автоматического масштабирования количества подов (Pods) в
  +
Replication Controller, Replica Set или Deployment, основываясь на использовании CPU (или, при поддержке custom metrics, на других метриках приложения).
  +
<BR>
 
Сразу стоит отметить, что HorizontalPodAutoscaler не может быть применен к объектам, которые не предназначены для масштабирования, например DaemonSets.
  +
Horizontal Pod Autoscaler состоит из Kubernetes ресурса (объекта) и контроллера, поведение которого описывается ресурсом.
  +
<BR>
  +
C периодичностью 15 секунд (можно изменить с помощью параметра --horizontal-pod-autoscaler-sync-period), контроллер собирает данные по использованию метрик,
  +
определенных в манифесте ресурса HorizontalPodAutoscaler.
  +
<BR>
 
Метрики собираются или с resource metrics API (метрики использования ресурсов подами) или с custom metrics API (остальные метрики, например, метрики приложения).
  +
<BR>
  +
Для каждого подконтрольного пода, контроллер собирает метрики (например, использования CPU) с resource metrics API (metrics.k8s.io, предоставляется metrics-server).
  +
<BR>
  +
Далее, происходит вычисление текущего значения использования CPU в процентах от запрошенных ресурсов (resource request) контейнерами каждого пода,
  +
после чего это значение сравнивается с “целевым” (target) значением - порогом, после которого количество подов должно быть увеличено.
  +
<BR>
 
Рассмотрим конкретный пример. Создадим файл test-hpa.yaml с описанием ресурса HorizontalPodAutoscaler такого содержания:
 
Рассмотрим конкретный пример. Создадим файл test-hpa.yaml с описанием ресурса HorizontalPodAutoscaler такого содержания:
  +
<BR>
 
  +
<PRE>
 
apiVersion: autoscaling/v2beta1
 
apiVersion: autoscaling/v2beta1
 
kind: HorizontalPodAutoscaler
 
kind: HorizontalPodAutoscaler
Строка 33: Строка 40:
 
name: cpu
 
name: cpu
 
targetAverageUtilization: 80
 
targetAverageUtilization: 80
  +
</PRE>
 
Создадим данный объект в кластере Kubernetes:
 
Создадим данный объект в кластере Kubernetes:
  +
<BR>
 
 
kubectl create -f test-hpa.yaml
 
kubectl create -f test-hpa.yaml
  +
<BR>
 
Проверим наличие объекта:
 
Проверим наличие объекта:
  +
<PRE>
 
 
kubectl get horizontalpodautoscaler
 
kubectl get horizontalpodautoscaler
 
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
 
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
 
test-hpa Deployment/test-api-deploy <unknown>/80% 10 29 0 7s
 
test-hpa Deployment/test-api-deploy <unknown>/80% 10 29 0 7s
  +
</PRE>
Спустя некоторое время, вместо <unknown>, мы должны увидеть текущее использование CPU подами в деплойменте test-api-deploy, однако в моем случае этого не произошло. Начинаем разбираться - для начала, убедимся, что metrics.k8s.io доступно:
+
Спустя некоторое время, вместо <unknown>, мы должны увидеть текущее использование CPU подами в деплойменте test-api-deploy,
  +
однако в моем случае этого не произошло.
   
  +
Начинаем разбираться - для начала, убедимся, что metrics.k8s.io доступно:
  +
<PRE>
 
kubectl get --raw "/apis/metrics.k8s.io/" | jq
 
kubectl get --raw "/apis/metrics.k8s.io/" | jq
 
{
 
{
Строка 59: Строка 72:
 
}
 
}
 
}
 
}
  +
</PRE>
 
Проверим, что метрики использования CPU доступны. Первый вариант:
 
Проверим, что метрики использования CPU доступны. Первый вариант:
  +
<PRE>
 
 
kubectl top pod | grep test-api-deploy
 
kubectl top pod | grep test-api-deploy
 
test-api-deploy-5f77b79896-2t9x9 738m 43931Mi
 
test-api-deploy-5f77b79896-2t9x9 738m 43931Mi
Строка 72: Строка 86:
 
test-api-deploy-5f77b79896-rl4bb 650m 43979Mi
 
test-api-deploy-5f77b79896-rl4bb 650m 43979Mi
 
test-api-deploy-5f77b79896-xhpbx 752m 44116Mi
 
test-api-deploy-5f77b79896-xhpbx 752m 44116Mi
  +
</PRE>
 
Второй вариант (метрики только одного конкретного пода):
 
Второй вариант (метрики только одного конкретного пода):
  +
<PRE>
 
 
kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/default/pods/test-api-deploy-5f77b79896-xhpbx | jq
 
kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/default/pods/test-api-deploy-5f77b79896-xhpbx | jq
 
{
 
{
Строка 103: Строка 118:
 
]
 
]
 
}
 
}
  +
</PRE>
 
Как видим, метрики доступны. Получим детальное описание нашего HorizontalPodAutoscaler:
 
Как видим, метрики доступны. Получим детальное описание нашего HorizontalPodAutoscaler:
  +
<PRE>
 
 
kubectl describe hpa test-hpa
 
kubectl describe hpa test-hpa
 
Name: test-hpa
 
Name: test-hpa
Строка 135: Строка 151:
 
Warning FailedComputeMetricsReplicas 4m15s (x12 over 7m2s) horizontal-pod-autoscaler failed to get cpu utilization: missing request for cpu
 
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
 
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):
 
   
  +
</PRE>
  +
 
Здесь самое важное - сообщение the HPA was unable to compute the replica count: missing request for cpu. И действительно, в манифесте развертывания (Deployment) не указаны resource requests для одного из контейнеров (с именем envoy):
  +
<PRE>
 
apiVersion: apps/v1
 
apiVersion: apps/v1
 
kind: Deployment
 
kind: Deployment
Строка 182: Строка 201:
 
name: envoy-config
 
name: envoy-config
 
name: envoy-config
 
name: envoy-config
  +
</PRE>
Важно! Если не указаны resource request хотя бы для одного из контейнеров в Replication Controller, Replica Set или Deployment, то текущее значение использование CPU подами не может быть корректно определено, и, в результате, HorizontalPodAutoscaler не будет предпринимать никаких действий по масштабированию.
 
  +
Важно! Если не указаны resource request хотя бы для одного из контейнеров в Replication Controller, Replica Set или Deployment,
 
 
то текущее значение использование CPU подами не может быть корректно определено, и, в результате, HorizontalPodAutoscaler
  +
не будет предпринимать никаких действий по масштабированию.
  +
<BR>
 
После исправления этой досадной ошибки, HorizontalPodAutoscaler, базируясь на полученных метриках, начинает масштабировать поды в развертывании:
 
После исправления этой досадной ошибки, HorizontalPodAutoscaler, базируясь на полученных метриках, начинает масштабировать поды в развертывании:
  +
<PRE>
 
 
kubectl get horizontalpodautoscaler
 
kubectl get horizontalpodautoscaler
 
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
 
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
 
test-hpa Deployment/test-api-deploy 86%/80% 10 29 29 9m10
 
test-hpa Deployment/test-api-deploy 86%/80% 10 29 29 9m10
  +
</PRE>
 
Формула, по которой HorizontalPodAutoscaler вычисляет требуемое количество реплик выглядит так:
 
Формула, по которой HorizontalPodAutoscaler вычисляет требуемое количество реплик выглядит так:
   
 
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
 
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
  +
Например,
Например, если текущее значение метрики (currentMetricValue) равно 200m, а ожидаемое (desiredMetricValue) установлено в 100m, то количество реплик будет удвоено (200.0 / 100.0 == 2.0). Если же текущее значение метрики равно всего лишь 50m, то количество реплик должно быть уменьшено вдвое (50.0 / 100.0 == 0.5). Если соотношение текущего значения метрики к ожидаемому значению достаточно близко к 1, то никаких действий не будет предпринято.
+
если текущее значение метрики (currentMetricValue) равно 200m, а ожидаемое (desiredMetricValue) установлено в 100m, то количество реплик будет удвоено (200.0 / 100.0 == 2.0). Если же текущее значение метрики равно всего лишь 50m, то количество реплик должно быть уменьшено вдвое (50.0 / 100.0 == 0.5). Если соотношение текущего значения метрики к ожидаемому значению достаточно близко к 1, то никаких действий не будет предпринято.
 
  +
<BR>
 
Так как мы указали targetAverageUtilization при описании ресурса HorizontalPodAutoscaler, то текущее значение метрики (currentMetricValue) использования CPU рассчитывается как среднее значение этой метрики для всех подов, контролируемых данным автоскейлером.
 
Так как мы указали targetAverageUtilization при описании ресурса HorizontalPodAutoscaler, то текущее значение метрики (currentMetricValue) использования CPU рассчитывается как среднее значение этой метрики для всех подов, контролируемых данным автоскейлером.
  +
<BR>
 
 
После того, как текущее значение использования CPU снизилось и оставалось низким в течении 5 минут (устанавливается с помощью параметра --horizontal-pod-autoscaler-downscale-stabilization), количество реплик было автоматически уменьшено:
 
После того, как текущее значение использования CPU снизилось и оставалось низким в течении 5 минут (устанавливается с помощью параметра --horizontal-pod-autoscaler-downscale-stabilization), количество реплик было автоматически уменьшено:
  +
<PRE>
 
 
kubectl get horizontalpodautoscaler
 
kubectl get horizontalpodautoscaler
 
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
 
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
 
test-hpa Deployment/test-api-deploy 70%/80% 20 29 23 1h
 
test-hpa Deployment/test-api-deploy 70%/80% 20 29 23 1h
  +
</PRE>
На этом все, в одной из следующих статей рассмотрим более сложный вариант автоскейлинга, базирующийся на метриках приложения.
 
  +
 
TODO: более сложный вариант автоскейлинга, базирующийся на метриках приложения.

Версия 13:18, 9 января 2024


HorizontalPodAutoscaler

В этой статье рассмотрим использование 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:
# From https://www.spinnaker.io/reference/providers/kubernetes-v2/#strategy  
    strategy.spinnaker.io/use-source-capacity: "true"
  name: test-api-deploy
spec:
#  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

TODO: более сложный вариант автоскейлинга, базирующийся на метриках приложения.