基于Kubernetes的hpa实现pod实例数量的自动伸缩
Pod 是在 Kubernetes 体系中,承载用户业务负载的一种资源。Pod 们运行的好坏,是用户们最为关心的事情。在业务流量高峰时,手动快速扩展 Pod 的实例数量,算是玩转 Kubernetes 的基本操作。实际上这个操作还可以更加自动化,运维人员可以事先设置好规则,让 Pod 实例的数量,在指定情况下自动的调整实例的数量,这一操作依靠 Horizontal Pod Autoscaler 来实现。
场景描述
如果企业应用的最终用户是人,那么它的访问压力情况,都会有潮汐特征。好比一款供企业内部人员使用的OA系统,工作日的流量远比休息日高,工作时间的流量远比下班时间高。那么可否让这款 OA 系统根据流量的大小,自动调整实例的数量。令其忙时启动足够数量的实例抵御访问压力,闲时自动降低实例数量,将资源留给其他企业应用。
下图是某个业务系统,在 24 小时内的性能监控曲线。其吞吐率和在线人数曲线都可以反映出一定的潮汐特性:
- 午夜 0 点直到次日早上8 点,这个系统都处于无人使用的状态。在这一段时间里,可以自动将业务系统的实例数量降下来,释放一些计算资源。
- 上午 9 点直到晚间 21 点为系统使用高峰期,最高在线人数达到 1600 人。在这一段时间里,业务系统的实例数量可以自动提升起来,满足业务的需要。
关于 hpa
Kubernetes 在 1.2 版本开始支持了 Horizontal Pod Autoscaler(hpa) ,来应对 Pod 实例的自动伸缩场景。它可以基于实例的 CPU 使用率来决定是否为 Pod 进行实例数量的扩容。我们知道 Pod 的副本数量是被其控制器的配置所决定的,比如 Deployment、StatefulSet、ReplicaSet 。所以,hpa 是在获取了 Pod 实际 CPU 使用率这一指标,和扩展实例的目标指标对比后,操作了其控制器来实现副本数量的扩缩的。
了解了以上内容后,我们起码可以知道,在使用 hpa 进行自动伸缩的设置之前,Kubernetes 集群和 Pod 的控制器都应该符合一定的先决条件。
- 存在 Metrics-server。Metrics-server 是 Kubernetes 集群范围资源用量数据的聚合器。Pod 的 CPU 使用率这一指标,是从 Metrics-server 中获取 CPU 实际用量之后,与控制器中指定的 Pod 资源做比后所得。大多数 Kubernetes 发行版中都已经默认安装了 Metrics-server ,它一般部署在 kube-system 命名空间中。
- Pod 资源限额。既然使用的指标是 CPU 使用率,那么就必须存在一个 CPU 可用的上限作为分母。这个上限,实际上就是在控制器中规定的 Pod 资源限额
spec.resources.limits.cpu
。
创建 hpa
创建 hpa 之前, 我们需要确保 Pod 控制器中规定了CPU资源限额。我当前使用的案例,使用了 Deployment 控制器。其 Pod 的 CPU 资源限额给到 500m。
Kubernetes 体系中,CPU 是一种可以再分的资源,1000m = 1 Core
kubectl get deployment demo-java -n my-namespace -o yaml
返回的结果中,包含了事先设置的资源限额信息:
spec:
resources:
limits:
cpu: 200m
memory: 1Gi
requests:
cpu: 200m
最简单的创建 hpa 的方式,是使用 kubectl autoscale
命令进行操作。下面的示例,意味着在 Pod 的 CPU 使用率超过 50% 之后,将会触发自动伸缩,最多伸缩到 3 个实例。
kubectl autoscale deployment demo-java -n my-namespace --cpu-percent=50 --min=1 --max=3
返回结果:
horizontalpodautoscaler.autoscaling/demo-java autoscaled
创建完成后,我们可以查看 hpa 资源的状态:
kubectl get hpa -n my-namespace
返回结果中,自动伸缩已经被触发,所有实例的综合 CPU 使用率,已经低于设定的值:
hpa 资源只需要被设定一次,就会始终监控 Pod 指标,并根据设定进行自动伸缩
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
demo-java Deployment/demo-java 49%/50% 1 3 2 3m34s
查看 Pod 实际 CPU 使用量,可以得出相应的使用率计算值,和 hpa 中的显示是相符的。
kubectl top pod -n my-namespace
NAME CPU(cores) MEMORY(bytes)
demo-java-7d6d7d4c9c-lz8sw 197m 87Mi
demo-java-7d6d7d4c9c-52sdl 1m 90Mi
另一种创建 hpa 的方式,是通过 yaml 文件进行定义。我们可以将已存在的 hpa 资源导出,便可以了解这一资源的定义方式。
kubectl get hpa demo-java -n my-namespace -o yaml > hpa.yaml
其定义方式可以归结如下:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: demo-java
namespace: my-namespace
spec:
maxReplicas: 3
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: demo-java
targetCPUUtilizationPercentage: 50
通过命令,可以将这一yaml文件加载进 Kubernetes 集群:
kubectl apply -f hpa.yaml
更多的伸缩指标
在上一个章节,已经实现基于 Pod 的 CPU 使用率来进行自动伸缩。利用 CPU 使用率作为伸缩判定指标,是官方默认提供的方式。那么是否还有其他类型的指标可以作为伸缩判定指标呢?这需要 Kubernetes 用户自行扩展。
我建议从两个方向挑选更多的伸缩判定指标。第一个方向是资源的选择,相较于 CPU 而言,内存也可以作为判定指标;第二个方向是维度,相较于使用率而言,使用量也可以作为判定指标。两个方向彼此组合之后,除了 CPU 使用率,我们还得到了另外 3 种伸缩判定指标:
- CPU 使用量,单位 m
- 内存使用率,单位 %
- 内存使用量,单位 MB
在 CPU 与内存之间,个人更建议使用内存作为伸缩指标,原因是资源的不可压缩性。CPU 是一种可以压缩的资源,而内存不是,资源可压缩意味着当 Pod 的 CPU 用量无限接近于资源限额时,对 Pod 实例的影响很小,只是性能表现不佳而已。但是当 Pod 的内存用量无限接近于资源限额时, Kubernetes 会对 Pod 执行 OOM kill 操作,这对业务的影响很大。如果当内存用量/率达到一定程度,Pod 的实例数量得到了扩展,就有可能避免 Pod 被系统杀死重启。
Kubernetes 官方提供了如何扩展指标的方案,但这对于一般的用户而言并不好掌握。我的建议是选用市面上可见的基于 Kubernetes 实现的应用管理平台。它们往往已经将自动伸缩功能封装成为简单易用的功能,并且提供了上述几种伸缩判断指标。推荐使用北京好雨科技开源的 Rainbond 云原生管理平台。
Rainbond 目前已经集成了开箱可用的自动伸缩功能,下面是功能截图。
功能界面已经将易用性做到了极致,即使不去关注之前章节所写的纯技术内容,也可以掌握相关的设置。
在这个功能界面的示例中,将 CPU 使用率和内存使用率同时设定了。在 Kubernetes 中,一旦出现同个 hpa 设定中,包含了多个判定条件时,会分别计算在每一种条件下,满足条件的 Pod 实例数量,并在所有结果之中选择最大值作为最终的实例数量。
更多需要了解的内容,可以参考 Kubernetes 官方手册
基于Kubernetes的hpa实现pod实例数量的自动伸缩的更多相关文章
- Kubernetes自动伸缩pod-HPA
在运维中,虽然能预先知道负载何时会飙升,或者如果负载的变化是较长时间内逐渐发生的,手动扩容也是可以接受的,但指望靠人工干预来处理突发而不可预测的流量增长,仍然不够理想. 幸运的是,Kubernetes ...
- Kubernetes 自动伸缩 auto-scaling
使用 Kubernetes 的客户能够迅速响应终端用户的请求,交付软件也比以往更快.但是,当你的服务增长速度比预期更快时,计算资源不够时,该怎么处理呢? 此时可以很自豪地说: Kubernetes 1 ...
- 基于Custom-metrics-apiserver实现Kubernetes的HPA(内含踩坑)
前言 这里要说一下Prometheus的检控指标从哪里来,它有3个渠道: 主机监控,也就是部署了Node Exporter组件的主机,它以DaemonSet或者系统进程的形式运行,Prometheus ...
- [置顶]
kubernetes资源对象--Horizontal Pod Autoscaling(HPA)
概念 HPA全称Horizontal Pod Autoscaling,即pod的水平自动扩展.自动扩展主要分为两种,其一为水平扩展,针对于实例数目的增减:其二为垂直扩展,即单个实例可以使用的资源的增减 ...
- 终于成功部署 Kubernetes HPA 基于 QPS 进行自动伸缩
昨天晚上通过压测验证了 HPA 部署成功了. 所使用的 HPA 配置文件如下: apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscale ...
- kubernetes之Pod水平自动伸缩(HPA)
https://k8smeetup.github.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/ Horizon ...
- Kubernetes 无法删除pod实例的排查过程
今天在k8s集群创建pod时,执行了如下命令: #kubectl run busybox-service --image=busybox --replicas=3 但是在创建过程中pod既然失败了, ...
- 三、Kubernetes之深入了解Pod
1.yaml格式的Pod配置文件内容及注解 深入Pod之前,首先我们来了解下Pod的yaml整体文件内容及功能注解. 如下: # yaml格式的pod定义文件完整内容: apiVersion: v ...
- kubernetes 实践四:Pod详解
本篇是关于k8s的Pod,主要包括Pod和容器的使用.Pod的控制和调度管理.应用配置管理等内容. Pod的定义 Pod是k8s的核心概念一直,就名字一样,是k8s中一个逻辑概念.Pod是docekr ...
随机推荐
- Django笔记&教程 7-1 基于类的视图(Class-based views)介绍
Django 自学笔记兼学习教程第7章第1节--基于类的视图(Class-based views)介绍 点击查看教程总目录 1 介绍 Class-based views (CBVs) are view ...
- 开源一个由.netcore/.net framework4.6开发的saas微商城+独立部署版本微小程序商城
一.项目介绍 开源一款基于.NET4.6开发的一款完整的微信商城SAAS平台,前端支持小程序.h5,由前端商城,商户管理后台,平台管理后台三大块组成,sass功能完善,支持商户拖拽式零代码创建并提交上 ...
- php 图像和水印
生成图像 $img = imagecreate(400,400); imagecolorallocate($img,255,255,255); imageellipse($img,200,200,50 ...
- windows桌面图标不显示,左右键无法使用的解决方法
问题描述: 日常使用软件中,一返回桌面,桌面图标全部不显示,点击鼠标的左键,右键毫无反应 解决方法: 1. Ctrl+Shift+Esc呼出软仵管理器 2. 右键windows资管理器,点击属性 配图 ...
- 提升开发效率的notepad++一些快捷方法(实体类的创建和查询sql语句的编写)
新手要创建数据库表中,对应字段名的实体类,是不是感觉很麻烦,可以用notepad++快速的把实体类中的字段名进行排版,随后直接粘入idea使用 下面是navicat的演示 选择一个表,右键选择设计表 ...
- java及python调用RabbitMQ
1,python调用MQ发送消息(生产者),话不多说,直接上干货 import pika 如下图 2.java调用MQ发送消息(生产者) 具体代码如下: python 的代码如下 connection ...
- vue3 高阶 API 大汇总,强到离谱
高阶函数是什么呢? 高阶函数英文名叫:Higher Order function ,一个函数可以接收一个或多个函数作为输入,或者输出一个函数,至少满足上述条件之一的函数,叫做高阶函数. 前言 本篇内容 ...
- 66-Reorder List
Reorder List My Submissions QuestionEditorial Solution Total Accepted: 64392 Total Submissions: 2818 ...
- JavaBean内省与BeanInfo
Java的BeanInfo在工作中并不怎么用到,我也是在学习spring源码的时候,发现SpringBoot启动时候会设置一个属叫"spring.beaninfo.ignore", ...
- 巩固javaweb第八天
巩固内容: HTML 段落 HTML 可以将文档分割为若干段落. HTML 段落 段落是通过 <p> 标签定义的. 实例 <p>这是一个段落 </p> <p& ...