前置条件
创建 Horizontal Pod Autoscaler
- 需要注意的是,
targetCPUUtilizationPercentage
字段已经被名为metrics
的数组所取代。CPU
利用率这个度量指标是一个resource metric
(资源度量指标),因为它表示容器上指定资源的百分比。 除CPU
外,你还可以指定其他资源度量指标。默认情况下,目前唯一支持的其他资源度量指标为内存。 只要metrics.k8s.io API
存在,这些资源度量指标就是可用的,并且他们不会在不同的Kubernetes
集群中改变名称。
Pod水平自动伸缩
- 水平扩缩意味着对
增加的负载
的响应是部署更多的 Pods。 这与垂直(Vertical)
扩缩不同,对于 Kubernetes, 垂直扩缩意味着将更多资源(例如:内存或 CPU)分配给已经为工作负载运行的 Pod。- Kubernetes 将水平 Pod 自动扩缩实现为一个间歇运行的控制回路(它不是一个连续的过程)。
间隔由kube-controller-manager
的--horizontal-pod-autoscaler-sync-period
参数设置(默认间隔为15
秒)。
必须依赖: K8S 容器性能指标 metrics-server
Kubernetes v1.23: 可配置的扩缩行为
通过压测CPU
来验证HPA
1. 创建部署压测程序的yaml文件
cat > php-apache.yaml << ERIC
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
selector:
matchLabels:
run: php-apache
replicas: 1
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
# CPU 密集型计算,应用程序
image: registry.cn-qingdao.aliyuncs.com/cn-aliyun/hpa-example:v0.1.0
ports:
- containerPort: 80
resources:
limits:
cpu: 500m
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: php-apache
labels:
run: php-apache
spec:
type: NodePort
ports:
- port: 80
# targetPort 是pod的端口
targetPort: 80
# 可以被外网访问的端口
nodePort: 30808
selector:
run: php-apache
ERIC
2. 创建部署HPA的yaml文件
cat > php-apache-autoscale.yaml << ERIC
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
# 告诉k8s你要指定的缩放目标是谁
scaleTargetRef:
apiVersion: apps/v1
# 缩放目标是名为php-apache的Deployment
kind: Deployment
name: php-apache
# 至少1个pod
minReplicas: 1
# 最多不超过3个pod
maxReplicas: 3
# 根据监控指标执行动态扩缩容
metrics:
- type: Resource
resource:
name: cpu
# 按数值
target:
type: AverageValue
# 当CPU的使用率超过200m时,进行扩容
averageValue: 200m
ERIC
3. 开始测试,执行测试命令
kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
通过压测内存
来验证HPA
1. 创建部署压测程序的yaml文件
cat > iris-server-stress.yaml << ERIC
apiVersion: apps/v1
kind: Deployment
metadata:
name: iris-server-stress
spec:
selector:
matchLabels:
run: iris-server-stress
replicas: 1
template:
metadata:
labels:
run: iris-server-stress
spec:
containers:
- name: iris-server-stress
# 消耗指定内存大小的应用程序
image: registry.cn-qingdao.aliyuncs.com/cn-aliyun/iris-server-stress:v0.1.0
ports:
- containerPort: 8080
resources:
limits:
memory: "2Gi"
requests:
memory: "1Gi"
---
apiVersion: v1
kind: Service
metadata:
name: iris-server-stress
labels:
run: iris-server-stress
spec:
type: NodePort
ports:
- port: 80
# targetPort 是pod的端口
targetPort: 8080
# 可以被外网访问的端口
nodePort: 30808
selector:
run: iris-server-stress
ERIC
2. 创建部署HPA的yaml文件
cat > iris-server-stress-autoscale.yaml << ERIC
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: iris-server-stress
spec:
# 告诉k8s你要指定的缩放目标是谁
scaleTargetRef:
apiVersion: apps/v1
# 缩放目标是名为iris-server-stress的Deployment
kind: Deployment
name: iris-server-stress
# 至少1个pod
minReplicas: 1
# 最多不超过3个pod
maxReplicas: 3
# 根据监控指标执行动态扩缩容
metrics:
- type: Resource
resource:
name: memory
# 按资源使用率(百分比)
target:
type: Utilization
averageUtilization: 70
ERIC
3. 开始测试,执行测试命令
## 不会触发扩容
curl http://localhost:30808/v1/stressMEM?mem=512
## 会触发扩容
curl http://localhost:30808/v1/stressMEM?mem=1433
结论
- 从测试结果可以确定,HPA的扩容指标是参照容器资源.资源请求限制的数值,做为百分比的参考;
- 因此我们运行应用程序的虚拟机的资源限制,不要小于 containers.resources.
requests.memory
这个数值,更不能超出 containers.resources.limits.memory
这个数值,否则会内存溢出
。
教学
自定义,创建测试程序
可以使用kubectl命令生成Deployment
模板(新手学习
)
kubectl create deploy container-pressure-test --image=polinux/stress:1.0.4 --dry-run=client -o yaml > container-pressure-test.yaml
还可以直接创建Deployment
模板(推荐使用
)
cat > container-pressure-test.yaml << ERIC
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: container-pressure-test
name: container-pressure-test
spec:
replicas: 1
selector:
matchLabels:
app: container-pressure-test
template:
metadata:
labels:
app: container-pressure-test
spec:
containers:
- image: polinux/stress:1.0.4
name: stress
command: [ "/bin/sh" ]
# 压测目标:保持3个CPU满负载工作,并且每次只测试16秒
# 每隔400s进行一次压测
#args: [ "-c", "while true; do stress -c 3 -t 16s; sleep 400; done" ]
# 压测目标:模拟产生6个进程,每个进程分配2G内存,持续消耗内存60秒后在释放,测试300S
# 每隔5s进行一次压测
args: [ "-c", "while true; do stress --vm 6 --vm-bytes 2G --vm-hang 60 -t 300s; sleep 5; done" ]
ERIC
## 运行
kubectl apply -f container-pressure-test.yaml
创建HPA
可以使用kubectl命令生成HPA模板(新手学习
)
kubectl autoscale deployment container-pressure-test --cpu-percent=5 --min=1 --max=10 --dry-run -o yaml > pressure-test-hpa.yaml
## 生成的文件内容如下
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
creationTimestamp: null
name: container-pressure-test
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: container-pressure-test
targetCPUUtilizationPercentage: 5
status:
currentReplicas: 0
desiredReplicas: 0
还可以直接创建HPA
模板(推荐使用
)
提示HPA
是要与你的工作负载进行绑定使用的
cat > pressure-test-hpa.yaml << ERIC
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: pressure-test
spec:
# 告诉k8s你要指定的缩放目标是谁
scaleTargetRef:
apiVersion: apps/v1
# 缩放目标是名为container-pressure-test的Deployment
kind: Deployment
name: container-pressure-test
# 至少1个pod
minReplicas: 1
# 最多不超过3个pod
maxReplicas: 3
# 根据监控指标执行动态扩缩容
metrics:
- type: Resource
resource:
name: cpu
# # 按利用率(百分比)
# target:
# type: Utilization
# averageUtilization: 50
# 按数值
target:
type: AverageValue
averageValue: 3m
ERIC
## 运行
kubectl apply -f pressure-test-hpa.yaml
说明
- 测试程序启动以后,它会执行一条CPU的压测命令,会给工作节点的CPU增加压力
- 之后启动HPA去监控这个工作负载,它会根据
metrics-server
返回的监控数据,自动调整测试程序的副本数