HPA(Horizontal Pod Autoscaler)是 Kubernetes 中的一种资源自动伸缩机制,用于根据某些指标动态调整 Pod 的副本数量。
resources.requests
采用 KEDA 作为弹性伸缩系统的基座,主要考虑到如下优势点:
KEDA 监控来自外部指标提供程序系统(例如 Azure Monitor)的指标,然后根据基于指标值的缩放规则进行缩放。它直接与度量提供者系统通信。它作为 Kubernetes Operator 运行,它只是一个 pod 并持续监控。
img
KEDA 将 K8s Core Metrics Pipeline 和 Monitoring Pipeline 处理流程统一化,并内置多种 scaler ( link ),提供开箱即用的弹性策略支持,如常见的基于 CPU/Memory 的弹性策略、定时弹性等:
img
说明: 原生Deployment对象不支持灰度发布策略,所以改用 Argo-Rollout 资源对象,下面示例均采用 Argo-Rollout 演示
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: <appid>-cron
namespace: <env>
spec:
minReplicaCount: <origin-replicas>
scaleTargetRef:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
name: <appid>-default
triggers:
- type: cron
metadata:
timezone: Asia/Shanghai
start: 30 * * * *
end: 45 * * * *
desiredReplicas: "10"
支持三个周期
img
img
img
定时HPA动态扩缩容提醒:
AppID:<appid>
归属环境:<env>
容器集群:<cluster>
开始扩容时间:30 11 * * 1
结束扩容时间:30 12 * * 1
容器数量变化:1 --> 2
触发时间:2023-11-13 12:35:16
如有疑问可参考:HPA使用文档,或咨询@SRE客服
根据 cpu、mem 等资源使用率,自动扩缩容,低负载缩容,减小不必要资源占用,高负载自动扩容,保证应用有足够的资源使用。
说明: 基于 Prometheus 拉取真实资源使用情况,并屏蔽刚启动的 Pod -default 为基线应用,cluster、zone 是 Prometheus remote_write 到 VictoriaMetrics 新增便签,便于区分集群和区域 VictoriaMetrics 是统一汇总、查询层,方便不同集群使用一套数据源
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
labels:
scaledobject.keda.sh/name: <appid>
name: <appid>
namespace:<env>
spec:
maxReplicaCount: <max-replicas>
minReplicaCount: <origin-replicas>
scaleTargetRef:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
name: <appid>-default
triggers:
- metadata:
metricName: cpu_utilization
query: sum((sum (rate(container_cpu_usage_seconds_total{zone="<zone>",namespace="<env>",pod=~"<appid>-default.*",container!=""}[1m]))
by(pod) and on(pod) time() - kube_pod_start_time{zone="<zone>",namespace="<env>",pod=~"<appid>-default.*"}
> 150 )/( sum (container_spec_cpu_quota{zone="<zone>",namespace="<env>",pod=~"<appid>-default.*",container!=""})
by(pod) /100000) * 100)
serverAddress: http://<victoria-select>/select/1/prometheus
threshold: "80"
type: prometheus
- metadata:
metricName: mem_utilization
query: sum((sum by(pod) (container_memory_working_set_bytes{zone="<zone>",namespace="<env>",pod=~"<appid>-default.*",container!="",container!="POD"})
and on(pod) time() -kube_pod_start_time{zone="<zone>",namespace="<env>",pod=~"<appid>-default.*"}>
150) / sum by(pod) (container_spec_memory_limit_bytes{zone="<zone>",namespace="<env>",pod=~"<appid>-default.*",container!="",container!="POD"})*100)
serverAddress: http://<victoria-select>/select/1/prometheus
threshold: "80"
type: prometheus
img
指标HPA动态扩缩容提醒:
AppID:<appid>
归属环境:<env>
容器集群:<cluster>
触发指标:cpu使用率(设定阈值为: 40.0%)
触发指标当前值:77.0%
容器数量变化:1 --> 2
触发时间:2023-11-16 10:38:40
如有疑问可参考:HPA使用文档,或咨询@SRE客服
上生产前,在 UT 环境压测,确定 最大 QPS、最高接受的 RT、最大接受 消息积压数等,监控平台提供接口,根据阀值,自动扩容,自动应对突然流量或压力,保障应用稳定性。
说明: QPS 取自 CAT 数据,SRE这边将 CAT 数据使用工具写入到 VictoriaMetrics 中 前端设计、消息通知 和 基于资源的弹性使用的一套模版,都属于基于指标触发的 HPA,这里不再赘述
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
labels:
scaledobject.keda.sh/name: <appid>
name: <appid>
namespace: <env>
spec:
maxReplicaCount: <max-replicas>
minReplicaCount: <origin-replicas>
scaleTargetRef:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
name: <appid>-default
triggers:
- metadata:
metricName: http_requests_total
query: sum(cat_url_info{appid="<appid>",type="count",env="<env>",assettype="docker",zone="<zone>",host=~"<appid>-default.*"})/60
serverAddress: http://<victoria-select>/select/1/prometheus
threshold: "1000"
type: prometheus
计算公式 | 检查触发器间隔 | 指标最新数据间隔 | 备注 | |
---|---|---|---|---|
CPU 使用率 | 所有容器CPU使用率之和/ 容器数量 | 30s | 30s | 排除了刚启动的 Pod |
MEM 使用率 | 所有容器MEM使用率之和 / 容器数量 | 30s | 30s | 排除了刚启动的 Pod |
QPS | 所有容器每秒的请求量 / 容器数量 | 30s | 60s | 最新数据为 上一分钟 QPS 的平均值 |
扩容时间
当检测结果大于设置的阈值时,立刻触发扩容,没有稳定窗口。
期望副本数 = ceil[当前副本数 * (当前指标 / 期望指标)]
⚠️ HPA 在计算目标副本数时会有一个10%的波动因子。如果在波动范围内,HPA 并不会调整副本数目。
缩容时间
稳定窗口的时间为 300 秒,满足缩容条件后,连续5分钟持续满足缩容条件,触发缩容
后续补充
自动扩容大多数是在高并发大流量情况触发,此时如果没有对应的解决方案,就会产生短时间流量有损问题。
这里先说下问题,下篇文章会详细介绍具体场景及解决方案
过程 | 问题 |
---|---|
无损下线 | 消费者无法及时感知生产者已下线 |
无损上线 | 注册太早 |
无损上线 | 发布态与运行态未对⻬ |
无损上线 | 初始化慢 |