kubernetes-handbook/concepts/horizontal-pod-autoscaling.md

150 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Horizontal Pod Autoscaling
应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让 service 中的 Pod 个数自动调整呢?这就有赖于 Horizontal Pod Autoscaling 了,顾名思义,使 Pod 水平自动缩放。这个 Object跟 Pod、Deployment 一样都是 API resource也是最能体现 kubernetes 之于传统运维价值的地方,不再需要手动扩容了,终于实现自动化了,还可以自定义指标,没准未来还可以通过人工智能自动进化呢!
HPA 属于 Kubernetes 中的 **autoscaling** SIGSpecial Interest Group其下有两个 feature
- [Arbitrary/Custom Metrics in the Horizontal Pod Autoscaler#117](https://github.com/kubernetes/features/issues/117)
- [Monitoring Pipeline Metrics HPA API #118](https://github.com/kubernetes/features/issues/118)
Kubernetes 自 1.2 版本引入 HPA 机制,到 1.6 版本之前一直是通过 kubelet 来获取监控指标来判断是否需要扩缩容1.6 版本之后必须通过 API server、Heapseter 或者 kube-aggregator 来获取监控指标。
对于 1.6 以前版本中开启自定义 HPA 请参考 [Kubernetes autoscaling based on custom metrics without using a host port](https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac)。
## HPA 解析
Horizontal Pod Autoscaling 仅适用于 Deployment 和 ReplicaSet在 v1 版本中仅支持根据 Pod 的 CPU 利用率扩缩容,在 v1alpha 版本中,支持根据内存和用户自定义的 metric 扩缩容。
如果你不想看下面的文章可以直接看下面的示例图,组件交互、组件的配置、命令示例,都画在图上了。
Horizontal Pod Autoscaling 由 API server 和 controller 共同实现。
![horizontal-pod-autoscaler](../images/horizontal-pod-autoscaler.png)
## 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](https://github.com/kubernetes/kube-aggregator),也可以使用 heapster 来实现,通过在启动 heapster 的时候指定 `--api-server=true`。查看 [kubernetes metrics](https://github.com/kubernetes/metrics)
- 多种 metrics 组合
- HPA 会根据每个 metric 的值计算出 scale 的值,并将最大的那个值作为扩容的最终结果。
## 使用 kubectl 管理
Horizontal Pod Autoscaling 作为 API resource 也可以像 Pod、Deployment 一样使用 kubeclt 命令管理,使用方法跟它们一样,资源名称为 `hpa`
```bash
kubectl create hpa
kubectl get hpa
kubectl describe hpa
kubectl delete hpa
```
有一点不同的是,可以直接使用 `kubectl autoscale` 直接通过命令行的方式创建 Horizontal Pod Autoscaler。
用法如下:
```bash
kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MAXPODS
[--cpu-percent=CPU] [flags] [options]
```
举个例子:
```bash
kubectl autoscale deployment foo --min=2 --max=5 --cpu-percent=80
```
为 Deployment foo 创建 一个 autoscaler当 Pod 的 CPU 利用率达到 80% 的时候RC 的 replica 数在 2 到 5 之间。
**注意** :如果为 ReplicaSet 创建 HPA 的话,无法使用 rolling update但是对于 Deployment 来说是可以的,因为 Deployment 在执行 rolling update 的时候会自动创建新的 ReplicationController。
## 什么是 Horizontal Pod Autoscaling
利用 Horizontal Pod Autoscalingkubernetes 能够根据监测到的 CPU 利用率(或者在 alpha 版本中支持的应用提供的 metric自动的扩容 replication controllerdeployment 和 replica set。
Horizontal Pod Autoscaler 作为 kubernetes API resource 和 controller 的实现。Resource 确定 controller 的行为。Controller 会根据监测到用户指定的目标的 CPU 利用率周期性得调整 replication controller 或 deployment 的 replica 数量。
## Horizontal Pod Autoscaler 如何工作?
Horizontal Pod Autoscaler 由一个控制循环实现,循环周期由 controller manager 中的 `--horizontal-pod-autoscaler-sync-period` 标志指定(默认是 30 秒)。
在每个周期内controller manager 会查询 HorizontalPodAutoscaler 中定义的 metric 的资源利用率。Controller manager 从 resource metric API每个 pod 的 resource metric或者自定义 metric API所有的 metric中获取 metric。
- 每个 Pod 的 resource metric例如 CPUcontroller 通过 resource metric API 获取 HorizontalPodAutoscaler 中定义的每个 Pod 中的 metric。然后如果设置了目标利用率controller 计算利用的值与每个 Pod 的容器里的 resource request 值的百分比。如果设置了目标原始值,将直接使用该原始 metric 值。然后 controller 计算所有目标 Pod 的利用率或原始值(取决于所指定的目标类型)的平均值,产生一个用于缩放所需 replica 数量的比率。 请注意,如果某些 Pod 的容器没有设置相关的 resource request ,则不会定义 Pod 的 CPU 利用率,并且 Aucoscaler 也不会对该 metric 采取任何操作。
- 对于每个 Pod 自定义的 metriccontroller 功能类似于每个 Pod 的 resource metric只是它使用原始值而不是利用率值。
- 对于 object metric获取单个度量描述有问题的对象并与目标值进行比较以产生如上所述的比率。
HorizontalPodAutoscaler 控制器可以以两种不同的方式获取 metric :直接的 Heapster 访问和 REST 客户端访问。
当使用直接的 Heapster 访问时HorizontalPodAutoscaler 直接通过 API 服务器的服务代理子资源查询 Heapster。需要在集群上部署 Heapster 并在 kube-system namespace 中运行。
Autoscaler 访问相应的 replication controllerdeployment 或 replica set 来缩放子资源。
Scale 是一个允许您动态设置副本数并检查其当前状态的接口。
## API Object
Horizontal Pod Autoscaler 是 kubernetes 的 `autoscaling` API 组中的 API 资源。当前的稳定版本中,只支持 CPU 自动扩缩容,可以在 `autoscaling/v1` API 版本中找到。
在 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 controller *foo* 创建一个 autoscaler目标的 CPU 利用率是 `80%`replica 的数量介于 2 和 5 之间。
## 滚动更新期间的自动扩缩容
目前在 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/v2alpha1` API 版本来为 Horizontal Pod Autoscaler 指定多个 metric。然后 Horizontal Pod Autoscaler controller 将权衡每一个 metric并根据该 metric 提议一个新的 scale。在所有提议里最大的那个 scale 将作为最终的 scale。
## 支持自定义 metric
**注意:** Kubernetes 1.2 根据特定于应用程序的 metric ,通过使用特殊注释的方式,增加了对缩放的 alpha 支持。
在 Kubernetes 1.6 中删除了对这些注释的支持,有利于 `autoscaling/v2alpha1` API。 虽然旧的收集自定义 metric 的旧方法仍然可用,但是这些 metric 将不可供 Horizontal Pod Autoscaler 使用,并且用于指定要缩放的自定义 metric 的以前的注释也不在受 Horizontal Pod Autoscaler 认可。
Kubernetes 1.6 增加了在 Horizontal Pod Autoscale r 中使用自定义 metric 的支持。
您可以为 `autoscaling/v2alpha1` API 中使用的 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 aggregator 与 API 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](https://github.com/kubernetes/metrics) 获得)。
## 参考
- [HPA 说明 - kubernetes.io](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
- [HPA 详解 - kubernetes.io](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/)
- [自定义 metrics 开发 - github.com](https://github.com/kubernetes/metrics)