5w pod 压力测试复盘 #
1. 问题汇总 #
A类阻塞型问题 #
- ETCD 容量问题:默认 2G 容量远不足以支撑频繁触发的压力测试,导致
etcd: mvcc database space exceeded
错误。 - ETCD 容量超限清理策略:ETCD 容量超过限额,需要提供自动清理手段和策略。
- Kubelet Pod 数量超限:压力测试创建的 Pod 数量超过单台 Kubelet 默认配置。
- Watch 接口连接问题:压力测试客户端工具与磐基 Watch 接口在高压下频繁断联。
- List Pod 接口超时:paas平台的
List Pod
接口数据量过大,导致连接超时。
B类非阻塞型问题 #
- Deployment 数据丢失:前台丢失部分 Deployment 创建的数据,导致后台集群中的 Deployment 无法通过接口删除。
- Pod 数量超标:5W 级别压测最终 Pod 数量超过 5W,Running 状态符合 5W,但仍有部分 Pod 处于 Init 状态。
- EC-Watch 日志报错:
ec-watch
访问ec-resource-server 8080 failed to response
错误。
2. 问题分析与解决方案 #
ETCD 部分优化 #
调整 ETCD 容量至 8G:
--quota-backend-bytes=8589934592
配置自动压缩策略:
--auto-compaction-mode=periodic --auto-compaction-retention=30m
Kubelet 部分优化 #
限制单台 Kubelet 启动 Pod 数量:
--max-pods=250
优化 API Server 请求频率:
--kube-api-burst=400 --kube-api-qps=200
Kube-apiserver 部分优化 #
调整非 Mutating 请求的最大数量:
--max-requests-inflight=30000
调整默认 Watch 缓存大小:
--default-watch-cache-size=40000
调整 Mutating 请求的最大数量:
--max-mutating-requests-inflight=10000
F5 负载均衡优化 #
- 取消 F5 代理对运行
kube-apiserver
的 IP:端口的会话保持。
Linux 内核参数优化 #
- 参考另一个平面的内核参数列表进行调整。
3. 详细问题解决方案 #
问题 A4:Watch 接口频繁断联 #
- Watch 接口是长连接,服务器会持续推送数据。
- 在高并发情况下,数据量过大,TCP 连接缓冲区溢出,导致客户端断联。
- 解决方案:
- 业务研发团队优化压力测试客户端代码。
问题 A5:List Pod 接口超时 #
由于 Watch 断联,测试工具改用
List Pod
接口获取 Namespace 下所有 Pod。5W 级别压测导致
List Pod
请求数据量过大,默认 10s 超时,导致ec-app-server
无法返回。解决方案:
增加
ec-app-server
访问kube-apiserver
的超时时间。paas平台弹性计算研发调整参数,并发布新版本镜像(
ec-app-server
、ec-system-server
、ec-resource-server
)。修改 Nacos 配置:
fabric8: kubernetes-client: connection-timeout: 600000 # 连接超时时间 10 分钟 request-timeout: 120000 # 请求超时时间 2 分钟
4. B 类问题分析与优化 #
问题 B1:Deployment 数据丢失 #
- 可能原因:
- 测试环境频繁修改参数、重启组件。
- 高可用测试过程中出现异常。
- 解决方案:
- 规范重启操作,按照生产标准执行,避免异常情况。
- 观察一段时间后,如无复现,可关闭该问题。
问题 B2:Pod 数量超标 #
- 5W 级别压力测试发现 Pod 数量超过 5W,可能影响稳定性。
- 解决方案:
- 调整压测策略,先启动 3W Pod,再启动 2W Pod。
- 当前单中心常驻 Pod 约 2W,优化后的策略符合实际情况。
- 在调整策略后未复现问题,认为可关闭。
问题 B3:EC-Watch 访问失败 #
- 经弹性计算研发团队确认,该错误可以忽略。
5. 总结 #
通过上述优化,我们解决了 ETCD 容量不足、Kubelet Pod 数量超限、Watch 断联、List Pod 超时 等核心问题,同时优化了 Kube-apiserver、F5 代理、Linux 内核参数等方面,提升了系统的稳定性。
未来优化方向:
- 进一步优化 Watch 接口,减少单次推送数据量,提高稳定性。
- 增加 API Server 可用性,通过 HA 部署减少高并发情况下的瓶颈。
- 优化压力测试流程,保证测试环境与生产环境一致,减少不必要的变量影响。
本次 5w pod 压力测试复盘总结完毕。
这些参数主要用于优化 Kubernetes 控制平面的性能,特别是在高并发和大规模 Pod 启动场景下。下面是各参数的详细解释:
ETCD 部分优化 #
1. --quota-backend-bytes=8589934592
#
- 含义:设置 etcd 数据存储的最大容量(单位:字节)。默认值为 2GB(2147483648 字节),这里调整为 8GB。
- 原因:etcd 存储的 key-value 数据超过默认 2GB 时,会触发
mvcc database space exceeded
报错,导致集群无法正常运行。 - 优化作用:扩展 etcd 存储空间,防止 etcd 容量溢出。
2. --auto-compaction-mode=periodic
#
- 含义:启用 etcd 的自动压缩模式,减少历史版本数据占用的存储空间。
- 原因:etcd 默认不会自动清理历史版本数据,导致存储空间迅速增长。
- 优化作用:启用 定期压缩,减少 etcd 存储压力。
3. --auto-compaction-retention=30m
#
- 含义:设置 etcd 数据的保留时间,每 30 分钟 进行一次历史数据压缩。
- 原因:长期存储历史数据会影响 etcd 性能。
- 优化作用:定期清理无用数据,提高 etcd 读写性能。
Kubelet 部分优化 #
4. --max-pods=250
#
- 含义:限制 单台节点 能够调度的最大 Pod 数量,默认值通常是 110。
- 原因:压力测试期间,单台 Kubelet 可能调度超过其默认能力的 Pod 数,导致 kubelet 资源耗尽,影响调度能力。
- 优化作用:限制单节点 Pod 数量,避免超载,提高节点稳定性。
5. --kube-api-burst=400
#
- 含义:Kubelet 访问 API Server 时的 突发请求上限,默认值通常是 100。
- 原因:当 Kubelet 需要高频率访问 API Server 时,如果突发请求数过低,可能导致 Kubelet 请求被限流,进而影响 Pod 的创建和调度。
- 优化作用:提升 Kubelet 在高并发场景下的 API 请求处理能力,提高 Pod 启动速度。
6. --kube-api-qps=200
#
- 含义:Kubelet 访问 API Server 的 平均每秒请求数,默认值通常是 50。
- 原因:默认值在大规模 Pod 创建时可能限制 kubelet 的 API 交互能力,影响调度效率。
- 优化作用:提升 kubelet 向 API Server 发送请求的吞吐量,加快 Pod 创建速度。
Kube-apiserver 部分优化 #
7. --max-requests-inflight=30000
#
- 含义:限制 API Server 在 同一时间 处理的 非 mutating(非变更) 请求(如
GET
请求)。 - 原因:API Server 默认限制该参数为 10000,当 List Pod 请求数据量过大时,可能因
超时
导致 Watch 断联。 - 优化作用:提高 API Server 处理非变更请求的能力,避免压力测试期间
List Pod
超时问题。
8. --default-watch-cache-size=40000
#
- 含义:配置 API Server 默认的 Watch 缓存大小,默认值通常是 10000。
- 原因:在大规模 Pod 变更时,watch 事件量会迅速增加,缓存大小不足会导致 watch 断流。
- 优化作用:提高 Watch 缓存大小,降低 Watch 断流风险,提高 API Server 事件响应能力。
9. --max-mutating-requests-inflight=10000
#
- 含义:限制 API Server 在 同一时间 处理的 mutating(变更) 请求(如
POST
、PUT
、DELETE
)。 - 原因:压力测试期间 Pod 创建请求量巨大,API Server 可能因 变更请求超载 而变慢,影响 Pod 启动。
- 优化作用:提高 API Server 处理变更请求的能力,确保 Pod 能够稳定创建。
总结 #
参数 | 作用 | 默认值 | 调整值 | 影响 |
---|---|---|---|---|
--quota-backend-bytes | etcd 存储容量 | 2G | 8G | 防止 etcd 存储超限 |
--auto-compaction-mode | etcd 自动压缩 | none | periodic | 定期清理历史数据 |
--auto-compaction-retention | etcd 数据保留时间 | 永久 | 30m | 减少存储压力 |
--max-pods | 限制单节点 Pod 数量 | 110 | 250 | 避免 kubelet 资源超载 |
--kube-api-burst | Kubelet API 突发请求 | 100 | 400 | 提高 kubelet 高峰期 API 请求能力 |
--kube-api-qps | Kubelet API 平均请求 | 50 | 200 | 提高 kubelet API 请求吞吐量 |
--max-requests-inflight | API Server 非变更请求上限 | 10000 | 30000 | 解决 List Pod 超时问题 |
--default-watch-cache-size | Watch 缓存大小 | 10000 | 40000 | 解决 Watch 断流问题 |
--max-mutating-requests-inflight | API Server 变更请求上限 | 5000 | 10000 | 解决 Pod 创建变慢问题 |
通过优化这些参数,可以 提高 Kubernetes 在大规模压力测试下的稳定性和响应能力,避免 etcd 超限
、API Server 过载
、Watch 断流
、Pod 创建超时
等问题。
这里是对关键优化参数的详细解释:
ETCD 调优 #
ETCD 作为 Kubernetes 的核心存储组件,在高并发场景下容易成为瓶颈,因此需要优化其存储和请求处理能力。
调整 ETCD 空间至 8GB
--quota-backend-bytes=8589934592
解释:
- ETCD 默认最大存储为 2GB,超过 2GB 后可能会导致性能下降甚至不可用。
8589934592
(8GB)扩展了存储容量,减少etcd
触发自动碎片整理的频率,提高存储性能。
配置 ETCD 自动压缩
--auto-compaction-mode=periodic --auto-compaction-retention=30m
解释:
--auto-compaction-mode=periodic
:定期进行数据压缩,防止 ETCD 体积无限增长。--auto-compaction-retention=30m
:保留最近 30 分钟的数据快照,释放旧版本数据占用的磁盘空间。
最大请求大小
--max-request-bytes=15728640
解释:
- 限制单个请求的最大大小,默认值可能过小,增加到
15MB
以适应大规模的 API 调用。
- 限制单个请求的最大大小,默认值可能过小,增加到
Kube-apiserver 调优 #
Kube-apiserver 作为 Kubernetes 控制平面的核心组件,优化其请求并发数、缓存大小等参数可以减少瓶颈,提高集群响应速度。
调整 API Server 处理的最大请求数
--max-requests-inflight=30000
解释:
- 该参数限制了非 Mutating(非变更)请求的最大数量,防止 API Server 过载。
调整 Watch 缓存大小
--default-watch-cache-size=40000
解释:
watch
机制是 Kubernetes 监控资源变化的核心方式,增大watch
缓存可以提升 API Server 的效率,减少list
操作的开销。
调整 Mutating 请求的最大数量
--max-mutating-requests-inflight=10000
解释:
mutating
请求指的是可能会改变集群状态的 API 请求,例如创建、更新、删除 Pod。- 增大该值可以提升 API Server 在高负载下的处理能力。
Kubelet 调优 #
Kubelet 负责与 API Server 通信,并在节点上管理 Pod,因此优化 Kubelet 可以提升整个集群的调度能力。
限制单台 Kubelet 启动的 Pod 数量
--max-pods=500
解释:
- Kubelet 默认
--max-pods=110
,对于 181 台计算节点的集群来说,默认值过小,调大至500
以适应大规模 Pod 部署需求。
- Kubelet 默认
优化 Kubelet 与 API Server 交互
--kube-api-burst=600 --kube-api-qps=300
解释:
--kube-api-burst=600
:表示在短时间内,最多可以向 API Server 发送 600 个请求,提高短时请求的吞吐量。--kube-api-qps=300
:Kubelet 每秒最多向 API Server 发送 300 个请求,增加 API Server 处理能力。
Controller-manager 调优 #
Kube-controller-manager 负责集群中的控制循环(Controller),优化其 API Server 交互能力可以提高调度效率。
优化 API Server 交互
--kube-api-burst=600 --kube-api-qps=200
解释:
--kube-api-burst=600
:短时间内的最大 API Server 请求数,防止控制器请求 API Server 过载。--kube-api-qps=200
:控制器每秒最多发出的请求数量。
Scheduler 调优 #
Kubernetes Scheduler 负责为新建 Pod 分配合适的 Node,在高并发环境下需要优化其调度性能。
优化调度器的 API Server 交互
--kube-api-burst=600 --kube-api-qps=200
解释:
--kube-api-burst=600
:提高 Scheduler 在短时间内请求 API Server 的能力,加快调度速度。--kube-api-qps=200
:提高 Scheduler 的 API 请求吞吐量,减少调度阻塞。
主机参数调优 #
服务器层面的优化可以提升 Kubernetes 在物理硬件上的运行效率。
1. 负载均衡(F5)优化 #
VIP 取消会话保持
解释:
- 取消 Master VIP 的会话保持,防止 API Server 负载均衡出现倾斜。
2. 调整系统内核参数 #
kernel.threads-max = 800000
kernel.pid_max = 1000000
kernel.shmall = 4294967296
解释:
kernel.threads-max=800000
:增加最大线程数,避免高并发下线程耗尽。kernel.pid_max=1000000
:增加最大进程数,提高服务器并发能力。kernel.shmall=4294967296
:调整共享内存大小,提高内存使用效率。
总结 #
- ETCD 调优:增大存储容量,启用自动压缩,增加请求大小限制。
- API Server 调优:增大缓存,优化请求处理能力。
- Kubelet 调优:提高最大 Pod 处理能力,提高 API Server 交互性能。
- Controller-manager & Scheduler 调优:优化 API Server 交互能力,加快 Pod 调度。
- 主机参数优化:提升线程、进程、内存等系统资源的上限。
这些优化措施可以有效提升 Kubernetes 集群的并发处理能力,使其能够在短时间内稳定地启动 5 万个 Pod。
压测调优总结 #
1. 压测背景 #
项目进行生产环境压测,目标是在10分钟内启动5万个POD,涉及400个Deployment,其中200个启动249个POD,另外200个启动单个POD,压测时并发启动约20个Deployment。
2. 压测调优 #
2.1. paas平台调优 #
- 中间件扩容:istio-ingressgateway扩容至5副本,apisix扩容至4副本。
- 统一门户扩容:portal-auth扩容至2副本。
- 弹性计算调整:
- 副本数调整:ec-openapi-proxy-server扩容至2副本,ec-app-server扩容至4副本等。
- 调大超时时间:调整nacos中的相关配置以增加应用容忍时间。
- 应用内存调大:将ec-app-server的启动内存调整至16GB。
2.2. K8S集群调优 #
- ETCD调整:增加ETCD空间至8GB,启用定期压缩及监控。
- Kube-apiserver调优:调整请求限制与缓存配置,提高并发能力。
- Kubelet、Controller-manager、Scheduler调优:增加与api-server交互时的并发限制和QPS配置,优化POD的管理。
2.3. 主机参数调优 #
- 硬负载F5调整:取消会话保持以优化流量分配。
- 系统参数调整:修改内核参数,如线程数、PID最大值等,优化资源使用。
3. 压测问题 #
3.1. ETCD容量不足 #
- 增加ETCD数据容量至8GB,启用定期数据压缩,并增加监控和告警,确保ETCD健康。
3.2. POD数量超出单台kubelet默认配置 #
- 调整Kubelet的最大POD数配置,确保5万个POD在压测中正常启动。
3.3. Deployment期望POD数量与实际不一致 #
- 发现因metrics-server在压力下无法提供正确的资源使用数据,导致部分POD处于init状态。通过扩容metrics-server解决了此问题。
- 进一步分析发现硬件规格差异影响RC调度器性能,通过调整kube-controller-manager和kube-scheduler的参数(kube-api-burst、kube-api-qps)解决了一个平面的问题,确保POD数量准确。
3.4. 客户端工具与磐基watch接口频繁断开 #
- 由于压力测试期间POD创建量大,导致watch接口的数据量超过TCP连接缓冲区,引发断联。客户端代码优化后解决了此问题。
3.5. List pod接口数据量过大导致超时 #
- 由于POD创建量过大,list-pod接口请求超时。通过调整ec-app-server的超时配置,延长了请求时间,避免超时导致的错误。
3.6. 平台接口查询数据不一致 #
- 由于环境频繁修改参数及重启组件,导致部分数据丢失。通过与测试团队讨论,确保重启操作规范化,避免复现问题。
总结 #
本次压测调优主要集中在系统资源配置、Kubernetes集群调优、应用层优化以及压力测试工具的调整。通过扩容、调整超时、优化系统参数等手段,解决了多个性能瓶颈,确保在高负载下系统能够稳定运行并满足压测目标。同时,也优化了客户端工具的稳定性,提高了集群的整体效率。