Horizontal Pod Autoscaling (HPA) 可以根据 CPU 使用率或应用自定义 metrics 自动扩展 Pod 数量(支持 replication controller、deployment 和 replica set )。
- 控制管理器每隔 30s(可以通过 
--horizontal-pod-autoscaler-sync-period修改)查询 metrics 的资源使用情况 支持三种 metrics 类型
- 预定义 metrics(比如 Pod 的 CPU)以利用率的方式计算
 - 自定义的 Pod metrics,以原始值(raw value)的方式计算
 - 自定义的 object metrics
 
- 支持两种 metrics 查询方式:Heapster 和自定义的 REST API
 - 支持多 metrics
 
注意:
- 本章是关于 Pod 的自动扩展,而 Node 的自动扩展请参考 Cluster AutoScaler。
 - 在使用 HPA 之前需要 确保已部署好 metrics-server。
 
API 版本对照表
| Kubernetes 版本 | autoscaling API 版本 | 支持的 metrics | 
|---|---|---|
| v1.5+ | autoscaling/v1 | CPU | 
| v1.6+ | autoscaling/v2beta1 | Memory及自定义 | 
示例
# 创建 pod 和 service$ kubectl run php-apache --image=k8s.gcr.io/hpa-example --requests=cpu=200m --expose --port=80service "php-apache" createddeployment "php-apache" created# 创建 autoscaler$ kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10deployment "php-apache" autoscaled$ kubectl get hpaNAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache/scale 0% / 50% 1 10 1 18s# 增加负载$ kubectl run -i --tty load-generator --image=busybox /bin/shHit enter for command prompt$ while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done# 过一会就可以看到负载升高了$ kubectl get hpaNAME REFERENCE TARGET CURRENT MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache/scale 305% / 50% 305% 1 10 1 3m# autoscaler 将这个 deployment 扩展为 7 个 pod$ kubectl get deployment php-apacheNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEphp-apache 7 7 7 7 19m# 删除刚才创建的负载增加 pod 后会发现负载降低,并且 pod 数量也自动降回 1 个$ kubectl get hpaNAME REFERENCE TARGET MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache/scale 0% / 50% 1 10 1 11m$ kubectl get deployment php-apacheNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEphp-apache 1 1 1 1 27m
自定义 metrics
使用方法
- 控制管理器开启 
--horizontal-pod-autoscaler-use-rest-clients - 控制管理器配置的 
--master或者--kubeconfig - 在 API Server Aggregator 中注册自定义的 metrics API,如 https://github.com/kubernetes-incubator/custom-metrics-apiserver 和 https://github.com/kubernetes/metrics
 
注:可以参考 k8s.io/metics 开发自定义的 metrics API server。
比如 HorizontalPodAutoscaler 保证每个 Pod 占用 50% CPU、1000pps 以及 10000 请求 / s:
HPA 示例
apiVersion: autoscaling/v1kind: HorizontalPodAutoscalermetadata:name: php-apachenamespace: defaultspec:scaleTargetRef:apiVersion: apps/v1beta1kind: Deploymentname: php-apacheminReplicas: 1maxReplicas: 10metrics:- type: Resourceresource:name: cputargetAverageUtilization: 50- type: Podspods:metricName: packets-per-secondtargetAverageValue: 1k- type: Objectobject:metricName: requests-per-secondtarget:apiVersion: extensions/v1beta1kind: Ingressname: main-routetargetValue: 10kstatus:observedGeneration: 1lastScaleTime: <some-time>currentReplicas: 1desiredReplicas: 1currentMetrics:- type: Resourceresource:name: cpucurrentAverageUtilization: 0currentAverageValue: 0
状态条件
v1.7+ 可以在客户端中看到 Kubernetes 为 HorizontalPodAutoscaler 设置的状态条件 status.conditions,用来判断 HorizontalPodAutoscaler 是否可以扩展(AbleToScale)、是否开启扩展(ScalingActive)以及是否受到限制(ScalingLimitted)。
$ kubectl describe hpa cm-testName: cm-testNamespace: promLabels: <none>Annotations: <none>CreationTimestamp: Fri, 16 Jun 2017 18:09:22 +0000Reference: ReplicationController/cm-testMetrics: (current / target)"http_requests" on pods: 66m / 500mMin replicas: 1Max replicas: 4ReplicationController pods: 1 current / 1 desiredConditions:Type Status Reason Message---- ------ ------ -------AbleToScale True ReadyForNewScale the last scale time was sufficiently old as to warrant a new scaleScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from pods metric http_requestsScalingLimited False DesiredWithinRange the desired replica count is within the acceptable rangeEvents:
HPA 最佳实践
- 为容器配置 CPU Requests
 - HPA 目标设置恰当,如设置 70% 给容器和应用预留 30% 的余量
 - 保持 Pods 和 Nodes 健康(避免 Pod 频繁重建)
 - 保证用户请求的负载均衡
 - 使用 
kubectl top node和kubectl top pod查看资源使用情况 
