Pod水平自动扩缩(Horizontal Pod Autoscaler, 简称HPA)可以基于 CPU/MEM 利用率自动扩缩Deployment、StatefulSet 中的 Pod 数量,同时也可以基于其他应程序提供的自定义度量指标来执行自动扩缩。默认HPA可以满足一些简单场景,对于生产环境并不一定适合,本文主要分析HPA的不足与优化方式。

HPA Resource类型不足

默认HPA提供了Resource类型,通过CPU/MEM使用率指标(由metrics-server提供原始指标)来扩缩应用。

使用率计算方式

在Resource类型中,使用率计算是通过request而不是limit,源码如下:

// 获取Pod resource request
func calculatePodRequests(pods []*v1.Pod, resource v1.ResourceName) (map[string]int64, error) {requests := make(map[string]int64, len(pods))for _, pod := range pods {podSum := int64(0)for _, container := range pod.Spec.Containers {if containerRequest, ok := container.Resources.Requests[resource]; ok {podSum += containerRequest.MilliValue()} else {return nil, fmt.Errorf("missing request for %s", resource)}}requests[pod.Name] = podSum}return requests, nil
}
// 计算使用率
func GetResourceUtilizationRatio(metrics PodMetricsInfo, requests map[string]int64, targetUtilization int32) (utilizationRatio float64, currentUtilization int32, rawAverageValue int64, err error) {metricsTotal := int64(0)requestsTotal := int64(0)numEntries := 0for podName, metric := range metrics {request, hasRequest := requests[podName]if !hasRequest {// we check for missing requests elsewhere, so assuming missing requests == extraneous metricscontinue}metricsTotal += metric.ValuerequestsTotal += requestnumEntries++}currentUtilization = int32((metricsTotal * 100) / requestsTotal)return float64(currentUtilization) / float64(targetUtilization), currentUtilization, metricsTotal / int64(numEntries), nil
}

通常在Paas平台中会对资源进行超配,limit即用户请求资源,request即实际分配资源,如果按照request来计算使用率(会超过100%)是不符合预期的。相关issue见72811,目前还存在争论。可以修改源码,或者使用自定义指标来代替。

多容器Pod使用率问题

默认提供的Resource类型的HPA,通过上述方式计算资源使用率,核心方式如下:

metricsTotal = sum(pod.container.metricValue)
requestsTotal = sum(pod.container.Request)
currentUtilization = int32((metricsTotal * 100) / requestsTotal)

计算出所有container的资源使用量再比总的申请量,对于单容器Pod这没影响。但对于多容器Pod,比如Pod包含多个容器con1、con2(request都为1cpu),con1使用率10%,con2使用率100%,HPA目标使用率60%,按照目前方式得到使用率为55%不会进行扩容,但实际con2已经达到资源瓶颈,势必会影响服务质量。当前系统中,多容器Pod通常都是1个主容器与多个sidecar,依赖主容器的指标更合适点。

好在1.20版本中已经支持了ContainerResource可以配置基于某个容器的资源使用率来进行扩缩,如果是之前的版本建议使用自定义指标替换。

性能问题

单线程架构

默认的hpa-controller是单个Goroutine执行的,随着集群规模的增多,势必会成为性能瓶颈,目前默认hpa资源同步周期会15s,假设每个metric请求延时为100ms,当前架构只能支持150个HPA资源(保证在15s内同步一次)

func (a *HorizontalController) Run(stopCh <-chan struct{}) {// ...// start a single worker (we may wish to start more in the future)go wait.Until(a.worker, time.Second, stopCh)<-stopCh
}

可以通过调整worker数量来横向扩展,已提交PR。

调用链路

hpa controller中一次hpa资源同步,需要调用多次apiserver接口,主要链路如下

  1. 通过scaleForResourceMappings得到scale资源
  2. 调用computeReplicasForMetrics获取metrics value
  3. 调用Scales().Update更新计算出的副本数

尤其在获取metrics value时,需要先调用apiserver,apiserver调用metrics-server/custom-metrics-server,当集群内存在大量hpa时可能会对apiserver性能产生一定影响。

其他

对于自定义指标用户需要实现custom.metrics.k8s.ioexternal.metrics.k8s.io,目前已经有部分开源实现见custom-metrics-api。

另外,hpa核心的扩缩算法根据当前指标和期望指标来计算扩缩比例,并不适合所有场景,只使用线性增长的指标。

期望副本数 = ceil[当前副本数 * (当前指标 / 期望指标)]

watermarkpodautoscaler提供了更灵活的扩缩算法,比如平均值、水位线等,可以作为参考。

总结

Kubernetes提供原生的HPA只能满足一部分场景,如果要上生产环境,必须对其做一些优化,本文总结了当前HPA存在的不足,例如在性能、使用率计算方面,并提供了解决思路。

优化Kubernetes横向扩缩HPA相关推荐

  1. Kubernetes HPA 动态弹性扩缩容

    1.HPA 1.1HPA介绍 1.在Kubernetes中,HPA自动更新工作负载资源(例如:Deployment或者StatefulSet),目的是自动扩缩工作负载以满足需求,水平扩缩意味着对增加的 ...

  2. Kubernetes:HPA 详解-基于 CPU、内存和自定义指标自动扩缩容

    目录 HPA 基本原理 Metrics Server 聚合 API 安装Metrics Server HPA 基于 CPU自动扩缩容 查看 HPA 资源的对象了解工作过程: HPA 基于 内存自动扩缩 ...

  3. Serverless Kubernetes 应用部署及扩缩容

    作者 | 邓青琳(轻零) 阿里云技术专家 导读:本文分为三个部分,首先给大家演示 Serverless Kubernetes 集群的创建和业务应用的部署,其次介绍 Serverless Kuberne ...

  4. k8s自定义指标HPA实践(微服务基于自定义指标自动扩缩容的实践)附demo

    先上demo代码仓库 https://github.com/wentjiang/prometheus-HPA-test 自动扩缩容的使用场景 在开发微服务时,我们会有一些请求量突增的场景,举个例子,快 ...

  5. 拆解交易系统--性能优化,安全加固与弹性扩缩容

    点击上方蓝色字体,选择"设为星标" 优质文章,及时送达 前几篇文章我们拆解了交易系统架构层次的设计方案,对于代码细节我们讨论很很少,今天基于几个方面简短的介绍一下,未来有时间可以针 ...

  6. 恒源云(Gpushare)_【存储优化】/hy-tmp可以扩/缩容啦

    继[会员体系].[活动专区]上线后,为了进一步优化数据存储体验,特升级了[Tmp(/hy-tmp)]的使用规则,其他免费存储方式包括[OSS存储].[共享存储 (/hy-nas )],其免费额度及收费 ...

  7. Kubernetes基础:资源扩缩容方法(Replica Set)

    Kubernetes提供了多种方式对于资源的扩缩容进行操作,这篇文章以RS(Replica Set)为例进行说明. 常用方法 方法1: 使用kubectl scale进行扩缩容 执行kubectl s ...

  8. Flink checkpoint操作流程详解与报错调试方法汇总,增量checkpoint原理及版本更新变化,作业恢复和扩缩容原理与优化

    这里写目录标题 flink checkpint出错类型 flink 重启策略 Checkpint 流程简介 增量Checkpoint实现原理 MemoryStateBackend 原理 FsState ...

  9. Kubernetes基础:资源扩缩容方法(Replication Controller)

    Kubernetes提供了多种方式对于资源的扩缩容进行操作,这篇文章以RC(Replication Controller)为例进行说明. 常用方法 方法1: 使用kubectl scale进行扩缩容 ...

最新文章

  1. 在滴滴和头条干了 2 年后端开发,太真实了…
  2. Android开发之Activity转场动画
  3. python抓取简单网页_【Python3 爬虫】01_简单页面抓取
  4. Spring MVC 拦截器
  5. 我要去三清山国家公园。。。
  6. excel设置默认值_职场办公必备的7个Excel应用技巧解读,易学易懂,收藏备用!...
  7. img内联块元素的操作
  8. 【Oracle】SCOPE=MEMORY|SPFILE|BOTH
  9. 鼠标光标一直在闪烁_硬核鼠标科普,选出适合你的鼠标
  10. 【AR】DroidCam笔记本调用手机摄像头(smartphone's camera as pc webcam)
  11. Bluecoat代理设备维护手册
  12. Html网页设计-美食网站
  13. 艾德克斯充电测试软件_艾德克斯ITECH 交流充电桩模拟系统
  14. 微信公众号的web开发者工具的自助解绑功能终于有了!
  15. 如何从App Store排行榜中脱颖而出
  16. 服务器系统具备自检能力,服务器内存自检自动重启
  17. Android 概述
  18. 这一次彻底搞定 useReducer - 基础概念
  19. ——————【 正则表达式 】——————
  20. n1ctf(部分复现)

热门文章

  1. 百度网盘资源怎么分享群链接下载?
  2. 关于hadoop集群常见的节点失联问题
  3. 网络安全术语和协议栈自身的脆弱性
  4. mybatis-plus QueryWrapper 添加limit
  5. vue大屏(驾驶舱)实现数字滚动
  6. weblogic的集群与配置--架构师第九天
  7. java第10章总结
  8. Jessi-记录工作问题
  9. 实现弹簧柔性状态的2种方式 | Solidworks教程
  10. 带有详细书签的IT电子书大全