0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Horizontal Pod Autoscaler的工作原理

马哥Linux运维 来源:博客园 作者:大数据老司机 2022-09-21 10:57 次阅读

概述

Horizontal Pod Autoscaler(HPA,Pod水平自动伸缩),根据平均 CPU 利用率、平均内存利用率或你指定的任何其他自定义指标自动调整 Deployment 、ReplicaSet 或 StatefulSet 或其他类似资源,实现部署的自动扩展和缩减,让部署的规模接近于实际服务的负载。HPA不适用于无法缩放的对象,例如DaemonSet。

官方文档:https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale/

实际生产中,一般使用这四类指标:

  • Resource metrics——CPU核 和 内存利用率指标。
  • Pod metrics——例如网络利用率和流量。
  • Object metrics——特定对象的指标,比如Ingress, 可以按每秒使用请求数来扩展容器。
  • Custom metrics——自定义监控,比如通过定义服务响应时间,当响应时间达到一定指标时自动扩容。

安装 metrics-server

HAP 前提条件

默认情况下,Horizontal Pod Autoscaler 控制器会从一系列的 API 中检索度量值。集群管理员需要确保下述条件,以保证 HPA 控制器能够访问这些 API:

  • 对于资源指标,将使用 metrics.k8s.io API,一般由 metrics-server 提供。它可以作为集群插件启动。
  • 对于自定义指标,将使用 custom.metrics.k8s.io API。它由其他度量指标方案厂商的“适配器(Adapter)” API 服务器提供。检查你的指标管道以查看是否有可用的 Kubernetes 指标适配器。
  • 对于外部指标,将使用 external.metrics.k8s.io API。可能由上面的自定义指标适配器提供。
Kubernetes Metrics Server:
  • Kubernetes Metrics Server 是 Cluster 的核心监控数据的聚合器,kubeadm 默认是不部署的。
  • Metrics Server 供 Dashboard 等其他组件使用,是一个扩展的 APIServer,依赖于 API Aggregator。所以,在安装 Metrics Server 之前需要先在 kube-apiserver 中开启 API Aggregator。
  • Metrics API 只可以查询当前的度量数据,并不保存历史数据。
  • Metrics API URI 为 /apis/metrics.k8s.io/,在 k8s.io/metrics 下维护。
  • 必须部署 metrics-server 才能使用该 API,metrics-server 通过调用 kubelet Summary API 获取数据。
开启 API Aggregator
#添加这行
#--enable-aggregator-routing=true
###修改每个 API Server 的 kube-apiserver.yaml 配置开启 Aggregator Routing:修改 manifests 配置后 API Server 会自动重启生效。
cat/etc/kubernetes/manifests/kube-apiserver.yaml

843d6e50-3957-11ed-9e49-dac502259ad0.png

开始安装 metrics-server

GitHub地址:https://github.com/kubernetes-sigs/metrics-server/releases

下载

wgethttps://github.com/kubernetes-sigs/metrics-server/releases/download/metrics-server-helm-chart-3.8.2/components.yaml

修改

...
template:
metadata:
labels:
k8s-app:metrics-server
spec:
containers:
-args:
---cert-dir=/tmp
---secure-port=4443
---kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
---kubelet-use-node-status-port
---kubelet-insecure-tls#加上该启动参数,不加可能会报错
image:registry.aliyuncs.com/google_containers/metrics-server:v0.6.1#镜像地址根据情况修改
imagePullPolicy:IfNotPresent
...
metrics-serverpod无法启动,出现日志unabletofullycollectmetrics:...x509:cannotvalidatecertificateforbecause...itdoesn'tcontainanyIPSANs...

解决方法:在metrics-server中添加--kubelet-insecure-tls参数跳过证书校验

84589e1e-3957-11ed-9e49-dac502259ad0.png

开始安装
kubectlapply-fcomponents.yaml
kubectlgetpod-nkube-system|grepmetrics-server
#查看
kubectlgetpod-nkube-system|grepmetrics-server
#查看node和pod资源使用情况
kubectltopnodes
kubectltoppods

84726eb6-3957-11ed-9e49-dac502259ad0.png

Horizontal Pod Autoscaler 工作原理

原理架构图

85387098-3957-11ed-9e49-dac502259ad0.png

  • 自动检测周期由 kube-controller-manager--horizontal-pod-autoscaler-sync-period 参数设置(默认间隔为 15 秒)。
  • metrics-server 提供 metrics.k8s.io API 为pod资源的使用提供支持。
  • 15s/周期 -> 查询metrics.k8s.io API -> 算法计算 -> 调用scale 调度 -> 特定的扩缩容策略执行。
HPA扩缩容算法

从最基本的角度来看,Pod 水平自动扩缩控制器根据当前指标和期望指标来计算扩缩比例。

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

如果计算出的扩缩比例接近 1.0, 将会放弃本次扩缩, 度量指标 / 期望指标接近1.0。

缩容

冷却/延迟: 如果延迟(冷却)时间设置的太短,那么副本数量有可能跟以前一样出现抖动。默认值是 5 分钟(5m0s)--horizontal-pod-autoscaler-downscale-stabilization

特殊处理
  • 丢失度量值:缩小时假设这些 Pod 消耗了目标值的 100%, 在需要放大时假设这些 Pod 消耗了 0% 目标值。这可以在一定程度上抑制扩缩的幅度。
  • 存在未就绪的pod的时候:我们保守地假设尚未就绪的 Pod 消耗了期望指标的 0%,从而进一步降低了扩缩的幅度。
  • 未就绪的 Pod 和缺少指标的 Pod 考虑进来再次计算使用率。如果新的比率与扩缩方向相反,或者在容忍范围内,则跳过扩缩。否则,我们使用新的扩缩比例。指定了多个指标, 那么会按照每个指标分别计算扩缩副本数,取最大值进行扩缩。
HPA 对象定义
apiVersion:autoscaling/v2beta2
kind:HorizontalPodAutoscaler
metadata:
name:nginx
spec:
behavior:
scaleDown:
policies:
-type:Pods
value:4
periodSeconds:60
-type:Percent
value:10
periodSeconds:60
stabilizationWindowSeconds:300

scaleTargetRef:
apiVersion:apps/v1
kind:Deployment
name:nginx
minReplicas:1
maxReplicas:10
metrics:
-type:Resource
resource:
name:cpu
target:
type:Utilization
averageUtilization:50

HPA对象默认行为

behavior:
scaleDown:
stabilizationWindowSeconds:300
policies:
-type:Percent
value:100
periodSeconds:15
scaleUp:
stabilizationWindowSeconds:0
policies:
-type:Percent
value:100
periodSeconds:15
-type:Pods
value:4
periodSeconds:15
selectPolicy:Max

示例演示

编排yaml
apiVersion:autoscaling/v2
kind:HorizontalPodAutoscaler
metadata:
name:hap-nginx
spec:
maxReplicas:10#最大扩容到10个节点(pod)
minReplicas:1#最小扩容1个节点(pod)
metrics:
-resource:
name:cpu
target:
averageUtilization:40#CPU平局资源使用率达到40%就开始扩容,低于40%就是缩容
#设置内存
# AverageValue:40
type:Utilization
type:Resource
scaleTargetRef:
apiVersion:apps/v1
kind:Deployment
name:hap-nginx
---
apiVersion:v1
kind:Service
metadata:
name:hap-nginx
spec:
type:NodePort
ports:
-name:"http"
port:80
targetPort:80
nodePort:30080
selector:
service:hap-nginx
---
apiVersion:apps/v1
kind:Deployment
metadata:
name:hap-nginx
spec:
replicas:1
selector:
matchLabels:
service:hap-nginx
template:
metadata:
labels:
service:hap-nginx
spec:
containers:
-name:hap-nginx
image:nginx:latest
resources:
requests:
cpu:100m
memory:100Mi
limits:
cpu:200m
memory:200Mi

主要参数解释如下:

  • scaleTargetRef:目标作用对象,可以是Deployment、ReplicationController或ReplicaSet。
  • minReplicas和maxReplicas:Pod副本数量的最小值和最大值,系统将在这个范围内进行自动扩缩容操作,并维持每个Pod的内存使用率为40%,这个值就是上面设置的阈值averageUtilization。
  • metrics:目标指标值。在metrics中通过参数type定义指标的类型;通过参数target定义相应的指标目标值,系统将在指标数据达到目标值时(考虑容忍度的区间,见前面算法部分的说明)触发扩缩容操作。
  • 对于CPU使用率,在target参数中设置averageUtilization定义目标平均CPU使用率。
  • 对于内存资源,在target参数中设置AverageValue定义目标平均内存使用值。
执行
kubectlapply-ftest.yaml
使用 ab 工具进行压测

进入apache官网 http://httpd.apache.org/ 下载apache即可,或者直接通过yum安装apache都行,这里选择最简单的方式yum安装

yuminstallhttpd-y

开始压测

ab-n100000-c800http://local-168-182-112:30080/

#-c:并发数
#-n:总请求数

8586720c-3957-11ed-9e49-dac502259ad0.png

85b7537c-3957-11ed-9e49-dac502259ad0.png

从上图发现已经实现了根据CPU 动态扩容了,关于更多 HAP相关的知识点,可以先查看官方文档。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10855

    浏览量

    211605
  • kubernetes
    +关注

    关注

    0

    文章

    224

    浏览量

    8713

原文标题:K8s pod 动态弹性扩缩容 HAP(metrics-server)

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    感光太阳能灯工作原理。#工作原理大揭秘

    太阳工作原理DIY
    jf_24750660
    发布于 :2022年11月07日 22:26:04

    从零开始入门 K8s| 详解 Pod 及容器设计模式

    或者另外像 Sidecar 的方式去解决;当然还有一个典型例子就是我的日志收集,日志收集本身是一个进程,是一个小容器,那么就可以把它打包进 Pod 里面去做这个收集工作;还有一个非常重要的东西就是
    发表于 09-20 15:12

    Pod资源配置

    《Kubernetes进阶实战》第四章《管理Pod资源对象》
    发表于 10-22 14:39

    Land Pattern and POD

    Land Pattern and POD
    发表于 03-05 15:59 0次下载
    Land Pattern and <b class='flag-5'>POD</b>

    Kubernetes组件pod核心原理

    1. 核心组件原理 —— pod 核心原理 1.1 pod 是什么 pod 也可以理解是一个容器,装的是 docker 创建的容器,也就是用来封装容器的一个容器; pod 是一个虚拟化
    的头像 发表于 09-02 09:27 1823次阅读

    pod底层网络和数据存储是如何进行的

    1. 核心组件原理 —— pod 核心原理 1.1 pod 是什么 pod 也可以理解是一个容器,装的是 docker 创建的容器,也就是用来封装容器的一个容器; pod 是一个虚拟化
    的头像 发表于 09-24 11:35 1682次阅读

    如何利用Docker实现Pod

    Container 和 Pod 是相似的。在底层,它们主要依赖 Linux 命名空间和 cgroup。但是,Pod 不仅仅是一组容器。Pod 是一个自给自足的高级构造。
    发表于 11-14 12:51 1398次阅读

    Kubernetes中的Pod简易理解

    Pod是Kubernetes中非常重要的概念,也是Kubernetes管理的基本单位。正如其名,Pod像一个豌豆荚,可以容纳多个container,拥有相同的IP地址。
    的头像 发表于 02-15 10:44 1271次阅读

    什么是CNI,基于Calico的Pod网络介绍

    每一个Node上都会有一个tunl0的虚拟网卡,这个网卡可以理解成网桥,所有Pod都要基于此网桥来和其它Pod通信。 ② 每生成一个新的Pod,那么在Node上都会生成一个calixxxx的虚拟网卡,这个网卡会对应到
    发表于 04-20 09:37 2340次阅读

    k8s与pod之间是如何进行网络隔离的?

    NetworkPolicy用来控制PodPod之间的网络通信,它也支持针对Namespace进行限制。
    的头像 发表于 05-11 09:35 1548次阅读
    k8s与<b class='flag-5'>pod</b>之间是如何进行网络隔离的?

    Kubernetes Pod如何独立工作

    在学习 Kubernetes 网络模型的过程中,了解各种网络组件的作用以及如何交互非常重要。本文就介绍了各种网络组件在 Kubernetes 集群中是如何交互的,以及如何帮助每个 Pod 都能获取 IP 地址。
    的头像 发表于 05-16 14:29 621次阅读
    Kubernetes <b class='flag-5'>Pod</b>如何独立<b class='flag-5'>工作</b>

    initContainer工作原理

    一、initContainer工作原理 初始化容器是在pod的主容器启动之前要运行的容器,主要是做一些 主容器的前置工作 ,它具有两大特征: 1、初始化容器必须运行完成直至结束,若某初始化容器运行
    的头像 发表于 05-30 09:49 679次阅读
    initContainer<b class='flag-5'>工作原理</b>

    POD到底是什么?聊聊POD

    POD,即Plain Old Data的缩写,plain代表普通,Old代表旧,从字面意思看是老的、普通的数据类型。
    的头像 发表于 06-19 15:24 5487次阅读

    Pod是如何在底层实现的?如何使用Docker创建Pod

    刚开始接触 Kubernetes 时,你学到的第一件事就是每个 Pod 都有一个唯一的 IP 和主机名,并且在同一个 Pod 中,容器可以通过 localhost 相互通信。所以,显而易见,一个 Pod 就像一个微型的服务器。
    的头像 发表于 08-14 10:33 1295次阅读
    <b class='flag-5'>Pod</b>是如何在底层实现的?如何使用Docker创建<b class='flag-5'>Pod</b>?

    Pod一直处于Pending状态?什么是Pod拓扑约束?

    起因: 今天在部署组件的时候,发现组件的pod一直处于Pending状态,报错显示的原因是:不满足Pod拓扑分布约束,看了代码发现是原来同事给组件新增了Pod拓扑约束。
    的头像 发表于 12-18 11:46 1206次阅读
    <b class='flag-5'>Pod</b>一直处于Pending状态?什么是<b class='flag-5'>Pod</b>拓扑约束?