恢弘志士之气,不宜妄自菲薄。这篇文章主要讲述AWS EKS Horizontal Pod Autoscaler(HPA)相关的知识,希望能为你提供帮助。
文章图片
简介本文是《AWS EKS 集群自动扩容 Cluster Autoscaler》一文中引申部分的扩展,介绍 Horizontal Pod Autoscaler(HPA)。
本文先简单介绍 Horizontal Pod Autoscaler,然后以前文的 EKS 测试环境为基础,进行简单测试。
HPA 算法介绍部分写的比较笼统,看不明白,可以先略过,先做测试,有个直观感受后再回头研究具体算法。
目录
- 环境(配置)
- Horizontal Pod Autoscaler 简介
- HPA 版本
- HPA 算法介绍
- 实战步骤
- 部署 metrics server
- 部署测试应用
- 创建 Horizontal Pod Autoscaler
- 测试 Horizontal Pod Autoscaler
- 增加 CPU 负载
- 降低 CPU 负载
- 总结
- 引申
- 资源下载
- 后记
- AWS Global 帐号,可在官网申请,一年内使用指定资源免费
- AWS EKS
- Win10 + WSL
- AWS CLI 2.2.17 如何 aws 版本太低还需要手工安装插件,建议升级到高版本
- Kubectl
Horizontal Pod Autoscaler 以标准 Kubernetes API 资源和 controller 的方式实现,Kubernetes 本身已经包含了 Horizontal Pod Autoscaler 的 controller,所以不需要额外部署(这与 Cluster Autoscaler 不同)。
虽然 Horizontal Pod Autoscaler 不需要额外部署 controller,但它需要获取 metrics 信息,metrics 信息需要从 Metrics Server 中获取或者从第三方软件获取。
HPA 工作原理
文章图片
Horizontal Pod Autoscaler 会周期性查询目标资源使用情况,然后和 HorizontalPodAutoscaler 中定义的值做比较,然后相应的调整 pod 数量。
周期大小通过 controller manager “--horizontal-pod-autoscaler-sync-period” flag 控制,默认为 15 秒。
主要有三种 metric
- per-pod resource metrics (like CPU)
注意在使用时,pod 中要设定好 resource request 的值。比如我们要在 Pod 中设定使用的 CPU 数量,如果没有设置的话,是无法计算 CPU 利用率的。
- per-pod custom metrics
- object metrics and external metrics
对于第一种 metric,我们可以通过 metric server 获得。对于后两种则需要第三方软件支持(比如 Prometheus Adapter)。我们下面只测试第一种 metric。
HPA 版本
Horizontal Pod Autoscaler 属于 K8s autoscaling API group,目前 autoscaling/v1 是稳定版本,只支持 CPU metrics autoscaling。
在 autoscaling/v2beta2 版本中,加入了 memory 和 custom metrics,这些指标在配合 autoscaling/v1 时,以 annotations 的形式出现。
HPA 算法介绍
HAP 以下列公式为基础计算调整比率(ratio)
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
例 1:
某个 deployment 中当前 replicas 设置为 2,CPU request 值为 100m(desiredMetricValue),当前从 metric server 得到的 CPU metric 为 200m(currentMetricValue)
100m,代表 0.1 个 CPU
则:desiredReplicas = 2 * ( 200 / 100 ) = 4,即运行的 Pod 数量会翻倍,ratio = 2
如果当前 CPU metric 为 50m
则:desiredReplicas = 2 * ( 50 / 100 ) = 1,即运行的 Pod 数量减半,ratio = 0.5
当 ratio 计算出来与 1 接近时,则不会变化,以防止出现过度扩展或者收缩,默认变化小于 0.1(tolerance)时(即 ratio 计算出来大于 0.9 小于 1.1)不会变动。
我们可以通过--horizontal-pod-autoscaler-tolerance 改变这个默认值。
当指定了 targetAverageValue 或者 targetAverageUtilization 值 ,计算 currentMetricValue 时会把得到的结果对目标(比如 deployment)中所有的 Pod 的数量取平均值。
在计算平均值时,正在停止或者失败的 Pod 不记入 Pod 数量。这里会计算两次平均值。
在第一次计算平均值时,不是 ready 状态和缺少 metric 的 Pod不记入Pod 总数。
在第二次计算平均值时,不是 ready 状态和缺少 metric 的 Pod记入Pod 总数。
用两次计算平均值算出对应的调整比率(ratio),如果第二次算出的 ratio 反转了 scale 方向,或者处于 tolerance 之内则放弃 scale,否则按第二次算出的 ratio 进行调整。
如果在 HPA 中指定多个目标 metric,则对每个 metric 重复上述计算过程,最后取 desiredReplicas 最大的值做为调整值。
最后,scale up 会尽快进行,而 scale down 会逐步进行,默认间隔为 5 分钟,可以通过--horizontal-pod-autoscaler-downscale-stabilization flag 更改设置。
在 5 分钟之内,每隔 15 秒计算一次 scale down 的值,最后取所有结果中最大的值做为这次 scale down 的最终值。
注意:目前 AWS EKS 并不支持自行设置 control plane flag,所以上述 flag 无法在 EKS 中改动,但在 autoscaling/v2beta2 中可以在 HPA 对象中控制 scaling 的行为。
实战步骤1. 部署 metrics server
我们在《多种方式访问 AWS EKS 的 Kubernetes Dashboard 上篇》一文中已经在 EKS 中部署了 metrics server,这个 metrics server 就可以做为 Horizontal Pod Autoscaler 获取 metrics 的资源。
2. 部署测试应用
下载 K8s 官网的测试应用
wget --no-check-certificate https://k8s.io/examples/application/php-apache.yaml
文章图片
php-apache.yaml 文件创建了一个 deployment “php-apache”和一个 service,文件内容截取一段如下
#1
replicas: 1
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
image: k8s.gcr.io/hpa-example
ports:
- containerPort: 80
#2
resources:
limits:
cpu: 500m
requests:
cpu: 200m
说明:
- #1 默认 replicas 为 1
- #2 在 spec.containers.resources 中设定需要的 CPU 资源
- limit:最多可使用资源,500m(0.5 个 CPU)
- requests:期望使用资源(desiredMetricValue),200m(0.2 个 CPU)
kubectl apply -f php-apache.yaml
文章图片
观察部署的 php-apache pod
kubectl get pods
php-apache-d4cf67d68-2qllw 处于 pending 状态
文章图片
用 describe 查看 pod 详情,可以看到我们在上一篇文章中部署的 Cluster Autoscaler 开始工作,扩容 node 了
kubectl describe pods/php-apache-d4cf67d68-2qllw
Events:
TypeReasonAgeFromMessage
-------------------------
WarningFailedScheduling72s (x2 over 73s)default-scheduler0/2 nodes are available: 2 Too many pods.
NormalTriggeredScaleUp71scluster-autoscalerpod triggered scale-up: [eks-tsEKSnodeGrp-80be391c-95d8-ba91-fd97-e8b0b3f23444 2->
3 (max: 3)]
WarningFailedScheduling2s (x3 over 32s)default-scheduler0/3 nodes are available: 1 node(s) had taint node.kubernetes.io/not-ready: , that the pod didnt tolerate, 2 Too many pods.
文章图片
文章图片
过一段时间再看 php-apache-d4cf67d68-2qllw,可以看到正在运行了
文章图片
注意:Cluster Autoscaler 不是本篇要讲的内容,只是沿用之前的环境测试时,刚好资源不足触发了 node 扩容
3. 创建 Horizontal Pod Autoscaler
Horizontal Pod Autoscaler(HPA)是通过 k8s api 资源实现,也就是说 HPA 也是一个 K8s 对象。
下面,我们创建测试应用的 HPA 对象
运行以下语句创建 HPA
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
文章图片
说明:
- 命令创建了一个叫“php-apache”的 HPA,与 deployment 的名称相同
- 我们为 deployment “php-apache”创建了 HPA,replicas 变动范围是最小 1,最大 10。目标 CPU 利用率(utilization)为 50%。上面我们设定 CPU request 值为 200m,所以转发为目标平均 CPU 值为 100m
- 命令只能运行一次,重复运行会报“AlreadyExists”错误
Error from server (AlreadyExists): horizontalpodautoscalers.autoscaling "php-apache" already exists
查看 HPA “php-apache”
文章图片
4. 测试 Horizontal Pod Autoscaler
我们可以运行 top 命令,查看当前 pod 的负载情况
kubectl top pod php-apache-d4cf67d68-2qllw
文章图片
说明:目前消耗 1m(0.001 个 CPU)CPU,9Mi 内存
增加 CPU 负载我们在新的 terminal 窗口中运行下列命令,让 php-apache 的 pod 过载
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01;
do wget -q -O- http://php-apache;
done"
说明:这里利用 busybox 镜像临时生成一个 pod,用 while 循环不停的访问 php-apache 的 service,而 php-apache 中的 k8s.gcr.io/hpa-example 镜像已经配置了进行消耗 CPU 的计算网页,所以 php-apache pod 的 CPU 负载会很快增长
文章图片
再用 top 查看 pod,可见 CPU 消耗增长很快
文章图片
查看 HPA,可以看到 REPLICAS 已变成 7,目前平均 CPU 为 53%
文章图片
过一会儿再次查看 HPA,可以看到 REPLICAS 已变成 8,平均 CPU 在 50%以下,scale up 稳定在 8 个 pod
文章图片
文章图片
我们再随便查看 3 个 pod 的 CPU 负载情况,虽然有的大于目标值 100m,但 8 个 pod 平均值会低于 100m
文章图片
降低 CPU 负载在刚才运行增加负载的窗口运行\\< Ctrl\\> + C,终止命令
文章图片
回到原来的窗口查看 HPA,多次执行可以看到平均 CPU 负载已经降到 0 了,但 REPLICAS 还是 8 个,不会立即降低
文章图片
差不多过了 4,5 分钟,REPLICAS 最终变为 1
文章图片
总结相对于 cluster autoscaler,HPA 实现更简单,在部署 metric server 或者其它第三方可以提供 metric 的软件后,我们就可以通过命令对 deployment 等创建 HPA 对象。
本文中利用 kubectl autoscale 直接创建 HPA 对象,当然我们也可以用熟悉的 yaml 文件的方式创建 HPA 对象。
资源下载AWS 官网 Horizontal Pod Autoscaler
https://docs.aws.amazon.com/eks/latest/userguide/horizontal-pod-autoscaler.html
Kubernetes 官网 Horizontal Pod Autoscaler
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/
后记本文在测试的时候触发了 Cluster Autoscaler,最终增加了 2 node。大家在做实验的时候,如果没有部署 Cluster Autoscaler,
则可以先把之前实验部署的其它 deployment 先删除掉,或者再增加一个新的 nodegroup,防止扩容的 Pod 一直处于 pending 状态,影响实验效果。
::: hljs-center
喜欢请点赞,禁止转载,转发请标明出处
关注 B 站 UP 主“我是手拉面” 观看更多视频
微信公众号“全是 AWS 干货”
:::
:::
推荐阅读
- mysql配置主从配置遇到的坑
- web服务之源码编译安装LAMP(编译安装PHP 解析环境)
- python自动化测试六
- LAMP(ApacheMySQLPHP)
- 运维工程师必备利器|一招实现运维智能化!
- Web服务之Nginx优化与防盗链
- 自动化集成(Pipeline整合Docker+K8S)
- centos7下配置tomcat环境变量
- 从内存管理原理,窥探OS内存管理机制