HPA(Horizontal Pod Autoscaler)是 Kubernetes 中用于自动水平扩缩 Pod 数量的控制器,它根据资源使用率或自定义指标自动调整 Deployment、ReplicaSet 或 StatefulSet 的副本数。
1. 工作原理
- 基本工作流程
- 指标采集:从 Metrics Server 或自定义指标 API 获取指标数据。
- 指标计算:计算当前指标值与目标值的比率。
- 决策算法:使用算法确定需要的副本数。
- 执行扩缩:通过修改对应工作负载的
replicas
字段实现扩缩。
- 扩缩容决策算法
期望副本数 = ceil[当前副本数 * (当前指标值 / 目标指标值)]
TeX2. HPA 获取的指标类型
- Pod 资源指标:Pod 级别的性能指标,通常是一个比率,例如 Pod 的 CPU、内存使用率等,通常由 Metrics-Server 提供。
- Metrics-Server 的数据直接来源于集群中每个节点上的 Kubelet。Kubelet 会持续收集本节点上所有 Pod 和节点自身的资源使用情况(如 CPU、内存),并通过一个名为 Summary API 的接口暴露这些数据。
- Metrics-Server 通过 Kubernetes API Server 获取所有节点的列表,然后直接向各节点的 Kubelet 发起请求,调用 Summary API 获取实时数据。
- Metrics-Server 将拉取的原始数据聚合为标准的 Kubernetes 资源指标。
- Container 资源指标:Container 级别的性能指标,该指标从 v1.20 开始引入,可以基于某个容器的性能指标实现自动扩缩容。也是由 Metrics-Server 提供的。
- Pod 自定义指标:Pod 级别的性能指标,通常是一个值,例如接收的请求数量。
- Object 自定义指标:自定义指标通常是从 Kubernetes 集群内部运行的应用程序中收集的。这些指标可以通过 Prometheus、Metrics Server 或其他监控工具采集,通常与特定应用程序或 Pod 的性能相关
- 外部自定义指标:HPA 允许根据 Kubernetes 集群外部的服务指标来进行扩展。外部指标来自于 Kubernetes 集群外部的资源或服务,通常是由外部的监控系统或服务提供的。这些指标不依赖于 Kubernetes 内部的资源,可能包括外部服务的响应时间、消息队列的长度、数据库的请求数等。
3. 部署 Metrics Server
修改 kube-apiserver.yaml 配置:
# 修改每个节点 API Server 的 kube-apiserver.yaml ,修改后会自动重启生效
# /etc/kubernetes/manifests/kube-apiserver.yaml
# 添加启动参数
--enable-aggregator-routing=true
YAML部署 Metrics Server:
# 下载官方部署文件
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 修改 components.yaml 配置
...
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: metrics-server
strategy:
rollingUpdate:
maxUnavailable: 0
template:
spec:
containers:
- args:
- --cert-dir=/tmp
- --secure-port=10250
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
# 跳过证书验证
- --kubelet-insecure-tls
image: k8s.mirror.nju.edu.cn/metrics-server/metrics-server:v0.7.1 # 修改镜像地址
...
# 部署
kubectl apply -f components.yaml
BashMetrics Server 相关命令:
# 查看 top 命令的帮助
kubectl top --help
# 查看node节点的资源使用情况
kubectl top node
# 查看pod的资源使用情况
kubectl top pod
# 查看所有命名空间的pod资源使用情况
kubectl top pod -A
Bash4. HPA 资源定义
HPA 当前有两个版本:
- HPA v1 版,需要借助Heapster获取CPU和内存指标。
- HPA v2 版,需要借助Metrics Server获取需要的指标。
4.1. 基本 YAML 结构
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
YAML关键字段说明:
字段 | 描述 | 示例值 |
scaleTargetRef | 指定要扩缩的目标工作负载 | Deployment/myapp |
minReplicas | 最小副本数 | 1 |
maxReplicas | 最大副本数 | 10 |
metrics | 扩缩依据的指标列表 | 见下文 |
4.2. 指标类型示例
- Pod 资源指标(Resource Metrics)
metrics:
- type: Resource
resource:
name: cpu # 或 memory
target:
type: Utilization # 或 AverageValue
averageUtilization: 50 # 目标CPU利用率百分比
# 或 averageValue: 200m
YAML- Container 资源指标(ContainerResource Metrics)
metrics:
- type: ContainerResource
containerResource:
name: cpu # 或 memory
container: applicatuon # pod 中容器的名字
target:
type: Utilization # 或 AverageValue
averageUtilization: 50 # 目标CPU利用率百分比
# 或 averageValue: 200m
YAML- Pod 指标(Pod Metrics)
metrics:
- type: Pods
pods:
metric:
name: packets-per-second
target:
type: AverageValue
averageValue: 1k
# 设置 Pod 的指标值名称为 packets-per-second ,在目标指标平均值为 1000 时触发扩容操作。
YAML- 对象指标(Object Metrics)
metrics:
- type: Object
object:
metric:
name: requests-per-second
describedObject:
apiVersion: networking.k8s.io/v1
kind: Ingress
name: main-route
target:
type: Value
value: 2k
YAML- 外部指标(External Metrics)
metrics:
- type: External
external:
metric:
name: queue_messages_ready
selector:
matchLabels:
queue: "worker_tasks"
target:
type: AverageValue
averageValue: 30
YAML4.3. 自定义扩缩行为
我们可以通过 HorizontalPodAutoscaler 资源的 behavior 字段进行行为策略配置,系统默认的行为策略如下:
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 缩容稳定窗口
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selecPolicy: Max
YAML关键字段说明:
- scaleDown:缩容行为策略。
- scaleUp:扩容行为策略。
- stabilizationWindowSeconds:稳定窗口时间,单位为 s。HPA 控制器可能因为 Pod 目标副本数量的变化而不断创建和删除 Pod,为了减少不必要的数量调整,该参数提供了一个缓冲时间,HPA 控制器在此时间内不做频繁调整操作,而是取其中最安全的 Pod 期望副本数量,在到达窗口时间后,再进行调整。
- policies:扩缩容策略,具体如下。
- type:策略类型,例如 Pods 表示 Pod 数量,Percent 表示比例。
- value:策略允许的修改量。
- periodSeconds:策略应该保证为 true 的时间窗口,单位为 s。
- selectPolicy:指定该方向使用哪种策略,默认为 Max,表示选择影响 Pod 副本数量最大的策略;将该参数设置为 Min,表示选择影响 Pod 副本数量最小的策略;将该参数设置为 Disabled,表示禁用当前方向的策略。
在上面的默认行为示例中,对于缩容行为设置的策略如下:
- 每 15s 允许减少100%的 Pod 副本数量,缩容稳定窗口时间为 300s。
对于扩容行为设置的策略如下:
- stabilizationWindowSeconds=0 表示没有稳定窗口时间。
- 每15s允许增加最多4个Pod副本,或最多增加当前Pod副本数量的 100%。
5. 工作负载使用 HPA 的配置调整
在启用了 HPA 的集群中,建议在 Deployment 或者 StatefulSet 的定义中不要设置 spec.replicas 副本数量,对于已存在的资源可以通过 kubectl edit 命令删除该配置项。
6. 快速创建 HPA
除了基于 HorizontalPodAutoscaler 资源 yaml 配置文件创建 HPA 资源,还可以通过 kubectl autoscale 子命令一键创建 HPA 资源,如下所示:
# 或通过命令创建
kubectl autoscale deployment myapp --cpu-percent=50 --min=1 --max=10
# 为 Deployment“myapp”创建的HPA自动扩缩容控制器,副本数量可以在1和10之间变化,每个Pod副本的目标CPU使用率为90%。
Bash