当前位置: 首页 > news >正文

kubenetes从入门到上天系列第二十四篇:Kubernetes Pod的自动扩缩容

一:弹性扩缩容背景分析

1:背景

弹性伸缩是根据用户的业务需求和策略,自动 “调整” 其 “弹性资源” 的管理服务。通过弹性伸缩功能,用户可设置定时、周期或监控策略,恰到好处地增加或减少 “弹性资源”,并完成实例配置,保证业务平稳健康运行。

在实际工作中,我们常常需要做一些扩容缩容操作,如:电商平台在 618 和双十一搞秒杀活动。由于资源紧张、工作负载降低等都需要对服务实例数进行扩缩容操作。

2:K8s扩缩容分为两种

在 k8s 中扩缩容分为两种:

  1. Node 层面:对 K8s 物理节点扩容和缩容,根据业务规模实现物理节点自动扩缩容。

阿里的ack可以实现Node方面的扩容,但是得买人家的云服务,加购一个扩缩容服务。底层用的是OpenStack。

  1. Pod 层面:我们一般会使用 Deployment 中的 replicas 参数,设置多个副本集来保证服务的高可用,但是这是一个固定的值,比如我们设置 10 个副本,就会启动 10 个 pod 同时 running 来提供服务。如果这个服务平时流量很少的时候,也是 10 个 pod 同时在 running,而流量突然暴增时,又可能出现 10 个 pod 不够用的情况。针对这种情况怎么办?就需要扩容和缩容。

二:K8s当中自动伸缩方案

一般情况下,我们在生产当中使用的最多的就是HPA。毕竟cpu和内存使用率是最好的度量指标。

1:HPA

HPA水平自动伸缩。通过此功能,只需简单的配置,便可以利用监控指标(cpu 使用率、磁盘、自定义的等)自动的扩容或缩容服务中 Pod 数量,当业务需求增加时,系统将无缝地自动增加适量 pod 容器,提高系统稳定性。

要想实现自动扩容,需要先考虑如下几点:

1:通过哪些指标决定扩容缩容?

HPA v1 版本只能基于 CPU 使用率来进行自动扩容:但是并非所有的系统都可以仅依靠 CPU 或者 Memory 指标来扩容,对于大多数 Web 应用的后端来说,基于每秒的请求数量进行弹性伸缩来处理突发流量会更加的靠谱,所以对于一个自动扩容缩容系统来说,我们不能局限于 CPU、Memory 基础监控数据,每秒请求数 RPS 等自定义指标也是十分重要。

HPA v2 版本可以根据自定义的指标进行自动扩容。hpa v2 可以基于内存和自定义的指标做扩容和缩容。

2:如何采集资源指标

如果我们的系统默认依赖 Prometheus,自定义的 Metrics 指标则可以从各种数据源或者 exporter 中获取,基于拉模型的 Prometheus 会定期从数据源中拉取数据。也可以基于 metrics-server 自动获取节点和 pod 的资源指标。

3:如何实现自动扩缩容

HPA controller 已实现简单的自动扩缩容逻辑。默认每 30 秒检测一次指标,当检测到配置的 HPA 目标值时,计算预期副本数并执行扩缩容操作。为避免过于频繁,默认 5 分钟内未重新扩缩容才会触发。HPA 算法较保守,可能不适用于部分场景。例如,快速流量突发时,若处于 5 分钟 HPA 稳定期,可能导致无法扩容。

2:KPA

KPA 基于请求数对 Pod 实现自动扩缩容,其主要限制是不支持基于 CPU 的自动扩缩容。

  1. 根据并发请求数实现自动扩缩容
  2. 设置扩缩容边界实现自动扩缩容扩缩容边界指应用程序提供服务的最小和最大 Pod 数量。通过设置应用程序提供服务的最小和最大 Pod 数量实现自动扩缩容。相比 HPA,KPA 会考虑更多的场景,其中一个比较重要的是流量突发的时候。

3:VPA

Kubernetes VPA(Vertical Pod Autoscaler,垂直 Pod 自动扩缩容),VPA 会基于 Pod 的资源使用情况自动为集群设置资源占用的限制,从而让集群将 Pod 调度到有足够资源的最佳节点上。VPA 也会保持最初容器定义中资源 request 和 limit 的占比。它会根据容器资源使用率自动设置 pod 的 CPU 和内存的 requests,从而允许在节点上进行适当的调度,以便为每个 Pod 提供适当的可用的节点。它既可以缩小过度请求资源的容器,也可以根据其使用情况随时提升资源不足的容量。

三:基于HPA的CPU指标实现Pod的自动伸缩

HPA(Horizontal Pod Autoscaler,Pod 水平自动伸缩)基于 CPU 利用率自动扩缩容 Deployment 中的 Pod 数量,也支持自定义指标。不适用于无法缩放的对象(DaemonSets)。无状态副本集Deployment,有状态副本集StatefulSet。

Kubernetes API 资源和控制器实现,控制器定期获取平均 CPU 利用率,与目标值对比后调整副本数。

1:HPA工作原理

1:指标从哪里来?

从 K8s 1.8 版本开始,CPU、内存等资源的 metrics 信息可通过Metrics API获取,用户可直接获取这些 metrics 信息(如通过kubectl top命令),HPA 会使用这些 metrics 信息实现动态伸缩

2:Metrics server

  1. Metrics server 是 K8s 集群资源使用情况的聚合器。
  2. 从 1.8 版本开始,Metrics server 可通过 yaml 文件的方式进行部署。
  3. Metrics server 收集所有 node 节点的 metrics 信息。

3:HPA 如何运作?

HPA 的实现是一个控制循环,由 controller manager 的--horizontal-pod-autoscaler-sync-period参数指定周期(默认值为 15 秒)。每个周期内,controller manager 根据每个HorizontalPodAutoscaler定义中指定的指标查询资源利用率。controller manager 可从 resource metrics API(Pod 资源指标)和 custom metrics API(自定义指标)获取指标。

kubectl top nodes 可以查看Node资源指标,同样kubectl top pods podname查看。Metric Server就是提供这个命令支撑的。

然后,通过现有 pods 的 CPU 使用率的平均值(计算方式是最近的 pod 使用量(最近一分钟的平均值,从 metrics-server 中获得)除以设定的每个 Pod 的 CPU 使用率限额)跟目标使用率进行比较,并且在扩容时,还要遵循预先设定的副本数限制:MinReplicas <= Replicas <= MaxReplicas。

计算扩容后 Pod 的个数:sum (最近一分钟内某个 Pod 的 CPU 使用率的平均值)/CPU 使用上限的整数 + 1。

4:HPA 工作流程

  1. 创建 HPA 资源,设定目标 CPU 使用率限额,以及最大、最小实例数。
  2. 收集一组中(PodSelector)每个 Pod 最近一分钟内的 CPU 使用率,并计算平均值。
  3. 读取 HPA 中设定的 CPU 使用限额。
  4. 计算:平均值之和 / 限额,求出目标调整的实例个数。
  5. 目标调整的实例数不能超过 1 中设定的最大、最小实例数,如果没有超过,则扩容。超过,则扩容至最大的实例个数。
  6. 回到 2,不断循环。

5:核心计算(简化)

目标实例数 = 平均 CPU 使用率 / 目标 CPU 使用率限额最终实例数会被钳制在最小实例数与最大实例数之间。

2:创建数据采集组件MetricServer

metrics-server 是集群范围内的资源数据集和工具,仅用于显示数据,不提供数据存储服务,核心聚焦于资源度量 API 的实现(如 CPU、文件描述符、内存、请求延时等指标)。它收集数据供 Kubernetes(k8s)集群内部组件使用,例如 kubectl、HPA、调度器(scheduler)等。

我们之前已经创建过了。查看一下。

[root@k8s-node1 ~]# kubectl get pods -n kube-system -w NAME READY STATUS RESTARTS AGE coredns-75944bc9b-w9p2v 1/1 Running 6 (87s ago) 14d coredns-75944bc9b-zxrsd 1/1 Running 12 (83s ago) 36d etcd-k8s-node1 1/1 Running 33 (93s ago) 189d kube-apiserver-k8s-node1 1/1 Running 10 (93s ago) 26d kube-controller-manager-k8s-node1 1/1 Running 35 (93s ago) 189d kube-proxy-cgn9t 1/1 Running 32 (83s ago) 189d kube-proxy-jxkfh 1/1 Running 33 (93s ago) 189d kube-proxy-qdp9p 1/1 Running 33 (86s ago) 189d kube-proxy-vhhhs 1/1 Running 19 (76s ago) 58d kube-scheduler-k8s-node1 1/1 Running 35 (93s ago) 189d metrics-server-589dbffcf9-h54f7 0/1 Running 10 (82s ago) 14d tigera-operator-5d6845b496-rdbg2 1/1 Running 25 (83s ago) 36d metrics-server-589dbffcf9-h54f7 1/1 Running 10 (85s ago) 14d

我们确实已经成功部署过了。

3:创建测试Pod

apiVersion: apps/v1 kind: Deployment metadata: name: hpatest spec: replicas: 1 selector: matchLabels: app: hpatest template: metadata: labels: app: hpatest spec: containers: - name: hpatest image: nginx imagePullPolicy: IfNotPresent command: ["/bin/sh"] args: ["-c", "/usr/sbin/nginx; while true; do echo `hostname -I` > /usr/share/nginx/html/index.html; sleep 120; done"] ports: - containerPort: 80 resources: limits: cpu: 500m requests: cpu: 200m --- apiVersion: v1 kind: Service metadata: name: hpatest-svc spec: selector: app: hpatest ports: - port: 80 targetPort: 80 protocol: TCP

4:顺便验证一个问题

Node节点上访问svc的name:80是访问不通的,因为Node上没有在host中配置coredns的解析地址。Pod中curl name:80直接就通了,因为Pod创建的时候,内部就植入了coredns的ip地址。

[root@k8s-node1 test]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hpatest-svc ClusterIP 10.102.178.236 <none> 80/TCP 9s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 189d new-nginx ClusterIP 10.109.4.182 <none> 80/TCP 5d15h nginx NodePort 10.105.226.103 <none> 80:30010/TCP 13d old-nginx ClusterIP 10.96.83.158 <none> 80/TCP 5d15h readiness-http NodePort 10.96.106.97 <none> 80:30080/TCP 16d tomcat ClusterIP 10.99.11.198 <none> 8080/TCP 6d19h tomcat-https ClusterIP 10.108.91.114 <none> 8080/TCP 5d17h [root@k8s-node1 test]# curl 10.102.178.236:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> [root@k8s-node1 test]# curl hpatest-svc curl: (6) Could not resolve host: hpatest-svc; Unknown error [root@k8s-node1 test]# curl hpatest-svc curl: (6) Could not resolve host: hpatest-svc; Unknown error [root@k8s-node1 test]# kubectl exec -it my-nginx-654f997cd5-jtf5q -- bash root@my-nginx-654f997cd5-jtf5q:/# curl hpatest-svc <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> root@my-nginx-654f997cd5-jtf5q:/#

5:创建HPA

Web 服务正在运行,使用kubectl autoscale创建自动缩放器,实现对 Web 这个 deployment 创建的 pod 自动扩缩容。下面的命令将会创建一个 HPA,HPA 将会根据 CPU、内存等资源指标增加或减少副本数,创建一个可以实现如下目的的 hpa:

  1. 让副本数维持在 1-10 个之间(这里副本数指的是通过 deployment 部署的 pod 的副本数)
  2. 将所有 Pod 的平均 CPU 使用率维持在 50%(通过kubectl top pods看到的每个 pod 如果是 200 毫核,这意味着平均 CPU 利用率为 100 毫核)

创建这种资源可以使用命令,但是更推荐使用yaml资源文件。可以留痕。

1:查看当前pod的资源利用率

[root@k8s-node1 test]# kubectl top pod hpatest-68d7ccdc85-p672c NAME CPU(cores) MEMORY(bytes) hpatest-68d7ccdc85-p672c 0m 2Mi

2:定义Hpa资源文件

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: hpatest spec: minReplicas: 1 maxReplicas: 10 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: hpatest metrics: - type: Resource resource: name: cpu target: averageUtilization: 50 type: Utilization

3:压测查看扩容状态

四:基于HPA的内存指标实现Pod的扩缩容

1:创建测试Pod

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-hpa spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: http protocol: TCP resources: requests: cpu: 0.01 memory: 25Mi limits: cpu: 0.05 memory: 60Mi --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: selector: app: nginx type: NodePort ports: - name: http protocol: TCP port: 80 targetPort: 80

2:创建HPA

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: nginx-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx-hpa minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: memory target: type: Utilization averageUtilization: 60

3:同时监控CPU和内存的。

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: nginx-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx-hpa minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 60

这个也有 3 种:Utilization(使用率百分比)你现在用的CPU 50% → 超过就扩。AverageValue(平均值)比如 平均每个 Pod 500m CPU不是百分比,是绝对值Value(单值)极少用。Utilization 百分比的分母永远是 requests,不是 limits!

http://www.jsqmd.com/news/538511/

相关文章:

  • 豆包AI生成 —— 强化学习 —— TRPO算法
  • Llama-3.2V-11B-cot开源大模型实战教程:双卡4090环境下11B视觉模型快速调用
  • 基于Python的宠物商城网站毕业设计
  • 从Win10到Copilot:一文搞懂系统更新、硬件要求及AI助手完整配置流程
  • 测试行业“内卷”报告:哪些岗位还在涨薪?
  • 合肥金融雨桥 个人/企业融资顾问介绍: - 野榜精选
  • 别再到处找教程了!手把手教你用艾可API密钥配置Sider,5分钟搞定GPT-4o模型接入
  • CardEditor:3MB小工具解决桌游卡牌批量制作大难题
  • 在Ubuntu 20.04上为工业机器人搭建实时内核与EtherCAT主站:我的踩坑与避坑全记录
  • 排序算法---(一)
  • Universal-IFR-Extractor:UEFI固件分析工具的终极实战指南
  • 抖音无水印视频批量采集开源工具:3大突破实现内容获取全流程效率提升90%
  • STM32板级支持包实战:从GPIO配置到LED控制全流程解析
  • 3个实战技巧快速掌握英雄联盟智能工具集League Akari
  • C# 实现 Modern Standby 模式下的电源事件精准监听(Sleep 状态)
  • Aider Repo Map 功能实战:如何一键生成并保存整个项目的代码地图(附常见问题排查)
  • FanControl:实现散热智能化的全面解决方案
  • Wan2.2-I2V-A14B部署教程:多用户隔离+权限控制+日志监控配置
  • ArduPilot自定义参数实战:手把手教你让飞控向地面站“说话”(打印参数值)
  • RS485项目翻车实录:我是这样用FIFO解决多设备通信卡顿的
  • TikTok爆火:C语言代码让电脑无硬件发无线电,靠谱吗?
  • AXI非对齐访问实战指南:从WSTRB信号到DMA数据搬运的避坑细节
  • 5大核心功能提升英雄联盟体验:League-Toolkit从自动秒选到战绩分析全攻略
  • RAD-seq数据分析利器:Stacks拆分命令process_radtags.pl的实战指南
  • Linux网卡中断优化实战:如何让多核CPU均衡处理网络流量(附性能对比测试)
  • 塑料配件管厂家怎么选?从金华精彩看懂挤出工艺优化与稳定供货 - 企师傅推荐官
  • DataContext类
  • 汽车电子工程师必看:CAN总线硬件电路设计避坑指南(附TJA1050实战)
  • CCS12.3.0保姆级教程:手把手教你为AWR6843AOP毫米波雷达新建工程(附完整配置参数)
  • 如何用Audacity实现专业音频编辑?从入门到精通的完整指南