35.Horizontal Pod Autoscaling

Horizontal Pod Autoscaling

应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让service中的Pod个数自动调整呢?这就有赖于Horizontal Pod Autoscaling了,顾名思义,使Pod水平自动缩放。这个Object(跟PodDeployment一样都是API resource)也是最能体现kubernetes之于传统运维价值的地方,不再需要手动扩容了,终于实现自动化了,还可以自定义指标,没准未来还可以通过人工智能自动进化呢!

HPA属于Kubernetes中的autoscalingSIG(Special Interest Group,其下有两个feature

Kubernetes1.2版本引入HPA机制,到1.6版本之前一直是通过kubelet来获取监控指标来判断是否需要扩缩容,1.6版本之后必须通过API serverHeapseter或者kube-aggregator来获取监控指标。

对于1.6以前版本中开启自定义HPA请参考 Kubernetes autoscaling based on custom metrics without using a host port

HPA解析

Horizontal Pod Autoscaling仅适用于DeploymentReplicaSet,在v1版本中仅支持根据PodCPU利用率扩缩容,在v1alpha版本中,支持根据内存和用户自定义的metric扩缩容。

如果你不想看下面的文章可以直接看下面的示例图,组件交互、组件的配置、命令示例,都画在图上了。

Horizontal Pod AutoscalingAPI servercontroller共同实现。

horizontal-pod-autoscaler
HPA示意图

Metrics支持

在不同版本的API中,HPA autoscale时可以根据以下指标来判断:

  • autoscaling/v1
    • CPU
  • autoscaling/v1alpha1
    • 内存
    • 自定义metrics
      • kubernetes1.6起支持自定义metrics,但是必须在kube-controller-manager中配置如下两项:
        • --horizontal-pod-autoscaler-use-rest-clients=true
        • --api-server 指向 kube-aggregator,也可以使用heapster来实现,通过在启动heapster的时候指定 --api-server=true。查看 kubernetes metrics
    • 多种metrics组合
      • HPA会根据每个metric的值计算出scale的值,并将最大的那个值作为扩容的最终结果。

使用kubectl管理

Horizontal Pod Autoscaling作为API resource也可以像PodDeployment一样使用kubeclt命令管理,使用方法跟它们一样,资源名称为 hpa

kubectl create hpa
kubectl get hpa
kubectl describe hpa
kubectl delete hpa

有一点不同的是,可以直接使用 kubectl autoscale 直接通过命令行的方式创建Horizontal Pod Autoscaler

用法如下:

kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MAXPODS
[--cpu-percent=CPU] [flags] [options]

举个例子:

kubectl autoscale deployment foo --min=2 --max=5 --cpu-percent=80

Deployment foo创建 一个autoscaler,当PodCPU利用率达到80%的时候,RCreplica数在25之间。

注意 :如果为ReplicaSet创建HPA的话,无法使用rolling update,但是对于Deployment来说是可以的,因为Deployment在执行rolling update的时候会自动创建新的ReplicationController

什么是Horizontal Pod Autoscaling

利用Horizontal Pod Autoscalingkubernetes能够根据监测到的CPU利用率(或者在alpha版本中支持的应用提供的metric)自动的扩容replication controllerdeploymentreplica set

Horizontal Pod Autoscaler作为kubernetes API resourcecontroller的实现。Resource确定controller的行为。Controller会根据监测到用户指定的目标的CPU利用率周期性得调整replication controllerdeploymentreplica数量。

Horizontal Pod Autoscaler如何工作?

Horizontal Pod Autoscaler由一个控制循环实现,循环周期由controller manager中的 --horizontal-pod-autoscaler-sync-period 标志指定(默认是30

在每个周期内,controller manager会查询HorizontalPodAutoscaler中定义的metric的资源利用率。Controller managerresource metric API(每个podresource metric)或者自定义metric API(所有的metric)中获取metric

  • 每个Podresource metric(例如CPUcontroller通过resource metric API获取HorizontalPodAutoscaler中定义的每个Pod中的metric。然后,如果设置了目标利用率,controller计算利用的值与每个Pod的容器里的resource request值的百分比。如果设置了目标原始值,将直接使用该原始metric值。然后controller计算所有目标Pod的利用率或原始值(取决于所指定的目标类型)的平均值,产生一个用于缩放所需replica数量的比率。请注意,如果某些Pod的容器没有设置相关的resource request ,则不会定义PodCPU利用率,并且Aucoscaler也不会对该metric采取任何操作。
  • 对于每个Pod自定义的metriccontroller功能类似于每个Podresource metric,只是它使用原始值而不是利用率值。
  • 对于object metric,获取单个度量(描述有问题的对象,并与目标值进行比较,以产生如上所述的比率。

HorizontalPodAutoscaler控制器可以以两种不同的方式获取metric :直接的Heapster访问和REST客户端访问。

当使用直接的Heapster访问时,HorizontalPodAutoscaler直接通过API服务器的服务代理子资源查询Heapster。需要在集群上部署Heapster并在kube-system namespace中运行。

Autoscaler访问相应的replication controllerdeploymentreplica set来缩放子资源。

Scale是一个允许您动态设置副本数并检查其当前状态的接口。

API Object

Horizontal Pod AutoscalerkubernetesautoscalingAPI组中的API资源。当前的稳定版本中,只支持CPU自动扩缩容,可以在autoscaling/v1API版本中找到。

alpha版本中支持根据内存和自定义metric扩缩容,可以在 autoscaling/v2alpha1 中找到。autoscaling/v2alpha1 中引入的新字段在 autoscaling/v1 中是做为annotation而保存的。

kubectl中支持Horizontal Pod Autoscaling

Horizontal Pod Autoscaler和其他的所有API资源一样,通过 kubectl 以标准的方式支持。

我们可以使用 kubectl create 命令创建一个新的autoscaler

我们可以使用 kubectl get hpa 列出所有的autoscaler,使用 kubectl describe hpa 获取其详细信息。

最后我们可以使用 kubectl delete hpa 删除autoscaler

另外,可以使用 kubectl autoscale 命令,很轻易的就可以创建一个Horizontal Pod Autoscaler

例如,执行 kubectl autoscale rc foo —min=2 —max=5 —cpu-percent=80 命令将为replication controllerfoo创建一个autoscaler,目标的CPU利用率是 80%replica的数量介于25之间。

滚动更新期间的自动扩缩容

目前在Kubernetes中,可以通过直接管理replication controller或使用deployment对象来执行 滚动更新,该deployment对象为您管理基础replication controller

Horizontal Pod Autoscaler仅支持后一种方法:Horizontal Pod Autoscaler被绑定到deployment对象,它设置deployment对象的大小,deployment负责设置底层replication controller的大小。

Horizontal Pod Autoscaler不能使用直接操作replication controller进行滚动更新,即不能将Horizontal Pod Autoscaler绑定到replication controller,并进行滚动更新(例如使用 kubectl rolling-update

这不行的原因是,当滚动更新创建一个新的replication controller时,Horizontal Pod Autoscaler将不会绑定到新的replication controller上。

支持多个metric

Kubernetes 1.6中增加了支持基于多个metric的扩缩容。您可以使用autoscaling/v2alpha1API版本来为Horizontal Pod Autoscaler指定多个metric。然后Horizontal Pod Autoscaler controller将权衡每一个metric,并根据该metric提议一个新的scale。在所有提议里最大的那个scale将作为最终的scale

支持自定义metric

注意: Kubernetes 1.2根据特定于应用程序的metric ,通过使用特殊注释的方式,增加了对缩放的alpha支持。

Kubernetes 1.6中删除了对这些注释的支持,有利于autoscaling/v2alpha1API。虽然旧的收集自定义metric的旧方法仍然可用,但是这些metric将不可供Horizontal Pod Autoscaler使用,并且用于指定要缩放的自定义metric的以前的注释也不在受Horizontal Pod Autoscaler认可。

Kubernetes 1.6增加了在Horizontal Pod Autoscale r中使用自定义metric的支持。

您可以为autoscaling/v2alpha1API中使用的Horizontal Pod Autoscaler添加自定义metric

Kubernetes然后查询新的自定义metric API来获取相应自定义metric的值。

前提条件

为了在Horizontal Pod Autoscaler中使用自定义metric,您必须在您集群的controller manager中将 --horizontal-pod-autoscaler-use-rest-clients 标志设置为true。然后,您必须通过将controller manager的目标API server设置为API server aggregator(使用 --apiserver 标志,配置您的controller manager通过API server aggregatorAPI server通信。Resource metric API和自定义metric API也必须向API server aggregator注册,并且必须由集群上运行的API server提供。

您可以使用Heapster实现resource metric API,方法是将 --api-server 标志设置为true并运行Heapster。单独的组件必须提供自定义metric API(有关自定义metric API的更多信息,可从 k8s.io/metrics repository 获得

本节大纲

参考