VPA和HPA

云原生:使用HPA和VPA实现集群扩缩容 - Hello-Brand - 博客园 (cnblogs.com)

K8s官网介绍

Pod 水平自动扩缩 | Kubernetes

Pod水平自动扩容

在 Kubernetes 中,HorizontalPodAutoscaler 自动更新工作负载资源 (例如 Deployment 或者 StatefulSet), 目的是自动扩缩工作负载以满足需求。

水平扩缩意味着对增加的负载的响应是部署更多的 Pod。 这与“垂直(Vertical)”扩缩不同,对于 Kubernetes, 垂直扩缩意味着将更多资源(例如:内存或 CPU)分配给已经为工作负载运行的 Pod。

如果负载减少,并且 Pod 的数量高于配置的最小值, HorizontalPodAutoscaler 会指示工作负载资源(Deployment、StatefulSet 或其他类似资源)缩减。

水平 Pod 自动扩缩不适用于无法扩缩的对象(例如:DaemonSet。)

HorizontalPodAutoscaler 被实现为 Kubernetes API 资源和控制器

资源决定了控制器的行为。 在 Kubernetes 控制平面内运行的水平 Pod 自动扩缩控制器会定期调整其目标(例如:Deployment)的所需规模,以匹配观察到的指标, 例如,平均 CPU 利用率、平均内存利用率或你指定的任何其他自定义指标。

如何工作?

kube-controller-manager

Kubernetes 控制器管理器是一个守护进程,内嵌随 Kubernetes 一起发布的核心控制回路。 在机器人和自动化的应用中,控制回路是一个永不休止的循环,用于调节系统状态。 在 Kubernetes 中,每个控制器是一个控制回路,通过 API 服务器监视集群的共享状态, 并尝试进行更改以将当前状态转为期望状态。 目前,Kubernetes 自带的控制器例子包括副本控制器、节点控制器、命名空间控制器和服务账号控制器等。

Kubernetes将水平的Pod自动扩容实现为一个简写运行的控制回路(它不是一个连续的过程)间隔youkube-controller-manager的--horizontal-pod-autoscaler-sync-period参数设置(默认间隔为15秒)。

每个时间段内,控制器管理器都会根据每个HorizontalPodAutoscaler 定义指定的指标查询资源利用率。控制器管理器找的哦啊由scaletargetRef定义的目标资源,然后根据目标资源的.spec .selector标签选择pod,并从资源指标API(针对每个Pod的资源指标)或自定义获取指标API(适用于所有其他指标)

  • 对于按 Pod 统计的资源指标(如 CPU),控制器从资源指标 API 中获取每一个 HorizontalPodAutoscaler 指定的 Pod 的度量值,如果设置了目标使用率,控制器获取每个 Pod 中的容器资源使用情况, 并计算资源使用率。如果设置了 target 值,将直接使用原始数据(不再计算百分比)。 接下来,控制器根据平均的资源使用率或原始值计算出扩缩的比例,进而计算出目标副本数。

需要注意的是,如果 Pod 某些容器不支持资源采集,那么控制器将不会使用该 Pod 的 CPU 使用率。 下面的算法细节章节将会介绍详细的算法。

  • 如果 Pod 使用自定义指示,控制器机制与资源指标类似,区别在于自定义指标只使用原始值,而不是使用率。
  • 如果 Pod 使用对象指标和外部指标(每个指标描述一个对象信息)。 这个指标将直接根据目标设定值相比较,并生成一个上面提到的扩缩比例。 在 autoscaling/v2 版本 API 中,这个指标也可以根据 Pod 数量平分后再计算。

HorizontalPodAutoscaler 的常见用途是将其配置为从聚合 APImetrics.k8s.iocustom.metrics.k8s.ioexternal.metrics.k8s.io)获取指标。 metrics.k8s.io API 通常由名为 Metrics Server 的插件提供,需要单独启动。有关资源指标的更多信息, 请参阅 Metrics Server

Metrics API 的支持解释了这些不同 API 的稳定性保证和支持状态。

HorizontalPodAutoscaler 控制器访问支持扩缩的相应工作负载资源(例如:Deployment 和 StatefulSet)。 这些资源每个都有一个名为 scale 的子资源,该接口允许你动态设置副本的数量并检查它们的每个当前状态。 有关 Kubernetes API 子资源的一般信息, 请参阅 Kubernetes API 概念

扩缩容介绍

VPA(Vertical Pod Autoscaler)和HPA(Horizontal Pod Autoscaler)都是Kubernetes中的自动扩展功能,但它们的作用对象和扩展方式不同。

HPA(纵向)的作用对象是Pod的数量。 它通过监控CPU使用率、内存使用率等指标,根据预设的阈值自动调整Pod的数量(即当个集群副本的数量)。当Pod的CPU和内存使用率超过阈值时,HPA会自动增加Pod的数量;当使用率下降时,HPA会自动减少Pod的数量。

VPA的作用对象是Pod的资源需求,如CPU、内存等。 它通过监控Pod的资源使用情况,根据实际的资源需求自动调整Pod的资源限制和请求。当Pod的资源使用率高于资源请求时,VPA会自动增加Pod的资源Request和Limit;当资源使用率下降时,VPA会自动减少Pod的资源Requist和Limit。这种方式可以帮助优化资源利用率,避免资源浪费。

HPA实现详解

HPA(纵向)的作用对象是Pod的数量。可针对CPU使用率、内存使用率进行扩缩容配置,会根据期望指标,会触发扩容或者缩容,若同时有多个指标,会取Max值。

解读下

  1. 设计HPA资源,包含实现扩容的条件
  2. 策略Yaml应用到HPA控制器中
  3. HPA控制器监听Prometheus,获取多个Metrix指标,如内存、CPU、连接数等
  4. 当监听的数据值大于等于扩容条件的阈值的时候,执行扩容操作
  5. 修改 replication controller, deployment, replica set, stateful set 中的pod数量
  6. 控制器定期调整 副本控制器(replica set) 或 部署(deploy) 中副本的数量

算法解析

desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]

举例

apiVersion: autoscaling/v2beta2  
kind: HorizontalPodAutoscaler  
metadata:  
  name: hpa-example  
spec:  
  scaleTargetRef:  
    apiVersion: apps/v1  
    kind: Deployment  
    name: hpa-example  
  minReplicas: 10  # Pod副本数下限
  maxReplicas: 20  # Pod副本数上限
  metrics:  
  - type: Resource  
    resource:  
      name: cpu  
      target:  
        type: Utilization  
        averageUtilization: 60  # 当CPU利用率大于60%或者内存占用大于60%的时候,执行调整
  1. 假设当前指标:CPU利用率 70%
  2. 期望指标:CPU利用率60%
  3. 假设当前副本数:10
  4. 期望副本数:ceil(10*(70/60))=12
  5. 最终总的Pod副本数应该是12,即扩容数量为2
  6. 注意扩容和缩容幅度不能超过 HorizontalPodAutoscaler 资源中的副本上下限

VPA实现

因为VPA影响的是Pod的Request和Limit这两个参数,所以我们先了解下这两个属性的含义。
1. Request表示容器在运行过程中所需的最小资源量,即容器启动时的资源保证。
当Pod被调度到节点上时,Kubernetes会确保该节点上至少有足够的资源来满足Pod中所有容器的Request值。如果节点的可用资源无法满足Pod的Request值,则不会被调度到该节点上,而是保持在Pending状态,直到找到满足条件的节点为止。
因此,合理设置Request值可以确保Pod的稳定性和可靠性。

2. Limit则表示容器在运行过程中可以使用的最大资源量,即容器可以消耗的资源上限。
如果容器的实际资源使用量超过了Limit值,Kubernetes会采取相应的措施来限制容器的资源使用,例如限制CPU使用率、杀死进程等,以确保不会因资源不足而导致系统崩溃或性能下降。
通过设置Limit值,可以有效地防止单个容器或整个Pod占用过多的资源,从而影响整个集群的性能和稳定性。

apiVersion: v1
kind: Pod
  - apiVersion: v1
  name: xx-default-756gh8588cc
  namespace: xx-ns
spec:  
  containers:    
    name: xx-default
    resources:
      limits:  # 对应上限最大值
        cpu: "2"
        memory: 8G
      requests:  # 对应下限最小值
        cpu: 200m
        memory: 500Mi

而 VPA 是Kubernetes的一种自动调整Pod资源请求(Request)配额的工具。通过VPA,您可以根据Pod的实际资源使用情况动态地调整其CPU和内存资源请求(Request),以实现更精细的资源管理和更好的资源利用率。
简单理解就是 取服务一定周期内(如8天内) CPU 和内存资源用量的 TP90 分位数据作为推荐值,可以参考kubernetes的算法

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: myapp-vpa-default
  namespace: xx-ns
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-vpa-default
  updatePolicy:
    updateMode: "Off"  # 不直接进行修改
status:
  recommendation:
    containerRecommendations:
    - containerName: msg-index-default
      lowerBound: # 下限值
        cpu: 480m
        memory: "7117753323"
      target:  # 推荐值
        cpu: 930m
        memory: "8701517761"
      uncappedTarget:
        cpu: 930m
        memory: "8701517761"
      upperBound: # 上限值
        cpu: 1100m
        memory: "8841153193"

在这个配置中,我们定义了一个名为myapp-vpa的VPA,它将调整名为myapp的Deployment中的Pod的资源。
从输出信息可以看出,VPA对Pod给出了推荐值:Cpu: 930m,Memory: 8Gi,因为 updatePolicy 策略设置了updateMode: "Off",所以不会主动更新Pod。

上面的案例可以通过下面的图进行演进:通过VPA的推荐,我们将Request值从 200m的CPU 和 500Mi 的内存,调整为 1 Core 的CPU 和 8Gi 的内存。

调优完成之后,资源分配更加合理,资源更充足,性能、稳定性更高。

总结

总的来说,HPA是通过自动调整Pod的数量来应对负载压力,而VPA是通过自动调整Pod的资源需求来优化资源利用率。它们可以配合使用,实现更加精细的自动扩展策略。保证流量动态变化的业务场景中实现资源的弹性伸缩,实现资源的最优合理性利用。

Last modification:May 23, 2024
如果觉得我的文章对你有用,请随意赞赏