HPA全名Horizontal Pod Autoscaling,既Pod水平自动伸缩。其基本原理的监控分析RC或者Deployment控制的所有的Pod的负载情况来确定是否需要调整Pod的副本数。

HPA在kubernetes集群中被设计成了一个controller,我们可以直接通过kubectl autoscale命令来创建一个HPA对象,HPA controller默认15s轮询一次,查询指定的资源中的Pod的使用率,并于创建时设定的指标做对比,从而实现自动伸缩的功能。

目前HPA可以从两个地方获取数据:

  1. Heapster:仅支持CPU使用率,需要安装https://github.com/kubernetes/heapster
  2. 自定义监控
  3. metrics-server

注意: 1、自 Kubernetes 1.11起,从 Heapster 获取指标特性已废弃。

工作原理

  • K8s通过HPA,基于获取到的metrics(CPU utilization, custom metrics) value,对rc, deployment管理的pods进行自动伸缩。
  • HPA Controller周期性(默认每30s一次,可通过kube-controller-manager的flag--horizontal-pod-autoscaler-sync-period进行设置)的调整对应的rc, deployment中的replicas数量,使得指定的metrics value能匹配用户指定的target utilization value。
  • 在每个HPA Controller的处理周期中,kube-controller-manager都去查询HPA中定义的metrics的utilization。查询方式根据metric类型不同而不同:
    • 如果metric type是resource metrics,则通过resource metrics API查询。
    • 如果metric type属于custom metrics,则通过custom metrics API查询。
  • 计算伸缩比例算法:

    • 对于resource metrics,比如CPU,HPA Controller获取HPA中指定的metrics,如果HPA中设定了target utilization,则HPA Controller会将获取到的metrics除于对应的容器的resource request值作为监测到的当前pod的resource utilization。如此计算完所有HPA对应的pods后,对该resource utilization values取平均值。最后将平均值除于定义的target utilization,得到伸缩的比例。

      注意:如果HPA对应的某些pods中的容器没有定义对应的resource request,则HPA不会对这些pods进行scale。

    • 对于custome metrics,HPA Controller的伸缩算法几乎与resource metrics一样,不同的是:此时是根据custome metrics API查询到的metrics value对比target metics value计算得到的,而不是通过utilization计算得到的。

  • HPA与rc, deployment, pod的关系如下图所示。
    • HPA通过Scale sub-resource接口,对RC和Deployment的replicas进行控制。
    • HPA最终对Pod副本数的控制终归还是通过RC和Deployment控制器。

HPA - 图1
HPA Controller有两种方式获取metrics:

  • direct Heapster access: 用于对resource metrics的监控,需要提前在kube-system namespace中部署Heapster。
  • REST client access: 用于对custom metrics的监控,需要设置kube-controller-manager的--horizontal-pod-autoscaler-use-rest-clients flag为true。

算法细节

从最基本的角度来看,pod 水平自动缩放控制器跟据当前指标和期望指标来计算缩放比例。

  1. 期望副本数 = ceil[当前副本数 * ( 当前指标 / 期望指标 )]

例如,当前指标为200m,目标设定值为100m,那么由于200.0 / 100.0 == 2.0, 副本数量将会翻倍。 如果当前指标为50m,副本数量将会减半,因为50.0 / 100.0 == 0.5。 如果计算出的缩放比例接近1.0(跟据--horizontal-pod-autoscaler-tolerance 参数全局配置的容忍值,默认为0.1), 将会放弃本次缩放。

例子:创建一个Deployment的Pod,然后利用HPA来实现自动扩缩容。
1、创建一个Deployment的YAML文件

  1. apiVersion: apps/v1beta2
  2. kind: Deployment
  3. metadata:
  4. name: nginx-deploy-hpa
  5. labels:
  6. app: nginx-demo
  7. spec:
  8. revisionHistoryLimit: 15
  9. selector:
  10. matchLabels:
  11. app: nginx
  12. template:
  13. metadata:
  14. labels:
  15. app: nginx
  16. spec:
  17. containers:
  18. - name: my-nginx
  19. image: nginx:1.7.9
  20. imagePullPolicy: IfNotPresent
  21. ports:
  22. - containerPort: 80

2、创建Deployment

  1. # kubectl apply -f nginx-deplo.yaml

3、创建HPA,用kubectl autoscale命令创建

  1. # kubectl autoscale deployment nginx-deploy-hpa --cpu-percent=10 --max=10
  2. horizontalpodautoscaler.autoscaling/nginx-deploy-hpa autoscaled
  3. # kubectl get hpa
  4. NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
  5. nginx-deploy-hpa Deployment/nginx-deploy-hpa <unknown>/10% 1 10 1 27s

YAML文件格式如下:

  1. apiVersion: autoscaling/v1
  2. kind: HorizontalPodAutoscaler
  3. metadata:
  4. name: hpa-demo
  5. spec:
  6. maxReplicas: 10
  7. minReplicas: 1
  8. scaleTargetRef:
  9. apiVersion: apps/v1
  10. kind: Deployment
  11. name: nginx-deploy
  12. targetCPUUtilizationPercentage: 55