作者:SRE运维博客
博客地址:https://www.cnsre.cn/
文章地址:https://www.cnsre.cn/posts/241205123704/
相关话题:https://www.cnsre.cn/tags/k8s/
在现代云原生应用中,合理地分配和调整容器的资源是保障应用性能和成本效益的关键。Kubernetes 的 Vertical Pod Autoscaler(VPA)提供了根据实际资源使用情况自动调整 Pod 资源请求和限制的能力。然而,默认的 VPA 配置可能无法满足所有场景的需求,因此我们需要根据实际情况调整 VPA 的参数。
本文将通过实验,详细介绍如何安装配置以及调整 VPA 的参数,以及通过实验展示带来的效果。
基础配置及测试
部署VPA
先决条件
- 拥有现有 k8s 集群。
- 已安装 Kubernetes Metrics Server。有关更多信息,请参阅 使用 KubernetesMetrics Server 查看资源使用情况。
- 安装配置好
kubectl
客户端。 - 设备已安装 OpenSSL
1.1.1
或更高版本(如本地设备可以通过kubectl
控制k8s,即在本地安装即可,如在 master 控制集群则在master安装)。
部署 Vertical Pod Autoscaler
在此部分中,我们将部署 Vertical Pod Autoscaler 到集群。
部署 Vertical Pod Autoscaler
-
打开终端窗口,导航到我们要下载 Vertical Pod Autoscaler 源代码的目录。
-
克隆 kubernetes/autoscaler GitHub 存储库。
git clone https://github.com/kubernetes/autoscaler.git
-
切换到
vertical-pod-autoscaler
目录。cd autoscaler/vertical-pod-autoscaler/
-
(可选)如果我们已经部署另一个版本的 Vertical Pod Autoscaler,请使用以下命令将其删除。
./hack/vpa-down.sh
-
使用以下命令将 Vertical Pod Autoscaler 部署到我们的集群。
./hack/vpa-up.sh
-
验证已成功创建 Vertical Pod Autoscaler Pods。
kubectl get pods -n kube-system
示例输出如下。
NAME READY STATUS RESTARTS AGE [...] metrics-server-788b46889b-s6jst 1/1 Running 0 55m metrics-server-788b46889b-tz8m9 1/1 Running 0 55m vpa-admission-controller-6b6b54cbd6-wkgqw 1/1 Running 0 43m vpa-recommender-7cf697b548-xq9td 1/1 Running 0 43m vpa-updater-856fc8c478-kx747 1/1 Running 0 45m
测试 Vertical Pod Autoscaler 安装
在此部分中,我们部署示例应用程序以验证 Vertical Pod Autoscaler 在正常运行。
测试 Vertical Pod Autoscaler 安装
-
使用以下命令部署
hamster.yaml
Vertical Pod Autoscaler 示例。kubectl apply -f examples/hamster.yaml
-
从
hamster
示例应用程序获取 Pods。kubectl get pods -l app=hamster
示例输出如下。
hamster-789f8477df-d8bd8 1/1 Running 0 48s hamster-789f8477df-7swj6 1/1 Running 0 48s
-
描述其中一个 Pods 以查看其
cpu
和memory
预留。请将c7d89d6db-rglf5
替换为上一步输出中返回的 ID 之一。kubectl describe pod hamster-789f8477df-7swj6
示例输出如下。
[...] Containers: hamster: Container ID: docker://e76c2413fc720ac395c33b64588c82094fc8e5d590e373d5f818f3978f577e24 Image: registry.k8s.io/ubuntu-slim:0.1 Image ID: docker-pullable://registry.k8s.io/ubuntu-slim@sha256:b6f8c3885f5880a4f1a7cf717c07242eb4858fdd5a84b5ffe35b1cf680ea17b1 Port: <none> Host Port: <none> Command: /bin/sh Args: -c while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done State: Running Started: Thu, 05 Dec 2024 02:21:42 +0800 Ready: True Restart Count: 0 Requests: cpu: 100m memory: 50Mi [...]
我们可以看到原始 Pod 预留了 100 millicpu 和 50 MiB 内存。对于本示例应用程序,100 millicpu 小于 Pod 运行所需的数量,因此 CPU 受限。它预留的内存也远小于所需的数量。Vertical Pod Autoscaler
vpa-recommender
部署分析hamster
Pods,以查看 CPU 和内存需求是否合适。如果需要调整,vpa-updater
使用更新后的值重新启动 Pods。 -
等待
vpa-updater
启动新hamster
Pod。这大概需要一两分钟。我们可以使用以下命令监控 Pods。
注意
如果我们不确定已经启动了新 Pod,请将 Pod 名称与我们之前的列表比较。新 Pod 启动时,我们会看到新 Pod 名称。
```
kubectl get --watch Pods -l app=hamster
```
-
当新
hamster
Pod 启动时,描述它并查看更新后的 CPU 和内存预留。kubectl describe pod hamster-789f8477df-ldpxc
示例输出如下。
[...] Containers: hamster: Container ID: docker://2c3e7b6fb7ce0d8c86444334df654af6fb3fc88aad4c5d710eac3b1e7c58f7db Image: registry.k8s.io/ubuntu-slim:0.1 Image ID: docker-pullable://registry.k8s.io/ubuntu-slim@sha256:b6f8c3885f5880a4f1a7cf717c07242eb4858fdd5a84b5ffe35b1cf680ea17b1 Port: <none> Host Port: <none> Command: /bin/sh Args: -c while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done State: Running Started: Thu, 05 Dec 2024 02:21:42 +0800 Ready: True Restart Count: 0 Requests: cpu: 587m memory: 262144k [...]
在之前的输出中,我们可以看到
cpu
预留提升到了 587 个 millicpu,这是原始值的五倍多。memory
提高到了 262144 KB,即大约 250 MB,也就是原始值的五倍。此 Pod 资源不足,Vertical Pod Autoscaler 使用更为合适的值纠正了估计值。 -
描述
hamster-vpa
资源以查看新的建议。kubectl describe vpa/hamster-vpa
示例输出如下。
Name: hamster-vpa Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"autoscaling.k8s.io/v1beta2","kind":"VerticalPodAutoscaler","metadata":{"annotations":{},"name":"hamster-vpa","namespace":"d... API Version: autoscaling.k8s.io/v1beta2 Kind: VerticalPodAutoscaler Metadata: Creation Timestamp: 2024-12-04T02:22:51Z Generation: 23 Resource Version: 14411 Self Link: /apis/autoscaling.k8s.io/v1beta2/namespaces/default/verticalpodautoscalers/hamster-vpa UID: d0d85fb9-e153-11e9-ae53-0205785d75b0 Spec: Target Ref: API Version: apps/v1 Kind: Deployment Name: hamster Status: Conditions: Last Transition Time: 2024-12-04T02:23:28Z Status: True Type: RecommendationProvided Recommendation: Container Recommendations: Container Name: hamster Lower Bound: Cpu: 550m Memory: 262144k Target: Cpu: 587m Memory: 262144k Uncapped Target: Cpu: 587m Memory: 262144k Upper Bound: Cpu: 21147m Memory: 387863636 Events: <none>
-
在完成对示例应用程序的试验后,使用以下命令可将其删除。
kubectl delete -f examples/hamster.yaml
优化vpa配置
调整 VPA Updater 参数
背景问题分析
由于业务需求,某些 Pod 的副本数必须固定为单副本,这与 VPA 默认策略的假设(需要至少两个副本以避免更新时的服务中断)相冲突。使用 VPA 时,Updater 遇到了以下报错
pods_eviction_restriction.go:226] too few replicas for ReplicaSet cnsre/cnsrevpapod-555464bbc9. Found 1 live pods, needs 2 (global 2)
为解决此问题,需要对 Updater 和 Recommender 进行参数调整,以适应单副本 Pod 的场景,提升配置调整的灵活性和稳定性。
配置文件
|
|
参数解析
-
--min-replicas=1
:设置最小副本数为 1,确保当部署的副本数大于等于 1 时,VPA Updater 才会执行更新操作,防止在只有一个副本时频繁重启影响服务可用性。 -
--kube-api-qps=20
和--kube-api-burst=40
:提高与 Kubernetes API 交互的 QPS(每秒请求数)和突发请求数限制,确保在大规模集群或频繁更新情况下,VPA Updater 能够及时获取和更新资源信息。 -
--in-recommendation-bounds-eviction-lifetime-threshold=0s
:设置当 Pod 的资源请求在推荐范围内时,允许立即驱逐 Pod。默认情况下,VPA 会等待一定时间才会驱逐这些 Pod,以减少不必要的重启。将此参数设置为0s
,可以加速资源更新,但需要谨慎使用,避免因频繁重启影响服务稳定性。 -
-v=4
和--stderrthreshold=info
:设置日志级别为详细模式,方便调试和监控 VPA Updater 的行为。
效果与注意事项
通过上述参数调整,VPA Updater 将更积极地更新 Pod 的资源配置,尤其是在资源请求已经在推荐范围内但需要更新的情况下。需要注意的是,过于频繁的 Pod 重启可能会导致服务不稳定,因此应根据实际需求和应用特点进行权衡。
调整 VPA Recommender 参数
背景问题分析*
在创建 Vertical Pod Autoscaler (VPA) 的配置后,经常会遇到推荐参数更新不及时或不符合预期的问题。这些问题主要表现为以下情况:
1. 推荐参数延迟:VPA Recommender 无法及时计算和更新资源需求,导致 Pod 重建和调优速度滞后。
2. 推荐效果不理想:推荐的 CPU 或内存参数无法满足实际工作负载需求,影响应用性能或资源利用率。
为了解决这些问题,我们需要对 VPA Recommender 的默认参数进行调整,使其更加贴合业务需求,提高资源管理的及时性和准确性。
配置文件
|
|
参数解析
-
--recommender-interval=1m
:将推荐器的运行间隔设置为 1 分钟,意味着 VPA 每分钟计算一次新的资源推荐值。 -
--history-length=30m
:仅使用过去 30 分钟的历史数据进行推荐,使得推荐结果更加敏感,能及时反映近期的资源使用情况。 -
--oom-bump-up-ratio=1.5
:当发生 OOM(内存不足)时,将内存推荐值提高 1.5 倍,增加内存缓冲,防止再次发生 OOM。 -
--oom-min-bump-up-bytes=209715200
:当发生 OOM 时,最少增加 200MB 的内存,确保有足够的内存缓冲。 -
--recommendation-margin-fraction=0.25
:将资源推荐的安全边际提高到 25%,在推荐值上增加额外的缓冲,减少资源不足的风险。 -
--recommendation-lower-bound-cpu-percentile=0.1
和--recommendation-lower-bound-memory-percentile=0.1
:将 CPU 和内存的推荐下限百分位设置为 10%,过滤掉短期的低资源使用情况,防止推荐值过低。 -
--recommendation-upper-bound-cpu-percentile=0.95
和--recommendation-upper-bound-memory-percentile=0.95
:将 CPU 和内存的推荐上限百分位设置为 95%,限制推荐值的最大值,防止过度分配资源。 -
--kube-api-qps=20
和--kube-api-burst=40
:同样提高与 Kubernetes API 交互的请求限制,确保 Recommender 能够及时获取数据。 -
-v=4
:设置详细的日志级别,方便调试。
效果与注意事项
通过调整 Recommender 的参数,可以使资源推荐更加灵活和贴近实际使用情况。例如,缩短历史数据的参考范围,可以使推荐值更快地响应负载变化。然而,过短的历史数据可能导致推荐值波动过大,需要通过增加安全边际和调整百分位来平衡。
压测过程与结果分析
在调整 VPA 配置后,为验证优化效果,我们进行了详细的压测。以下是完整的测试过程,包括观察 VPA 推荐值的变化、Pod 状态的更新,以及通过负载工具模拟高负载场景。
压测准备
1. 检查 VPA 推荐值
通过以下命令实时观察 VPA 推荐值的更新情况:
|
|
输出结果:
NAME MODE CPU MEM PROVIDED AGE
cnsrevpapod-vpa Recreate 2315m 30751634503 True 45h
cnsrevpapod-vpa Recreate 2315m 30751634503 True 45h
观察到 VPA 内存推荐值从 30Gi 提升至 50Gi,说明推荐器对负载进行了及时响应。
2. 监控 Deployment 状态
在 VPA 更新生效期间,通过以下命令实时跟踪 Deployment 的状态变化:
|
|
输出结果:
NAME READY UP-TO-DATE AVAILABLE AGE
cnsrevpapod 1/1 1 1 23d
分析:
- Pod 在 VPA 更新生效时被重建(Recreate 模式),出现短暂的不可用状态。
- 更新完成后,Pod 恢复为 READY 1/1 状态,资源调整成功。
3. 安装压测工具
进入 Pod 内部并安装 stress 工具,用于生成高负载。
|
|
安装步骤:
-
下载 RPM 包:
1
curl -O https://dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/s/stress-1.0.4-24.el8.x86_64.rpm
-
安装 RPM 包:
1
rpm -ivh stress-1.0.4-24.el8.x86_64.rpm
-
验证安装:
1
stress --version
输出:
stress 1.0.4
压测执行
运行以下命令,在 Pod 内部生成高负载:
|
|
压测输出
kube exec -it cnsrevpapod-555464bbc9-6vjst -n cnsre /bin/bash
─╯
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.4# curl -O https://dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/s/stress-1.0.4-24.el8.x86_64.rpm
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 39864 100 39864 0 0 1441k 0 --:--:-- --:--:-- --:--:-- 1441k
bash-4.4# rpm -ivh stress-1.0.4-24.el8.x86_64.rpm
warning: stress-1.0.4-24.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 2f86d6a1: NOKEY
Verifying... ################################# [100%]
Preparing... ################################# [100%]
Updating / installing...
1:stress-1.0.4-24.el8 ################################# [100%]
bash-4.4# stress --version
stress 1.0.4
bash-4.4# stress --cpu 10 --vm 5 --vm-bytes 10G --vm-keep
stress: info: [11485] dispatching hogs: 10 cpu, 0 io, 5 vm, 0 hdd
command terminated with exit code 137
断开是因为pod 进行了重启
参数说明:
--cpu 10
:使用 10 个 CPU 核心生成计算负载。--vm 5
:启动 5 个虚拟内存工作线程。--vm-bytes 10G
:每个线程分配 10GB 内存。--vm-keep
:持续分配内存,防止释放后被回收。
压测观察与结果
1. Pod 内部状态
在压测过程中,Pod 的 CPU 和内存资源被占满,符合预期。可以通过以下命令验证资源使用情况:
输出示例:
|
|
pod 不存在是因为pod进行了重启
2. VPA 推荐值更新
压测运行一段时间后,VPA 推荐值会自动调整,提升资源分配以应对负载:
|
|
更新后的推荐值:
NAME MODE CPU MEM PROVIDED AGE
cnsrevpapod-vpa Recreate 2315m 30751634503 True 45h
cnsrevpapod-vpa Recreate 2315m 30751634503 True 45h
cnsrevpapod-vpa Recreate 9500m 50Gi True 45h
3. Deployment 状态变化
VPA 调整完成后,Deployment 更新状态稳定,Pod 正常运行:
|
|
观察新pod的配置参数
|
|
输出示例:
State: Running
Started: Thu, 05 Dec 2024 12:11:42 +0800
Ready: True
Restart Count: 0
Requests:
cpu: 2315m
memory: 50Gi
Environment:
压测结论
- VPA 能够动态调整单副本 Pod 的资源分配,及时响应高负载需求。
- 在压测过程中,VPA 推荐值更新迅速,资源分配上限(50Gi 内存和 9500m CPU)有效保障了服务的稳定性。
- Deployment 的短暂重建(Recreate 模式)可能会导致服务瞬时不可用。建议在关键场景中考虑切换至 Auto 模式,结合 PodDisruptionBudget 进行平滑更新。
- stress 工具成功验证了优化配置的效果,为业务提供了可靠的负载保障机制。
通过此次测试,我们验证了优化配置在生产环境中的实际效果,为后续性能调优和稳定性保障提供了重要依据。
总结
通过以上调整,我们对 VPA 的 Updater、Recommender 和 VPA 对象本身进行了自定义配置,以满足特定的资源管理需求。具体效果包括:
-
更快速的资源更新:缩短了 Recommender 的运行间隔,并允许 Updater 立即驱逐符合条件的 Pod。
-
更灵活的资源推荐:调整了历史数据参考范围和推荐值的百分位,使推荐结果更贴近实际使用情况。
-
资源分配的安全性:增加了资源推荐的安全边际,设置了资源请求和限制的上下限,防止过度分配或资源不足。
在实际应用中,建议根据应用的特性和负载模式,逐步调整 VPA 的参数,并在测试环境中验证效果,确保在满足性能要求的同时,优化资源的利用率和成本效益。
参考资料
希望本文能帮助您更好地理解和使用 Kubernetes VPA,以实现高效的资源管理和自动伸缩。
作者:SRE运维博客
博客地址:https://www.cnsre.cn/
文章地址:https://www.cnsre.cn/posts/241205123704/
相关话题:https://www.cnsre.cn/tags/k8s/