本文分享自华为云社区《HPA各关联组件扭转关系以及建议》,作者:可以交个朋友。

一、背景

应用程序的使用存在波峰波谷现象,在应用流量处于低谷期间,可以释放因过多的Pod而浪费的硬件资源。在应用流量高峰期提供弹性足够的Pod处理流量。

二、HPA各个组件扭转关系

kubernetes使用者通过创建一个hpa资源(horizontalpodautoscaler)用于定义对某个负载比如deployment的弹性策略,策略中说明基于什么指标、指标的阈值以及弹性的最大值、最小值。hpa资源创建后,kube-controller-manager中的hpa-controller协程开始工作,大致工作步骤如下:

  • 调用kube-apiserver,获取HPA 资源关联负载的指标

  • 用负载当前的指标和HPA中规定的阈值比较,结合逻辑判断是增加、减少或者不修改负载的示例数

  • 根据步骤2的计算结果,调用kube-apiserver修改负载的示例数

需要理解的关键卡点问题是

  • 指标是从哪里来的?

  • kube-apiserver本身代码里面不提供指标的API,为啥调用kube-apiserver接口能获取到指标?

三、指标和指标的来源

指标均由业务API提供,一般业界指标标准URL为/metrics。kubernetes生态中,主要通过Metrics server和Prometheus获取指标:

  • metrics server:metrics-server作为集群组件,用于收集和聚合从每个kubelet中提取的资源指标。本质上只是做了数据的中转和聚合,通过调用kubelet的api接口获取数据。kubelet 作为用于管理容器资源的节点代理,可以使用 /metrics/resource 接口访问资源指标。

  • Prometheus:在某些场景下,prometheus采集的指标可能需要重命名或者重新计算,由Prometheus-adapter组件提供转换能力。

在kubernetes中指标分为core metric(核心指标)和custom metric(自定义指标):

  • Core metrics(核心指标):Metrics server通过调用各个节点kubelet 10250端口,由kubelet内部cAdvisor模块获取度量指标,对应指标实现由kubelet提供,使用者无法修改,然后返回给HPA。

  • Custom Metrics(自定义指标):通过Prometheus获取对应的业务指标,具体指标内容有业务自己实现。

四、通过API Aggregation拓展kubernetes API

API Aggregation 允许在不修改 Kubernetes 核心代码的同时扩展 Kubernetes API,即将第三方服务注册到 Kubernetes API 中,这样就可以通过 Kubernetes API 来访问外部服务。

如下图示例,通过APIService资源新增 /apis/metrics.k8s.io/v1beta1 和 /apis/custom.metrics.k8s.io/v1beta1。当kube-apiserver收到对应URL请求后,会将请求转发给APIService资源中spec.service指定的服务,URL为 /apis/metrics.k8s.io/v1beta1的请求转发给metrics-server服务处理,URL为/apis/custom.metrics.k8s.io/v1beta1的请求转发给custom-metrics-apiserver服务(本质上就是Prometheus-adapter,服务名称为custom-metrics-apiserver而已)。如此,便可以通过直接访问kube-apiserver端口,获取对应的指标数据。


# 比如获取核心指标
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/${yourNamespace}/pods" # 获取自定义指标:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/${yourNamespace}/x"

如此,kube-controller-manager就可以通过调用kube-apiserver接口获取相关业务的指标了。

五、HPA实践建议

HorizontalPodAutoscaler 是 Kubernetes autoscaling API 组中的 API 资源。 当前的稳定版本可以在 autoscaling/v2 API 版本中找到,其中包括对基于内存和自定义指标执行扩缩的支持。 在使用 autoscaling/v1 时,autoscaling/v2 中引入的新字段作为注释保留。可配置的扩缩行为(behavior)在之前的 autoscaling/v2beta2 API 版本将此功能作为 beta 功能提供。1.23 kubernetes及以上可参考yaml:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
behavior:
scaleDown:
policies:
- type: Pods
value: 4
periodSeconds: 60
- type: Percent
value: 10
periodSeconds: 60

核心指标弹性,一般建议采用cpu指标进行弹性,memory因为不太敏感而且跟开发语言相关,大多数语言都有内存池以及内置GC机制导致进程内存监控不准确

快速扩容,主要防止流量瓶颈;缓慢缩容,主要防止另一个流量高峰。

快速扩容策略配置

behavior:           #通过behavior单独配置扩缩行为
scaleUp:
stabilizationWindowSeconds: 0 # 扩容没有稳定窗口,满足条件 立刻扩容
policies:
- type: Percent #以下策略表示在15s内,最多扩容当前实例数的9倍
value: 900
periodSeconds: 15

快速扩容,缓慢缩容;业务在流量高峰期后,并发量骤降的场景中,如果使用默认的缩容策略,几分钟后Pod的数量也会随着骤降,此时如果又迎来流量高峰,扩容过程需要一段时间,这段时间内造成业务后端处理能力达到瓶颈,将导致部分请求失败。可以为HPA配置behavior缩容策略,快速缩容之后缓慢缩容。

behavior:                # 通过该字段单独配置扩缩行为
scaleDown:
policies:
- type: Pods #表示每600s删除一个pod
value: 1
periodSeconds: 600
scaleUp:
policies:
- type: Percent #表示在15s之内,扩容当前实例数的9倍
value: 900
periodSeconds: 15

禁止自动缩容。对于扩容后需要禁止自动缩容的关键业务应用,需要人工干预或者其他方式进行缩容,可以使用如下策略禁止缩容

behavior:                  #通过该字段单独配置扩缩行为
scaleDown:
selectPolicy: Disabled #selectPolicy 的值 Disabled 会关闭对给定方向的缩容,使用该策略,将会阻止缩容

延长缩容时间窗。缩容的稳定窗口默认是5分钟,如果需要延长时间窗口以避免一些流量毛刺,可以配置以下策略

behavior:      #通过该字段可单独配置扩缩行为
scaleDown:
stabilizationWindowSeconds: 600 #等待600s后 在开始缩容
policies:
- type: Pods
value: 5 # 每次只缩容5个Pod

HorizontalPodAutoscaler API 也支持容器指标源,这时 HPA 可以跟踪记录一组 Pod 中各个容器的资源用量,进而触发扩缩目标对象的操作。 特性状态: Kubernetes v1.27 [beta]

如果你有一个 Web 应用和一个执行日志操作的边车容器,你可以基于 Web 应 用的资源用量来执行扩缩,忽略边车容器的存在及其资源用量。

type: ContainerResource
containerResource:
name: cpu
container: application
target:
type: Utilization
averageUtilization: 60

HPA 控制器会对目标对象执行扩缩操作以确保所有 Pod 中 application 容器的平均 CPU 用量为 60%。

点击关注,第一时间了解华为云新鲜技术~

实践解析HPA各关联组件扭转关系的更多相关文章

  1. 完爆Facebook/GraphQL,APIJSON全方位对比解析(三)-表关联查询

    相关阅读: 完爆Facebook/GraphQL,APIJSON全方位对比解析(一)-基础功能 完爆Facebook/GraphQL,APIJSON全方位对比解析(二)-权限控制 自APIJSON发布 ...

  2. Atitit 表达式原理 语法分析 原理与实践 解析java的dsl  递归下降是现阶段主流的语法分析方法

    Atitit 表达式原理 语法分析 原理与实践 解析java的dsl  递归下降是现阶段主流的语法分析方法 于是我们可以把上面的语法改写成如下形式:1 合并前缀1 语法分析有自上而下和自下而上两种分析 ...

  3. 泛型编程、STL的概念、STL模板思想及其六大组件的关系,以及泛型编程(GP)、STL、面向对象编程(OOP)、C++之间的关系

    2013-08-11 10:46:39 介绍STL模板的书,有两本比较经典: 一本是<Generic Programming and the STL>,中文翻译为<泛型编程与STL& ...

  4. kubernetes之configmap,深度解析mountPath,subPath,key,path的关系和作用

    参考:https://www.cnblogs.com/breezey/p/6582082.html 我们知道,在几乎所有的应用开发中,都会涉及到配置文件的变更,比如说在web的程序中,需要连接数据库, ...

  5. App架构师实践指南三之基础组件

    App架构师实践指南三之基础组件 1.基础组件库随着时间的增长,代码量的逐渐积累,新旧项目之间有太多可以服用的代码.下面是整理的公共代码库. 2.关于加密密钥的保护以及网络传输安全是移动应用安全最关键 ...

  6. 在Visual Studio中使用组件图描述项目组件依赖关系

    如果想描述项目组件的关系,可以考虑使用UML组建图. 在建模项目下添加一个名称为"Applicaiton Component Structure"的UML组建图. 添加各个组件,并 ...

  7. src-resolve: 无法将名称 'extension' 解析为 'element declaration' 组件。

    activiti流程部署时,出现“src-resolve: 无法将名称 'extension' 解析为 'element declaration' 组件.”错误. 出错原因:项目所在路径中有中文.

  8. 嵌套查询--------关联一对多关系----------collection

    参考来源:   http://www.cnblogs.com/LvLoveYuForever/p/6689577.html <resultMap id="BaseResultMap&q ...

  9. 线程、进程概念与Android系统组件的关系

    Android系统是Google公司基于Linux内核开发的开源手机操作系统.通过利用 Linux 内核的优势,Android 系统使用了大量操作系统服务,包括进程管理.内存管理.网络堆栈.驱动程序. ...

  10. Vue_(组件通讯)父子组件简单关系

    Vue组件 传送门 在Vue的组件内也可以定义组件,这种关系成为父子组件的关系 如果在一个Vue实例中定义了component-a,然后在component-a中定义了component-b,那他们的 ...

随机推荐

  1. 升级java11后,maven命令打包报错

    一.问题 升级java11后,maven命令打包报错: mvn clean package -Dmaven.test.skip=true [ERROR] Failed to execute goal ...

  2. QA|新版Pycharm如何关闭和开启自动补全功能?|Pycharm|工具相关

    自动补全开启状态: 自动补全关闭状态: 建议:新学者建议开启自动补全,这样可以把各个函数方法记忆的更加深刻!

  3. QA|ValueError: write to closed file报错怎么debug|IHRM接口自动化测试

    unittest生成自动化测试报告时报错ValueError: write to closed file,如下图 代码如下: 原因排查:因为with open打开文件后会自动关闭,也就是上图16行执行 ...

  4. numpy_tricks

    Numpy Tricks 这篇文章不定期更新,主要是记录在使用numpy过程中一些有效的tricks(或者重要的API) import numpy as np numpy.where() numpy. ...

  5. 在线问诊 Python、FastAPI、Neo4j — 创建 疾病节点

    目录 疾病数据 创建节点 根据检查结果.医生的临床经验得出疾病 疾病数据 disease_data.csv 建议值用""引起来.避免中间有,号造成误识别 疾病 "干眼&q ...

  6. 2023-09-23:用go语言,假设每一次获得随机数的时候,这个数字大于100的概率是P。 尝试N次,其中大于100的次数在A次~B次之间的概率是多少? 0 < P < 1, P是double类型,

    2023-09-23:用go语言,假设每一次获得随机数的时候,这个数字大于100的概率是P. 尝试N次,其中大于100的次数在A次~B次之间的概率是多少? 0 < P < 1, P是dou ...

  7. npm install xxx 后加上-s、-d、-g之间的区别?

    1.npm install xxx -s npm install xxx -s.npm install xxx -S是npm install xxx --save的简写形式 局部安装,记录在packa ...

  8. std::for_each易忽略点

    以下代码为修改vector内部的每一个元素,使其每个元素大小变为原来的平方. std::vector v1{1, 2, 4, 2}; std::for_each(begin(v1), end(v1), ...

  9. node(1)

    1.新建http.js //node搭建http服务器 let http=require('http'); //使用http建立服务请求 http.createServer(function(requ ...

  10. Dynamics CRM中自定义页面实现附件管理包含下载模板、上传、下载、删除

    前言 附件使用的Dynamics CRM平台本身的注释表annotation存储,将附件转换成二进制字节流保存到数据库中,因自带的注释在页面中显示附件不够直观,特做了一个单独的附件管理自定义页面,通过 ...