横向伸缩
Pod 的横向伸缩是指由 Horizontal 控制器 管理的 Pod 副本数量 的自动伸缩。
可以通过向 Horizontal 控制器 提交一个 HorizontalPodAutoscaler (HPA) 资源来将需要自动横向伸缩的 Deployment 等资源对象托付给 HPA 资源对象,由 HPA 管理目标对象的 Pod 副本数量 (replicas
字段)。
🚦 提交 HPA 对象后,Horizontal 控制器 会周期性检查 Pod 度量(关注的是 Pod 的哪一项特性),计算满足 HPA 配置的目标数值所需的 副本数量,进而调整目标资源(如 Deployment、ReplicaSet、ReplicationController、StatefulSet 等)的 replicas
字段。
创建 HPA
最简单的创建方式是使用 kubectl autoscale
命令构建 HPA 资源对象。创建案例如下,将 deployment/kubia
作为伸缩对象,以该目标对象内部所有 Pod 的 CPU 平均使用率 为度量,持续调整目标对象的 replicas
,直至 Pod 的 CPU 实际使用量 接近 申请量 的 30%
,Pod 的最小数量为 1
,最大数量为 5
:
kubectl autoscale deployment kubia --cpu-percent=30 --min=1 --max=5
🚀 目前 HPA 资源已经有多个版本,每个版本使用的 YAML 配置清单会有区别,这里直接介绍 --api-version=autoscaling/v2beta2
版本的配置清单。
下面使用 YAML 配置清单创建 HPA 资源,配置实例中展示了基于目标 CPU 使用率、目标对象 deployment/kubia
中 Pod 的平均 QPS、度量对象 ingress/main-route
中所有 Pod 的总 QPS 三种度量的配置方式(实际使用中可以根据需求,只配置一种即可):
apiVersion: autoscaling/v2beta2 # 注意版本
kind: HorizontalPodAutoscaler # 资源类型
metadata:
name: kubia # HPA 资源对象名
namespace: default # 所在命名空间
spec:
maxReplicas: 5 # 目标资源对象中 replicas 可调成的最大值
minReplicas: 1 # 目标资源对象中 replicas 可调成的最小值
scaleTargetRef: # 需要调整的目标资源对象(!)
apiVersion: apps/v1 # 目标资源所在 API 版本
kind: Deployment # 目标资源类型
name: kubia # 目标资源对象名
metrics: # 度量(重点!!决定了以什么为标准决定是否伸缩、如何伸缩)
- resource: # Resource 类型度量对应的就是该字段
name: cpu # 参考的资源类型(如果是内存,就是 memory)
target:
averageUtilization: 30 # 调整目标对象的 Pod 副本数直至其中所有 Pod 的 CPU 实际平均利用率应该接近申请量的 30%
type: Utilization # 根据利用率伸缩
type: Resource # Resource 类型度量(还有 Pod 和 Object 两种)
- pods: # Pods 类型度量对应的就是该字段
metric:
name: packets-per-second # 参考的资源类型,这里是包的 QPS,该字段是通过其他手段添加至 API 服务器提供的 /metrics 下的度量类型
target:
averageValue: 1k # 调整目标对象的 Pod 副本数直至其中所有 Pod 的平均 QPS 接近 1K
type: Pods # Pods 类型度量
- object: # Object 类型度量对应的就是该字段
metric:
name: requests-per-second # 参考的资源类型,这里是请求 main-route 这个 Ingress 中的 Pod 的 QPS,该字段是通过其他手段添加至 API 服务器提供的 /metrics 下的度量类型
describedObject: # 度量对象
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
name: main-route
target:
type: Value
value: 2k # 调整目标对象的 Pod 副本数直至度量对象(main-route)中所有 Pod 的总 QPS 接近 2K
type: Object # Object 类型度量
🍓 伸缩操作的最大速率(避免抖动):扩缩容单次操作时 最多使副本数翻倍;两次操作之间的时间间隔也有限制,两次 扩容 操作需间隔 3 分钟,两次 缩容 操作需间隔 5 分钟。
🥑 在对目标对象的副本数伸缩后,该对象的 replicas
会被调整为对应的值,即使此时删除 HPA 资源,该目标对象的 replicas
仍然是被固定为 HPA 删除时的值。
伸缩过程
自动伸缩过程可以分为三步:
获取被伸缩资源对象(目标对象)所管理的所有 Pod 度量(CPU 利用率等),这个拉取动作是 周期性;
计算使度量数值到达(或接近)所指定目标数值所需的 Pod 副本数;
更新被伸缩资源对象的
replicas
字段;

获取度量
在 1.8 及之后的 Kubernetes 版本中,提供了 /metrics
API 接口供 HPA 获取度量数据。用户可以通过向 API 服务器提交请求,添加新的度量参数,实现自定义度量。
计算所需 Pod 数量
HPA 需要计算出一个合适的副本数 replicas
,使所有副本 Pod 上度量的平均值尽量接近配置的目标值。该计算的输入是一组 Pod 的度量(每个 Pod 可能有多个),输出则是一个整数(Pod 副本数)。
期望副本数的公式如下:
期望副本数 = ceil[当前副本数 * ( 当前指标 / 期望指标 )]
ceil 为向上取整
例如,当前度量为 200m
,目标设定值为 100m
,那么由于 200.0 / 100.0 == 2.0
, 副本数量将会翻倍。 如果当前指标为 50m
,副本数量将会减半,因为 50.0 / 100.0 == 0.5
。
多个度量时
当 Pod 存在多个度量时,首先根据每种度量计算出各自的期望副本数,然后取所有期望副本数中的 最大值 即可。
更新目标对象的副本数
HPA 会通过 Scale 子资源 修改目标资源对象的 replicas
字段,如下图。

这意味着只要 API 服务器为目标资源暴露了 Scale 子资源,HPA 就可以通过该资源间接操作目标资源的 replicas
字段。目前暴露了 Scale 子资源的资源有:
Deployment;
ReplicaSet;
ReplicationController;
StatefulSet;
Last updated
Was this helpful?