在 Kubernetes (K8S) 中,Horizontal Pod Autoscaler (HPA) 控制器是实现弹性伸缩的重要组件之一。HPA 控制器通过监控集群中的 CPU 和内存使用情况,自动增加或减少 Pod 的数量,以确保集群资源的充分利用和优化。在 K8S 中,HPA 控制器的应用可以大大简化集群的自动伸缩管理,并为应用程序提供更好的弹性和可用性。
本文以正在使用的 k8s 1.19.16 版本为例,对 hpa 弹性伸缩进行实践和验证。
hpa 版本
在 k8s-1.19.16 版本中,hpa 一共有三个版本,其中首选版本为 v1。
v1 版本的 HPA 只支持一种指标 —— CPU。传统意义上,弹性伸缩最少也会支持 CPU 与 Memory 两种指标,为什么在 Kubernetes 中只放开了 CPU 呢?其实最早的 HPA 是计划同时支持这两种指标的,但是实际的开发测试中发现:内存不是一个非常好的弹性伸缩判断条件。因为和 CPU不 同,很多内存型的应用,并不会因为 HPA 弹出新的容器而带来内存的快速回收,很多应用的内存都要交给语言层面的 VM 进行管理,也就是说,内存的回收是由 VM 的 GC 来决定的。这就有可能因为 GC 时间的差异导致 HPA 在不恰当的时间点震荡,因此在 v1 的版本中,HPA 就只支持了 CPU 这一种指标。
应用部署
部署 deployment
首先在 k8s 集群中部署一个 deployment 目标资源。
apiVersion: apps/v1
kind: Deployment
metadata:
name: dp12
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
jupiter.app.service: dp10
strategy:
rollingUpdate:
maxSurge: 3
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
jupiter.app.service: dp10
spec:
containers:
- image: hello-app:1.0
imagePullPolicy: IfNotPresent
name: container01
# 设定较小的容器配额,这样进行压测时,可以较容易观察到自动扩缩容的过程
resources:
limits:
cpu: 70m
memory: 500Mi
requests:
cpu: 10m
memory: 100Mi
dnsPolicy: ClusterFirst
nodeName: <nodeName>
restartPolicy: Always
部署 service+ingress
还需要部署 Service 和 Ingress 资源,这样我们就可以在集群外,通过压测工具对部署的 deployment 资源进行压测。
# Service
apiVersion: v1
kind: Service
metadata:
name: dp12-svc
namespace: default
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
jupiter.app.service: dp10
type: ClusterIP
---
# ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: newtest
namespace: default
spec:
rules:
- host: dp12.hpa.com
http:
paths:
- backend:
serviceName: dp12-svc
servicePort: 8080
path: /
pathType: ImplementationSpecific
上述资源部署完成后,测试是否可以通过 ingress 路由访问压测资源。确保测试成功后再进行后续的步骤。
压测和弹性伸缩
安装压测工具
需要先安装命令行压测工具,这里我选用的是 http_load
wget acme.com/software/http_load/http_load-12mar2006.tar.gz
tar -xvzf http_load-12mar2006.tar.gz
make && make install
# 如果 make 命令失败,可能是未安装 gcc,可以通过 yum install gcc 命令安装。
准备 url 文件 test-url.txt,内容如下。当然也可以按需增加 url 内容:
dp12.hpa.com/
dp12.hpa.com/1
dp12.hpa.com/2
dp12.hpa.com/abc
创建 hpa 弹性伸缩
创建弹性伸缩 hpa 资源,当 deployment 工作负载 cpu 使用率超过 50%时,就进行弹性扩容,最大扩容数量为 10 个副本数;
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: h3
namespace: default
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: dp12
# 当 cpu 资源利用率超过 50%,就会进行弹性扩容;
targetCPUUtilizationPercentage: 50
执行压测
执行压测压测,并观察 hpa 状态和 pod 变化:
# 以每秒 500 次请求的速率,向 test-url.txt 文件中的域名发起请求,持续事件 100秒;
http_load -rate 500 -seconds 100 test-url.txt
可以看到,随着压测进行,目标工作负载 cpu 使用量不断攀升,deploy 副本数也不断增加。
一段时间压测停止后,cpu 使用率下降,pod 陆续终止被回收。