如何使用 Metrics Server 配置 Kubernetes 水平 Pod Autoscaler

介绍

Kubernetes旨在提供复原力和可扩展性。 它通过部署多个具有不同资源分配的吊舱来实现这一点,为您的应用程序提供冗余. 虽然您可以根据您的需要手动增长并收缩自己的部署,但Kubernetes提供一等支持来进行点播,使用一个名为"Horizontal Pod Autoscale"(https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale)的功能. 它是一个封闭的循环系统,根据您当前的需要,自动地增长或收缩资源(应用程序 Pods). 您为每次需要自动缩放的应用程序配置创建)资源,并让它自动为您处理其余部分.

在高层次上,HPA可以做到以下几点:

  1. 联合国 它通过查询度量衡服务器来观察来自应用程序工作量(Pods)的资源请求计量。
  2. 联合国 它比较了您在HPA定义中设定的目标阈值与您应用工作量(CPU和内存)观察到的平均资源利用率. 3个 如果达到目标阈值,那么HPA会扩大您的应用部署,以满足更高的需求. 否则,如果低于阈值,它将缩小部署规模。 要了解HPA用什么逻辑来缩放您的应用程序部署,您可以从官方文档中查看[算法细节] (https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/# algorithm-details)页面. .

在帽子下,),它通过集群的控制平面内的专用控制器实现的Kubernetes控制环节。

为了工作,HPA需要一个在您的集群中可用的计量服务器来扫描所需的计量数据,例如CPU和内存利用率。一个简单的选择是Kubernetes Metrics Server。Metrics Server通过从Kubelets收集资源计量数据并通过Kubernetes API Server将其曝光到Horizontal Pod Autoscaler。如果需要,Metrics API也可以通过kubectl top访问。

在本教程中,你将:

  • 将 Metrics Server 部署到您的 Kubernetes 集群中。 * 了解如何为您的应用程序创建 horizontal Pod Autoscalers。 * 使用两个场景测试每个 HPA 设置:恒定和可变应用程序负载。

如果您正在寻找一个管理的Kubernetes托管服务,请查看我们的简单的,用于增长的管理的Kubernetes服务(https://www.digitalocean.com/products/kubernetes)。

前提条件

要遵循本教程,您将需要:

第1步:通过头盔安装Metrics服务器

您将首先将metrics-server存储库添加到您的helm包列表中,您可以使用helm repo add:

1[environment local]
2helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server

接下来,使用helm repo update来更新可用的包:

1[environment local]
2helm repo update metrics-server
1[secondary_label Output]
2Hang tight while we grab the latest from your chart repositories...
3...Successfully got an update from the "metrics-server" chart repository
4Update Complete. ⎈Happy Helming!⎈

现在你已将存储库添加到),其中包括metrics-server的配置。

要做到这一点,克隆 Kubernetes Starter Kit Git 存储库:

1[environment local]
2git clone https://github.com/digitalocean/Kubernetes-Starter-Kit-Developers.git

Metrics-server配置位于Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/metrics-server-values-v3.8.2.yaml中,您可以使用nano或您最喜欢的文本编辑器来查看或编辑:

1[environment local]
2nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/metrics-server-values-v3.8.2.yaml

它包含一些股票参数,请注意复制是一个固定的值,即2

 1[label metrics-server-values-v3.8.2.yaml]
 2## Starter Kit metrics-server configuration
 3## Ref: https://github.com/kubernetes-sigs/metrics-server/blob/metrics-server-helm-chart-3.8.2/charts/metrics-server
 4##
 5
 6# Number of metrics-server replicas to run
 7replicas: 2
 8
 9apiService:
10  # Specifies if the v1beta1.metrics.k8s.io API service should be created.
11  #
12  # You typically want this enabled! If you disable API service creation you have to
13  # manage it outside of this chart for e.g horizontal pod autoscaling to
14  # work with this release.
15  create: true
16
17hostNetwork:
18  # Specifies if metrics-server should be started in hostNetwork mode.
19  #
20  # You would require this enabled if you use alternate overlay networking for pods and
21  # API server unable to communicate with metrics-server. As an example, this is required
22  # if you use Weave network on EKS
23  enabled: false

请参阅 Metrics Server 图表页面metrics-server 的可用参数进行解释。

<美元 > [注] 注: 在将Kubernetes的部署与正在运行的Kubernetes的版本相匹配时,你需要相当小心,而且helm'图表本身也用于强制执行。 目前的计量服务器 ' 上游 " 掩体 " 图表为3.8.2,该图表部署计量服务器 ' 本身的0.6.1'版本。 从量子服务器相容性矩阵中,可以看到"0.6.x"版本. 支持 Kubernetes 1.19+'。 < $ > (美元)

在您审查了文件并做出任何更改后,您可以通过提供此文件以及头盔安装命令来部署metrics-server:

1[environment local]
2HELM_CHART_VERSION="3.8.2"
3
4helm install metrics-server metrics-server/metrics-server --version "$HELM_CHART_VERSION" \
5  --namespace metrics-server \
6  --create-namespace \
7  -f "Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/metrics-server-values-v${HELM_CHART_VERSION}.yaml"

这将部署metrics-server到您配置的 Kubernetes 集群:

 1[secondary_label Output]
 2NAME: metrics-server
 3LAST DEPLOYED: Wed May 25 11:54:43 2022
 4NAMESPACE: metrics-server
 5STATUS: deployed
 6REVISION: 1
 7TEST SUITE: None
 8NOTES:
 9***********************************************************************
10* Metrics Server                                                      *
11***********************************************************************
12  Chart version: 3.8.2
13  App version:   0.6.1
14  Image tag:     k8s.gcr.io/metrics-server/metrics-server:v0.6.1
15***********************************************************************

部署后,您可以使用helm ls来验证metrics-server已被添加到部署中:

1[environment local]
2helm ls -n metrics-server
1[secondary_label Output]
2NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
3metrics-server metrics-server 1 2022-02-24 14:58:23.785875 +0200 EET deployed metrics-server-3.8.2 0.6.1

接下来,您可以检查部署到metrics-server名称空间的所有Kubernetes资源的状态:

1[environment local]
2kubectl get all -n metrics-server

根据您部署的配置,无论是deployment.apps还是replicaset.apps值都应计算2个可用实例。

 1[secondary_label Output]
 2NAME READY STATUS RESTARTS AGE
 3pod/metrics-server-694d47d564-9sp5h 1/1 Running 0 8m54s
 4pod/metrics-server-694d47d564-cc4m2 1/1 Running 0 8m54s
 5
 6NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)   AGE
 7service/metrics-server ClusterIP 10.245.92.63   <none>        443/TCP 8m54s
 8
 9NAME READY UP-TO-DATE AVAILABLE AGE
10deployment.apps/metrics-server 2/2 2 2 8m55s
11
12NAME DESIRED CURRENT READY AGE
13replicaset.apps/metrics-server-694d47d564 2 2 2 8m55s

您现在已经在您的 Kubernetes 集群中部署了metrics-server。在下一步中,您将审查 HorizontalPodAutoscaler 定义自定义资源的一些参数。

步骤2 - 了解HPA

到目前为止,您的配置已经为部署的 ReplicaSet 实例数量使用了固定值. 在此步骤中,您将学习如何定义 HorizontalPodAutoscaler CRD,以便此值可以动态增长或缩小。

一个典型的HorizontalPodAutoscalerCRD看起来是这样的:

 1[label crd.yaml]
 2apiVersion: autoscaling/v2beta2
 3kind: HorizontalPodAutoscaler
 4metadata:
 5  name: my-app-hpa
 6spec:
 7  scaleTargetRef:
 8    apiVersion: apps/v1
 9    kind: Deployment
10    name: my-app-deployment
11  minReplicas: 1
12  maxReplicas: 3
13  metrics:
14    - type: Resource
15      resource:
16        name: cpu
17        target:
18          type: Utilization
19          averageUtilization: 50

在此配置中使用的参数如下:

  • spec.scaleTargetRef: 被扩展的资源的命名参照. * spec.minReplicas: 自动扩展器可以扩展的复制件数量的最低限制. * spec.maxReplicas: 上限. * spec.metrics.type: 用于计算所需复制件数的计量。

您有两种选择来创建应用部署的 HPA:

  1. 在现有部署中使用kubectl autoscale命令 2. 创建 HPA YAML 示例,然后使用kubectl将更改应用到您的集群中。

您将首先尝试选项# 1,使用DigitalOcean Kubernetes Starter Kit的另一个配置,它包含一个名为myapp-test.yaml的部署,该部署将通过创建一些任意的CPU负载来演示行动中的HPA。

您可以使用nano或您最喜欢的文本编辑器来查看该文件:

1[environment local]
2nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/myapp-test.yaml
 1[label myapp-test.yaml]
 2apiVersion: apps/v1
 3kind: Deployment
 4metadata:
 5  name: myapp-test
 6spec:
 7  selector:
 8    matchLabels:
 9      run: myapp-test
10  replicas: 1
11  template:
12    metadata:
13      labels:
14        run: myapp-test
15    spec:
16      containers:
17        - name: busybox
18          image: busybox
19          resources:
20            limits:
21              cpu: 50m
22            requests:
23              cpu: 20m
24          command: ["sh", "-c"]
25          args:
26            - while [ 1 ]; do
27              echo "Test";
28              sleep 0.01;
29              done

注意这个文件的最后几行. 它们包含一些壳语法,可以重复打印测试一百次每秒,以模拟负载. 一旦你完成了审查文件,你可以使用kubectl部署到你的集群中:

1[environment local]
2kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/myapp-test.yaml

接下来,使用kubectl autoscale创建一个针对myapp-test部署的HorizontalPodAutoscaler:

1[environment local]
2kubectl autoscale deployment myapp-test --cpu-percent=50 --min=1 --max=3

请注意传递给这个命令的参数 - 这意味着每次CPU利用率达到50%时,您的部署都会在13复制品之间进行扩展。

您可以通过运行kubectl get hpa来检查是否创建了 HPA 资源:

1[environment local]
2kubectl get hpa

输出的目标列最终会显示当前使用率% / 目标使用率%的数字。

1[secondary_label Output]
2NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
3myapp-test Deployment/myapp-test 240%/50%   1 3 3 52s

<$>[注] 注: )。这是正常的,因为HPA需要随着时间的推移收集平均值,并且在第一个15秒间隔之前不会有足够的数据。

您还可以使用kubectl 描述来观察 HPA 生成的日志事件:

1[environment local]
2kubectl describe hpa myapp-test
 1[secondary_label Output]
 2Name:                                                  myapp-test
 3Namespace:                                             default
 4Labels:                                                <none>
 5Annotations:                                           <none>
 6CreationTimestamp:                                     Mon, 28 May 2022 10:10:50 -0800
 7Reference:                                             Deployment/myapp-test
 8Metrics:                                               ( current / target )
 9  resource cpu on pods  (as a percentage of request):  240% (48m) / 50%
10Min replicas:                                          1
11Max replicas:                                          3
12Deployment pods:                                       3 current / 3 desired
13...
14Events:
15  Type Reason Age From Message
16  ----    ------             ----  ----                       -------
17  Normal SuccessfulRescale 17s horizontal-pod-autoscaler New size: 2; reason: cpu resource utilization (percentage of request) above target
18  Normal SuccessfulRescale 37s horizontal-pod-autoscaler New size: 3; reason: cpu resource utilization (percentage of request) above target

在生产场景中,你通常应该使用一个专用YAML宣言来定义每个HPA。这样,你可以通过将宣言致力于Git仓库来跟踪变化,并根据需要进行修改。

在继续前,删除myapp-test部署和相应的HPA资源:

1[environment local]
2kubectl delete hpa myapp-test
3kubectl delete deployment myapp-test

第3步:通过Metrics Server自动扩展应用程序

在这最后一步中,您将尝试两种不同的方式来生成服务器负载和扩展通过YAML表达式:

  1. 一个应用程序部署,通过执行一些CPU密集的计算来创建恒定的负载 2. 一个壳脚本通过对Web应用程序执行快速连续的HTTP调用来模拟该外部负载。

连续负载测试

在这种情况下,你将创建一个使用Python实现的样本应用程序,该应用程序执行一些CPU密集的计算。类似于上一个步骤的壳脚本,这个Python代码包含在启动套件的示例 manifests之一中。

1[environment local]
2nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/constant-load-deployment-test.yaml
 1[label constant-load-deployment-test.yaml]
 2---
 3apiVersion: v1
 4kind: ConfigMap
 5metadata:
 6  name: python-test-code-configmap
 7data:
 8  entrypoint.sh: |-
 9    #!/usr/bin/env python
10
11    import math
12
13    while True:
14      x = 0.0001
15      for i in range(1000000):
16        x = x + math.sqrt(x)
17        print(x)
18      print("OK!")
19
20---
21apiVersion: apps/v1
22kind: Deployment
23metadata:
24  name: constant-load-deployment-test
25spec:
26  selector:
27    matchLabels:
28      run: python-constant-load-test
29  replicas: 1
30  template:
31    metadata:
32      labels:
33        run: python-constant-load-test
34    spec:
35      containers:
36        - name: python-runtime
37          image: python:alpine3.15
38          resources:
39            limits:
40              cpu: 50m
41            requests:
42              cpu: 20m
43          command:
44            - /bin/entrypoint.sh
45          volumeMounts:
46            - name: python-test-code-volume
47              mountPath: /bin/entrypoint.sh
48              readOnly: true
49              subPath: entrypoint.sh
50      volumes:
51        - name: python-test-code-volume
52          configMap:
53            defaultMode: 0700
54            name: python-test-code-configmap

Python 代码,该代码反复生成任意的平方根,是上面提到的。部署将收集一个托管所需的 python 运行时间的 docker 图像,然后将一个ConfigMap附加到托管先前显示的样本 Python 脚本的Pod应用程序。

首先,为此部署创建一个单独的名称空间(为了更好地观察),然后通过kubectl部署它:

1[environment local]
2kubectl create ns hpa-constant-load
3
4kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/constant-load-deployment-test.yaml -n hpa-constant-load
1[secondary_label Output]
2configmap/python-test-code-configmap created
3deployment.apps/constant-load-deployment-test created

<$>[注] 注: 示例 [部署](资产/示例/hpa/metrics-server/constant-load-deployment-test.yaml# L37)也为示例应用程序 Pods 配置资源请求限制,这很重要,因为 HPA 逻辑依赖于为您的 Pods 设置资源请求限制。

检查部署是否成功创建,并且它正在运行:

1[environment local]
2kubectl get deployments -n hpa-constant-load
1[secondary_label Output]
2NAME READY UP-TO-DATE AVAILABLE AGE
3constant-load-deployment-test 1/1 1 1 8s

接下来,您需要在这个集群中部署另一个 HPA. 在 constant-load-hpa-test.yaml 中有一个与此场景匹配的示例,您可以使用 nano 或您最喜欢的文本编辑器打开:

1[environment local]
2nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/constant-load-hpa-test.yaml -n hpa-constant-load
 1[label constant-load-hpa-test.yaml]
 2apiVersion: autoscaling/v2beta2
 3kind: HorizontalPodAutoscaler
 4metadata:
 5  name: constant-load-test
 6spec:
 7  scaleTargetRef:
 8    apiVersion: apps/v1
 9    kind: Deployment
10    name: constant-load-deployment-test
11  minReplicas: 1
12  maxReplicas: 3
13  metrics:
14    - type: Resource
15      resource:
16        name: cpu
17        target:
18          type: Utilization
19          averageUtilization: 50

通过kubectl部署:

1[environment local]
2kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/constant-load-hpa-test.yaml -n hpa-constant-load

这将创建一个HPA资源,瞄准样本Python部署,您可以通过kubectl get hpa检查恒定负载测试的HPA状态:

1[environment local]
2kubectl get hpa constant-load-test -n hpa-constant-load

请注意参考列针对恒定负载部署测试,以及目标列显示当前 CPU 资源请求与门槛值,如上一个示例。

1[secondary_label Output]
2NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
3constant-load-test Deployment/constant-load-deployment-test 255%/50%   1 3 3 49s

您也可能注意到REPLICAS列值从1增加到3用于示例应用部署,正如 HPA CRD 规格中所述。

外部负载测试

一个更有趣和现实的场景是观察外部负载创建的地方. 对于这个最终的示例,您将使用不同的名称空间和示例集,以避免从上一个测试中重复使用任何数据。

此示例将使用(https://github.com/datawire/quote)样本服务器。每次向该服务器发送 HTTP 请求时,它会作为回应发送不同的请求。 您将通过每 1 分钟发送 HTTP 请求来创建集群的负载。 此部署包含在 quote_deployment.yaml 中。 使用 nano` 或您最喜欢的文本编辑器来审查此文件:

1[environment local]
2nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/quote_deployment.yaml
 1[label quote_deployment.yaml]
 2---
 3apiVersion: apps/v1
 4kind: Deployment
 5metadata:
 6  name: quote
 7spec:
 8  replicas: 1
 9  selector:
10    matchLabels:
11      app: quote
12  template:
13    metadata:
14      labels:
15        app: quote
16    spec:
17      containers:
18        - name: quote
19          image: docker.io/datawire/quote:0.4.1
20          ports:
21            - name: http
22              containerPort: 8080
23          resources:
24            requests:
25              cpu: 100m
26              memory: 50Mi
27            limits:
28              cpu: 200m
29              memory: 100Mi
30
31---
32apiVersion: v1
33kind: Service
34metadata:
35  name: quote
36spec:
37  ports:
38    - name: http
39      port: 80
40      targetPort: 8080
41  selector:
42    app: quote

请注意,实际的 HTTP 查询脚本不包含在这个 manifests 中 - 这个 manifests 只提供一个应用程序现在可以运行查询. 当您完成审查文件时,创建 quote的名称空间和部署使用 kubectl:

1[environment local]
2kubectl create ns hpa-external-load
3
4kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/quote_deployment.yaml -n hpa-external-load

检查引用应用程序部署和服务是否正在运行:

1[environment local]
2kubectl get all -n hpa-external-load
 1[secondary_label Output]
 2NAME READY STATUS RESTARTS AGE
 3pod/quote-dffd65947-s56c9 1/1 Running 0 3m5s
 4
 5NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)   AGE
 6service/quote ClusterIP 10.245.170.194   <none>        80/TCP 3m5s
 7
 8NAME READY UP-TO-DATE AVAILABLE AGE
 9deployment.apps/quote 1/1 1 1 3m5s
10
11NAME DESIRED CURRENT READY AGE
12replicaset.apps/quote-6c8f564ff 1 1 1 3m5s

接下来,您将创建HPA用于引文的部署。 此设置在quote-deployment-hpa-test.yaml中。 在nano或您最喜欢的文本编辑器中查看文件:

1[environment local]
2nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/quote-deployment-hpa-test.yaml
 1[label quote-deployment-hpa-test.yaml]
 2apiVersion: autoscaling/v2beta2
 3kind: HorizontalPodAutoscaler
 4metadata:
 5  name: external-load-test
 6spec:
 7  scaleTargetRef:
 8    apiVersion: apps/v1
 9    kind: Deployment
10    name: quote
11  behavior:
12    scaleDown:
13      stabilizationWindowSeconds: 60
14  minReplicas: 1
15  maxReplicas: 3
16  metrics:
17    - type: Resource
18      resource:
19        name: cpu
20        target:
21          type: Utilization
22          averageUtilization: 20

请注意,在这种情况下,CPU利用率资源度量表("20%`")有不同的阈值设定. 还有一个不同的缩放行为。 这种配置改变了 " 下.稳定Window Seconds " 行为,并将其设定为下等值为 " 60 " 秒。 这在实际中并不总是需要的,但在这种情况下,你可能想要加快事情的进度,以更快地看到自动缩放器如何进行缩放动作. 默认情况下, " Horizontal PodAutoscale " 的冷却期为5分钟。 这在多数情况下都足够了,在复制品规模扩大时应可避免波动.

当你准备好时,使用kubectl部署它:

1[environment local]
2kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/quote-deployment-hpa-test.yaml -n hpa-external-load

现在,检查HPA资源是否存在并活着:

1[environment local]
2kubectl get hpa external-load-test -n hpa-external-load
1[secondary_label Output]
2NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
3external-load-test Deployment/quote 1%/20%    1 3 1 108s

最后,您将运行实际的 HTTP 查询,使用壳脚本 `quote_service_load_test.sh. 此壳脚本之前没有嵌入到显示中的原因是,您可以观察它在您的集群中运行,同时直接登录到您的终端。

1[environment local]
2nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/scripts/quote_service_load_test.sh
 1[label quote_service_load_test.sh]
 2#!/usr/bin/env sh
 3
 4echo
 5echo "[INFO] Starting load testing in 10s..."
 6sleep 10
 7echo "[INFO] Working (press Ctrl+C to stop)..."
 8kubectl run -i --tty load-generator \
 9    --rm \
10    --image=busybox \
11    --restart=Never \
12    -n hpa-external-load \
13    -- /bin/sh -c "while sleep 0.001; do wget -q -O- http://quote; done" > /dev/null 2>&1
14echo "[INFO] Load testing finished."

要进行此演示,请打开两个单独的终端窗口. 首先,运行quote_service_load_test.sh壳脚本:

1[environment local]
2Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/scripts/quote_service_load_test.sh

接下来,在第二个窗口中,使用HPA资源上的w标志运行一个kubectl观看命令:

1[environment local]
2kubectl get hpa -n hpa-external-load -w

您应该看到负载向上滚动并自动扩展:

1[secondary_label Output]
2NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
3external-load-test Deployment/quote 1%/20%    1 3 1 2m49s
4external-load-test Deployment/quote 29%/20%   1 3 1 3m1s
5external-load-test Deployment/quote 67%/20%   1 3 2 3m16s

您可以观察自动缩放器在加载时如何启动,并将引用服务器部署副本设置增加到更高的值。一旦加载生成器脚本被停止,就会有一个冷却期,然后在1分钟或更长时间后,副本集被降至1的初始值。

结论

在本教程中,您部署并观察了使用Kubernetes Metrics Server的Horizontal Pod Autoscaling(HPA)的行为,在几个不同的场景下。

Metrics Server有一个显著的局限性,因为它不能提供超出CPU或内存用量的任何度量. 您可以进一步审查量子服务器文档,以了解如何在其使用的情况下工作。 如果需要使用任何其他度量衡(如磁盘用量或网络负载)来缩放,可以通过一个特殊的适配器来使用Prometheus,命名为Prometheus-adapter.

Published At
Categories with 技术
comments powered by Disqus