当前位置: 首页 > news >正文

从零开始的云原生之旅(十一):压测实战:验证弹性伸缩效果

从零开始的云原生之旅(十一):压测实战:验证弹性伸缩效果

用 k6 进行专业压测,看着 HPA 在真实负载下自动扩缩容,这才是云原生的魅力!

📖 文章目录

  • 前言
  • 一、为什么要做压测?
    • 1.1 手动测试的局限
    • 1.2 专业压测的价值
    • 1.3 压测的目标
  • 二、选择压测工具:k6
    • 2.1 为什么选择 k6?
    • 2.2 k6 安装
    • 2.3 k6 核心概念
  • 三、编写 k6 压测脚本
    • 3.1 脚本结构
    • 3.2 配置测试阶段
    • 3.3 实现测试场景
    • 3.4 完整脚本
  • 四、优化配置准备压测
    • 4.1 我踩的坑:256Mi 内存不够
    • 4.2 优化资源配置
    • 4.3 优化探针配置
    • 4.4 为什么这样优化?
  • 五、执行压测
    • 5.1 准备监控窗口
    • 5.2 启动压测
    • 5.3 实时观察
  • 六、压测结果分析
    • 6.1 k6 指标解读
    • 6.2 性能评估
    • 6.3 HPA 效果分析
    • 6.4 与行业标准对比
  • 七、问题诊断与优化
    • 7.1 CrashLoopBackOff 问题
    • 7.2 内存占用分析
    • 7.3 优化历程
  • 八、最佳实践总结
    • 8.1 资源配置建议
    • 8.2 探针配置建议
    • 8.3 HPA 配置建议
    • 8.4 压测策略建议
  • 九、v0.3 完整总结
    • 9.1 学习成果
    • 9.2 核心配置
    • 9.3 性能指标
  • 结语

前言

在完成 HPA 配置后,我手动发送了一些请求,看到了 Pod 自动扩缩容。但我知道,这还不够

  • 手动测试无法模拟真实负载
  • 无法持续观察长时间的扩缩容行为
  • 缺少性能指标数据

所以,我需要进行专业的压力测试

这篇文章记录我:

  • ✅ 使用 k6 编写压测脚本
  • ✅ 执行长达 9.5 分钟的负载测试
  • ✅ 观察 HPA 在真实负载下的表现
  • ✅ 分析性能指标和优化配置
  • 详细记录踩过的坑和解决方案

压测结果

  • 100% 请求成功率
  • P95 响应时间 983ms
  • 零失败请求
  • HPA 成功扩缩容

一、为什么要做压测?

1.1 手动测试的局限

之前我是这样测试的:

# 手动发送几个请求
for i in {1..10}; docurl "$SERVICE_URL/api/v1/workload/cpu?iterations=20000000"
done

问题

  • ❌ 只能测试短时间的行为
  • ❌ 无法模拟真实的并发场景
  • ❌ 缺少性能指标(P50、P95、P99)
  • ❌ 无法持续观察扩缩容过程
  • ❌ 没有成功率、错误率等关键指标

1.2 专业压测的价值

使用 k6 等专业工具后:

✅ 模拟真实负载:30 并发用户,持续 9.5 分钟
✅ 自动收集指标:响应时间、成功率、吞吐量
✅ 完整的测试周期:预热 → 增压 → 高负载 → 降压 → 冷却
✅ 观察完整的扩缩容过程
✅ 发现潜在问题(OOM、探针超时等)
✅ 验证系统稳定性

1.3 压测的目标

我的压测目标:

  1. 验证 HPA 是否正常工作

    • CPU/内存超过阈值时自动扩容
    • 负载降低时自动缩容
    • 扩缩容过程平滑
  2. 验证系统稳定性

    • 高负载下 Pod 不崩溃
    • 探针不误杀 Pod
    • 无 OOMKilled 事件
  3. 收集性能基线

    • 响应时间分布(P50、P95、P99)
    • 吞吐量(RPS)
    • 错误率
  4. 发现潜在问题

    • 资源配置是否合理
    • 探针配置是否需要优化
    • HPA 策略是否需要调整

二、选择压测工具:k6

2.1 为什么选择 k6?

对比常见的压测工具:

工具优点缺点适合场景
k6现代化、易用、详细的指标报告相对较新✅ 我的选择
JMeter功能强大、图形界面笨重、资源消耗大传统企业
ab简单、内置功能简陋快速测试
wrk高性能缺少图形界面极限测试
LocustPython 编写、分布式需要写 Python复杂场景

k6 的优势

  • ✅ 使用 JavaScript 编写(前端开发者友好)
  • ✅ 丰富的内置指标(P50、P95、P99)
  • ✅ 支持复杂的测试场景
  • ✅ 美观的终端输出
  • ✅ 支持自定义指标
  • ✅ 开源且活跃

2.2 k6 安装

Windows (Chocolatey)

choco install k6

macOS (Homebrew)

brew install k6

Linux (Debian/Ubuntu)

sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6

验证安装

k6 version
# k6 v0.48.0

2.3 k6 核心概念

VU (Virtual User): 虚拟用户

1 个 VU = 1 个并发用户
30 VU = 30 个并发用户同时发送请求

迭代 (Iteration): 一次完整的测试场景执行

1 次迭代 = 执行一次 default 函数
包括:发送请求 + 检查响应 + sleep

阶段 (Stage): 测试的不同阶段

Stage 1: 预热(VU 从 0 增加到 5)
Stage 2: 增压(VU 从 5 增加到 30)
Stage 3: 高负载(VU 保持 30)
Stage 4: 降压(VU 从 30 降到 5)

指标 (Metrics): 性能数据

- http_req_duration: HTTP 请求耗时
- http_req_failed: 请求失败率
- http_reqs: 总请求数
- checks: 检查通过率

三、编写 k6 压测脚本

3.1 脚本结构

// 1. 导入模块
import http from 'k6/http';
import { check, sleep } from 'k6';// 2. 配置
export let options = {stages: [...],      // 测试阶段thresholds: {...},  // 性能阈值
};// 3. 测试场景(每个 VU 重复执行)
export default function () {// 发送请求// 检查响应// 等待(模拟用户思考时间)
}// 4. 生命周期钩子
export function setup() {// 测试前执行一次
}export function teardown() {// 测试后执行一次
}

3.2 配置测试阶段

我的测试计划(总时长 9.5 分钟)

export let options = {stages: [// 阶段 1: 预热(30 秒){ duration: '30s', target: 3 },// 阶段 2: 缓慢增压(1 分钟){ duration: '1m', target: 10 },// 阶段 3: 激增负载(2 分钟)- 触发 HPA 扩容{ duration: '2m', target: 30 },// 阶段 4: 保持高负载(3 分钟)- 观察扩容效果{ duration: '3m', target: 30 },// 阶段 5: 缓慢降压(2 分钟){ duration: '2m', target: 10 },// 阶段 6: 完全冷却(1 分钟)- 观察缩容{ duration: '1m', target: 3 },],// 性能阈值thresholds: {'http_req_duration': ['p(95)<5000'],  // 95% 请求在 5 秒内'http_req_failed': ['rate<0.2'],      // 错误率低于 20%},
};

阶段设计思路

VUs30 |          ▄▄▄▄▄▄▄▄▄▄▄▄▄▄     ← 阶段 3-4: 高负载,HPA 扩容|        ▄▄                ▄▄10 |      ▄▄                    ▄▄   ← 阶段 2,5: 中负载|    ▄▄                        ▄▄3 |▄▄▄▄                            ▄▄ ← 阶段 1,6: 预热/冷却0 |_____________________________________0   1   2   3   4   5   6   7   8   9  分钟

3.3 实现测试场景

场景:50% CPU 负载 + 50% 内存负载

export default function () {// 随机选择负载类型const testType = Math.random();if (testType < 0.5) {// 50% - CPU 密集型负载testCPUWorkload();} else {// 50% - 内存密集型负载testMemoryWorkload();}// 随机等待 2-4 秒(模拟用户思考时间)sleep(Math.random() * 2 + 2);
}// CPU 密集型测试
function testCPUWorkload() {const intensity = Math.floor(Math.random() * 10) + 10;  // 10-20 百万次const url = `${BASE_URL}/api/v1/workload/cpu?iterations=${intensity * 1000000}`;const res = http.get(url, { timeout: '30s' });check(res, {'CPU test: status is 200': (r) => r.status === 200,'CPU test: has body': (r) => r.body && r.body.length > 0,});
}// 内存密集型测试
function testMemoryWorkload() {const sizeMB = Math.floor(Math.random() * 20) + 20;  // 20-40 MBconst duration = Math.floor(Math.random() * 1) + 1;  // 1-2 秒const url = `${BASE_URL}/api/v1/workload/memory?size=${sizeMB}&duration=${duration}`;const res = http.get(url, { timeout: '30s' });check(res, {'Memory test: status is 200': (r) => r.status === 200,'Memory test: has body': (r) => r.body && r.body.length > 0,});
}

3.4 完整脚本

完整脚本见 k6-tests/hpa-test.js(已在项目中创建)。

核心特性

  • ✅ 混合负载(CPU + 内存)
  • ✅ 随机参数(模拟真实场景)
  • ✅ 超时处理(30 秒)
  • ✅ 错误处理(JSON parse)
  • ✅ 自定义指标(cpu_requests、memory_requests)
  • ✅ 生命周期钩子(健康检查、总结)

四、优化配置准备压测

4.1 我踩的坑:256Mi 内存不够

第一次压测,所有 Pod 都崩溃了!

$ kubectl get pods
NAME                             READY   STATUS             RESTARTS
cloudnative-api-xxx              0/1     CrashLoopBackOff   4
cloudnative-api-yyy              0/1     CrashLoopBackOff   4
cloudnative-api-zzz              0/1     CrashLoopBackOff   4

查看事件

$ kubectl describe pod cloudnative-api-xxx
Events:Warning  BackOff  restarting failed container api

查看 HPA

$ kubectl get hpa
NAME                   TARGETS           REPLICAS
cloudnative-api-hpa    <unknown>/70%     3

问题分析

  1. k6 发送 30 并发请求
  2. 50% 是内存请求,每个分配 20-40MB
  3. 30 × 50% × 30MB = 450MB
  4. 加上 Go 运行时开销 ≈ 550MB
  5. limits: 256Mi → 严重不足 → OOMKilled!

4.2 优化资源配置

调整前

resources:requests:memory: "128Mi"cpu: "100m"limits:memory: "256Mi"  # ← 不够!cpu: "300m"

调整后

resources:requests:memory: "128Mi"  # 保持不变(HPA 基准)cpu: "100m"limits:memory: "512Mi"  # ← 翻倍!cpu: "500m"      # ← 提高到 5 倍

为什么这样调整?

配置原值新值原因
memory limits256Mi512Mi防止高负载时 OOM
cpu limits300m500m更大的突发空间
memory requests128Mi128Mi保持不变(HPA 基准)
cpu requests100m100m保持不变(HPA 基准)

关键点

  • requests 不变 → HPA 触发敏感度不变
  • limits 提高 → 支持更高的突发负载

4.3 优化探针配置

第二个坑:高负载下探针超时,Pod 被误杀

Events:Warning  Unhealthy  Readiness probe failed: Get "http://10.244.0.66:8080/ready": dial tcp: connect: connection refusedWarning  BackOff    Back-off restarting failed container

问题分析

应用处理 30 个并发请求 → CPU 100%
↓
就绪探针 3 秒超时
↓
应用忙于处理请求,无法响应探针
↓
连续失败 3 次 → Kubernetes 认为 Pod 不健康
↓
重启 Pod → 正在处理的请求丢失
↓
恶性循环:CrashLoopBackOff

优化方案

# 存活探针(避免误杀)
livenessProbe:httpGet:path: /healthport: 8080initialDelaySeconds: 15      # 增加初始延迟periodSeconds: 15            # 降低检查频率timeoutSeconds: 10           # ⭐ 增加超时时间failureThreshold: 5          # ⭐ 允许更多失败# 就绪探针(适应高负载)
readinessProbe:httpGet:path: /readyport: 8080initialDelaySeconds: 5periodSeconds: 10            # 降低检查频率timeoutSeconds: 10           # ⭐ 增加超时时间failureThreshold: 6          # ⭐ 允许更多失败

4.4 为什么这样优化?

对比表

探针参数优化前优化后效果
ReadinesstimeoutSeconds3s10s给应用 7 秒额外时间
failureThreshold36允许失败 60 秒
periodSeconds5s10s降低检查频率
LivenesstimeoutSeconds5s10s避免误杀
failureThreshold35允许失败 75 秒

效果

  • ✅ Pod 不会因为短暂的高负载被误杀
  • ✅ 压测期间 Pod 稳定运行
  • 0 次重启

五、执行压测

5.1 准备监控窗口

强烈建议打开 4 个监控窗口

终端 1 - Minikube Service 隧道(Windows PowerShell):

minikube service cloudnative-api-service --url
# 输出: http://127.0.0.1:53163
# 保持运行,不要关闭

终端 2 - HPA 监控

kubectl get hpa cloudnative-api-hpa -w

终端 3 - Pod 监控

kubectl get pods -l app=cloudnative-api -w

终端 4 - 资源监控(PowerShell):

while ($true) {Clear-HostWrite-Host "=== $(Get-Date -Format 'HH:mm:ss') ===" -ForegroundColor Cyankubectl top pods -l app=cloudnative-api 2>$nullkubectl get hpa cloudnative-api-hpa --no-headers 2>$nullStart-Sleep -Seconds 5
}

5.2 启动压测

在新的终端执行

# 进入项目目录
cd cloudnative-go-journey-plan# 运行压测
k6 run k6-tests/hpa-test.js

输出示例

         /\      Grafana   /‾‾/  /\  /  \     |\  __   /  /   /  \/    \    | |/ /  /   ‾‾\ /          \   |   (  |  (‾)  |/ __________ \  |_|\_\  \_____/ execution: localscript: k6-tests/hpa-test.jsoutput: -scenarios: (100.00%) 1 scenario, 30 max VUs, 10m0s max duration* default: Up to 30 looping VUs for 9m30s over 6 stagesINFO[0000] 🚀 Starting HPA Load Test (Light Version)...
INFO[0000] 📍 Target: http://127.0.0.1:53163
INFO[0000] ✅ Health check passed
INFO[0000] ⏰ Test duration: ~9.5 minutes
INFO[0000] 💡 This is a LIGHT version with reduced load

5.3 实时观察

观察终端 2 - HPA 变化

TIME    TARGETS         REPLICAS
00:00   5%/70%, 15%/80%    2        ← 初始状态
01:00   25%/70%, 30%/80%   2        ← 负载上升(预热)
02:00   55%/70%, 50%/80%   2        ← 接近阈值
03:00   85%/70%, 65%/80%   4        ← ⭐ 扩容:CPU 超标
04:00   75%/70%, 60%/80%   4        ← 负载分散
05:00   65%/70%, 55%/80%   4        ← 趋于稳定
06:00   45%/70%, 40%/80%   4        ← 负载下降(降压)
07:00   20%/70%, 25%/80%   4        ← 等待稳定窗口
...     (5 分钟稳定窗口)
12:00   15%/70%, 20%/80%   3        ← ⭐ 缩容:4 → 3
13:00   10%/70%, 18%/80%   2        ← ⭐ 缩容:3 → 2

观察终端 3 - Pod 变化

TIME    NAME                               STATUS
03:00   cloudnative-api-xxx-aaa            Running  ← 原有
03:00   cloudnative-api-xxx-bbb            Running  ← 原有
03:01   cloudnative-api-xxx-ccc            Pending  ← ⭐ 新建
03:01   cloudnative-api-xxx-ddd            Pending  ← ⭐ 新建
03:02   cloudnative-api-xxx-ccc            Running  ← 就绪
03:02   cloudnative-api-xxx-ddd            Running  ← 就绪
...
12:00   cloudnative-api-xxx-ddd            Terminating  ← ⭐ 缩容
13:00   cloudnative-api-xxx-ccc            Terminating  ← ⭐ 缩容

观察终端 4 - 资源使用

=== 02:00:00 ===
NAME                               CPU(cores)   MEMORY(bytes)
cloudnative-api-xxx-aaa            120m         145Mi
cloudnative-api-xxx-bbb            115m         140Mi=== 03:00:00 ===  ← 高负载
cloudnative-api-xxx-aaa            185m         180Mi
cloudnative-api-xxx-bbb            180m         175Mi=== 04:00:00 ===  ← 扩容后
cloudnative-api-xxx-aaa            95m          120Mi
cloudnative-api-xxx-bbb            92m          118Mi
cloudnative-api-xxx-ccc            88m          115Mi
cloudnative-api-xxx-ddd            90m          120Mi

六、压测结果分析

6.1 k6 指标解读

测试完成后,k6 输出完整报告

 █ THRESHOLDShttp_req_duration✓ 'p(95)<5000' p(95)=983.18ms        ← ⭐ 优秀!http_req_failed✓ 'rate<0.2' rate=0.00%              ← ⭐ 完美!█ TOTAL RESULTSchecks_total.......: 6370    11.147425/schecks_succeeded...: 100.00% 6370 out of 6370  ← ⭐ 100% 通过checks_failed......: 0.00%   0 out of 6370✓ CPU test: status is 200✓ CPU test: has body✓ Memory test: status is 200✓ Memory test: has bodyCUSTOMcpu_duration...................: avg=15.434094  min=0.6725   med=14.8267   max=86.8117   p(90)=32.08456  p(95)=36.51136cpu_requests...................: 1619   2.833231/smemory_duration................: avg=961.947939 min=933.8644 med=960.23395 max=1107.1016 p(90)=983.36405 p(95)=992.5427memory_requests................: 1566   2.740482/sHTTPhttp_req_duration..............: avg=480.66ms   min=672.5µs  med=48.86ms   max=1.1s      p(90)=974.02ms  p(95)=983.18ms{ expected_response:true }...: avg=480.66ms   min=672.5µs  med=48.86ms   max=1.1s      p(90)=974.02ms  p(95)=983.18mshttp_req_failed................: 0.00%  0 out of 3186    ← ⭐ 零失败http_reqs......................: 3186   5.575462/sEXECUTIONiteration_duration.............: avg=3.47s      min=2.01s    med=3.46s     max=4.98s     p(90)=4.55s     p(95)=4.77siterations.....................: 3185   5.573712/svus............................: 1      min=1         max=30vus_max........................: 30     min=30        max=30NETWORKdata_received..................: 922 kB 1.6 kB/sdata_sent......................: 354 kB 619 B/srunning (09m31.4s), 00/30 VUs, 3185 complete and 0 interrupted iterations
default ✓ [======================================] 00/30 VUs  9m30s

6.2 性能评估

关键指标评分

指标结果行业标准评分
P95 响应时间983ms< 2000ms⭐⭐⭐⭐⭐ 优秀
P50 响应时间48.86ms< 500ms⭐⭐⭐⭐⭐ 优秀
请求成功率100%> 99%⭐⭐⭐⭐⭐ 完美
请求失败率0%< 1%⭐⭐⭐⭐⭐ 完美
检查通过率100%> 95%⭐⭐⭐⭐⭐ 完美

响应时间分析

HTTP 请求耗时分布:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
最小值:    672.5µs  ← CPU 请求(极快!)
P50:       48.86ms  ← 50% 的请求都很快
平均值:    480.66ms ← 被内存请求拉高
P90:       974.02ms
P95:       983.18ms ← 95% 在 1 秒内
最大值:    1.1s     ← 内存请求(可接受)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

关键发现

  • ✅ 中位数只有 48.86ms → 大部分请求非常快
  • ✅ 平均值 480ms vs 中位数 48ms → 少数内存请求拉高平均值(正常)
  • ✅ P95 = 983ms < 1s → 95% 的请求在 1 秒内完成

CPU vs 内存请求对比

类型请求数平均耗时P95 耗时说明
CPU161915.43ms36.51ms非常快 ✅
内存1566961.95ms992.54ms符合预期(1-2秒持有)✅

6.3 HPA 效果分析

扩容表现

T+0:00   负载开始上升
T+2:30   CPU 达到 85%/70%(超过阈值)
T+2:45   HPA 触发扩容:2 → 4
T+3:00   新 Pod 创建完成
T+3:15   新 Pod 接管流量
T+3:30   CPU 降至 65%/70%(低于阈值)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
扩容延迟: ~45 秒(优秀)

缩容表现

T+6:00   负载下降,CPU 降至 45%/70%
T+6:00   进入稳定窗口(300 秒)
T+11:00  稳定窗口结束,开始缩容:4 → 3
T+12:00  继续缩容:3 → 2
T+12:30  回到 minReplicas
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
缩容延迟: ~6 分钟(符合设计)

HPA 评分

维度评分说明
扩容速度⭐⭐⭐⭐⭐45 秒完成,响应及时
扩容准确性⭐⭐⭐⭐⭐从 2 扩到 4,符合计算公式
缩容平滑性⭐⭐⭐⭐⭐5 分钟稳定窗口,避免抖动
指标准确性⭐⭐⭐⭐⭐TARGETS 实时显示,无 unknown
整体稳定性⭐⭐⭐⭐⭐0 次 Pod 重启,0 次 OOM

6.4 与行业标准对比

指标行业标准我的集群评价
可用性99.9% (SLA)100%✅ 超越
P95 响应时间< 2s983ms✅ 优秀
P99 响应时间< 5s~1.1s✅ 优秀
错误率< 1%0%✅ 完美
HPA 响应速度< 60s45s✅ 优秀
资源利用率60-80%65%✅ 理想

结论达到生产级别的性能标准!


七、问题诊断与优化

7.1 CrashLoopBackOff 问题

完整的问题诊断过程

Step 1: 发现问题

$ kubectl get pods
NAME                             STATUS             RESTARTS
cloudnative-api-d99d4f9c-hj9x5   CrashLoopBackOff   4 (49s ago)

Step 2: 查看事件

$ kubectl describe pod cloudnative-api-d99d4f9c-hj9x5 | grep -A 20 Events
Events:Warning  Unhealthy  Readiness probe failed: connection refusedWarning  BackOff    Back-off restarting failed container api

Step 3: 查看日志

$ kubectl logs cloudnative-api-d99d4f9c-hj9x5 --previous
2025/11/02 08:24:26 ✅ Redis connected successfully
2025/11/02 08:24:26 🚀 Server starting on port 8080...
2025/11/02 08:24:33 [GET] /api/v1/workload/cpu | Status: 200
...

关键发现

  • ✅ 应用启动成功
  • ✅ 正常处理请求
  • ❌ 但被探针误杀了

Step 4: 分析原因

应用处理大量请求 → CPU 100%
↓
就绪探针 3 秒超时 → 无法响应
↓
连续失败 3 次(15 秒)→ 被标记为 Unhealthy
↓
Kubernetes 重启 Pod

Step 5: 解决方案

调整探针配置(见 4.3)。

7.2 内存占用分析

问题:为什么 CPU 负载也会导致内存占用高?

原因分析

k6 测试脚本的设计:

export default function () {const testType = Math.random();if (testType < 0.5) {testCPUWorkload();      // 50% CPU 请求} else {testMemoryWorkload();   // 50% 内存请求 ← 这个分配内存!}
}

内存占用计算

30 并发用户
× 50% 内存请求
× 平均 30MB 分配
= 450MB加上:
+ Go 运行时: ~50MB
+ HTTP 缓冲区: ~30MB
+ Goroutine 栈: ~20MB
= 总计 ~550MB如果 limits: 256Mi → OOM!
如果 limits: 512Mi → 正常

验证

$ kubectl top pods -l app=cloudnative-api
NAME                               CPU(cores)   MEMORY(bytes)
cloudnative-api-xxx-aaa            185m         180Mi  ← 正常
cloudnative-api-xxx-bbb            180m         175Mi  ← 正常

7.3 优化历程

第 1 次压测:失败

resources:limits:memory: "256Mi"  # 不够cpu: "300m"readinessProbe:timeoutSeconds: 3      # 太短failureThreshold: 3    # 太少

结果

  • ❌ OOMKilled
  • ❌ CrashLoopBackOff
  • ❌ 压测中断

第 2 次压测:成功

resources:limits:memory: "512Mi"  # ✅ 翻倍cpu: "500m"      # ✅ 提高readinessProbe:timeoutSeconds: 10     # ✅ 增加failureThreshold: 6    # ✅ 增加

结果

  • ✅ 0 次 OOM
  • ✅ 0 次重启
  • ✅ 100% 成功率
  • ✅ 压测顺利完成

八、最佳实践总结

8.1 资源配置建议

基于压测结果的推荐配置

# API 服务(中等负载)
resources:requests:cpu: "100m"      # HPA 基准,容易触发扩容memory: "128Mi"  # HPA 基准limits:cpu: "500m"      # 5 倍突发空间memory: "512Mi"  # 4 倍突发空间# 如果是高并发场景,可以进一步提高:
resources:limits:cpu: "1000m"     # 1 核memory: "1Gi"    # 1G

配置原则

  1. requests 保守:确保 Pod 容易调度,HPA 容易触发
  2. limits 充足:给突发负载足够的缓冲空间
  3. 比例合理:limits = requests × 4-5(CPU),× 4-8(内存)

8.2 探针配置建议

# 启动探针(快速检测启动)
startupProbe:httpGet:path: /healthport: 8080initialDelaySeconds: 0periodSeconds: 2       # 快速检测timeoutSeconds: 2failureThreshold: 15   # 最多等 30 秒# 存活探针(避免误杀)
livenessProbe:httpGet:path: /healthport: 8080initialDelaySeconds: 15periodSeconds: 15      # 降低频率timeoutSeconds: 10     # ⭐ 关键:高负载下需要更长时间failureThreshold: 5    # 允许失败 75 秒# 就绪探针(适应负载变化)
readinessProbe:httpGet:path: /readyport: 8080initialDelaySeconds: 5periodSeconds: 10timeoutSeconds: 10     # ⭐ 关键:高负载下需要更长时间failureThreshold: 6    # 允许失败 60 秒

关键原则

  • startupProbe 快(2 秒周期)
  • livenessProbe 慢(15 秒周期)
  • readinessProbe 中等(10 秒周期)
  • 高负载场景增加 timeout 和 failureThreshold

8.3 HPA 配置建议

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:name: api-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: your-apiminReplicas: 2       # 高可用:至少 2 个maxReplicas: 10      # 根据流量峰值设置metrics:# ⭐ 始终配置双指标- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 70      # 60-70% 是合理范围- type: Resourceresource:name: memorytarget:type: UtilizationaverageUtilization: 80      # 70-80%,留更多 bufferbehavior:# ⭐ 快速扩容scaleUp:stabilizationWindowSeconds: 0policies:- type: Percentvalue: 100                  # 可以翻倍periodSeconds: 15- type: Podsvalue: 2periodSeconds: 60selectPolicy: Max             # 选择更激进的策略# ⭐ 保守缩容scaleDown:stabilizationWindowSeconds: 300  # 5 分钟稳定期policies:- type: Podsvalue: 1                    # 每次只减 1 个periodSeconds: 60selectPolicy: Min             # 选择保守策略

8.4 压测策略建议

压测脚本设计

  1. 分阶段测试

    • 预热(30s)→ 增压(1m)→ 高峰(3m)→ 降压(2m)→ 冷却(1m)
  2. 混合负载

    • CPU 密集型 + 内存密集型
    • 模拟真实业务场景
  3. 随机参数

    • 请求参数随机化
    • 模拟不同用户行为
  4. 合理的并发

    • 本地测试:20-30 VU
    • 生产验证:50-100 VU
    • 极限测试:200+ VU

监控要点

  • ✅ HPA 扩缩容过程
  • ✅ Pod 状态变化
  • ✅ 资源使用情况
  • ✅ 错误率和响应时间
  • ✅ 系统日志

九、v0.3 完整总结

9.1 学习成果

通过 v0.3 的开发和压测,我掌握了:

1. 弹性伸缩理论

  • ✅ HPA 工作原理和计算公式
  • ✅ Metrics Server 架构和作用
  • ✅ 资源管理(requests/limits)
  • ✅ Pod QoS 和资源保证

2. HPA 实战配置

  • ✅ 编写 HPA YAML 配置
  • ✅ 配置 CPU 和内存双指标
  • ✅ 调优 behavior 策略
  • ✅ 调试和排查 HPA 问题

3. 性能测试技能

  • ✅ 使用 k6 编写压测脚本
  • ✅ 设计多阶段测试场景
  • ✅ 分析性能指标(P50、P95、P99)
  • ✅ 验证系统稳定性

4. 问题诊断能力

  • ✅ 诊断 OOMKilled 问题
  • ✅ 解决探针超时问题
  • ✅ 分析内存占用原因
  • ✅ 迭代优化配置

9.2 核心配置

Deployment 资源配置

resources:requests:cpu: "100m"memory: "128Mi"limits:cpu: "500m"      # 5 倍突发memory: "512Mi"  # 4 倍突发

HPA 配置

minReplicas: 2
maxReplicas: 10
metrics:
- CPU: 70%
- Memory: 80%
behavior:
- scaleUp: 立即响应(0s 稳定窗口)
- scaleDown: 保守缩容(300s 稳定窗口)

探针配置

readinessProbe:timeoutSeconds: 10      # 高负载适配failureThreshold: 6     # 避免误杀
livenessProbe:timeoutSeconds: 10failureThreshold: 5

9.3 性能指标

压测结果

指标数值评价
总请求数3186-
成功率100%⭐⭐⭐⭐⭐
失败率0%⭐⭐⭐⭐⭐
P50 响应时间48.86ms⭐⭐⭐⭐⭐
P95 响应时间983ms⭐⭐⭐⭐⭐
P99 响应时间~1.1s⭐⭐⭐⭐⭐
吞吐量5.58 req/s符合预期
HPA 扩容延迟45s⭐⭐⭐⭐⭐
Pod 重启次数0⭐⭐⭐⭐⭐

HPA 行为

初始副本: 2
扩容到: 4(CPU 超过 70%)
扩容延迟: ~45 秒
缩容延迟: ~6 分钟(含 5 分钟稳定窗口)
最终副本: 2(回到 minReplicas)

结语

这篇文章标志着 v0.3 弹性伸缩版的圆满完成!

🎉 成就解锁

  • ✅ 成功配置 HPA,实现自动扩缩容
  • ✅ 使用 k6 进行专业的负载测试
  • ✅ 达到 100% 请求成功率
  • ✅ P95 响应时间 < 1 秒
  • ✅ 0 次 Pod 崩溃,0 次 OOM
  • ✅ 系统性能达到生产级别

💡 核心收获

  1. 云原生的真正威力

    • 自动应对流量变化
    • 无需人工干预
    • 提高系统可靠性
  2. 资源管理的重要性

    • requests 是 HPA 的基础
    • limits 保护系统稳定
    • 合理配置是成功的关键
  3. 探针配置的艺术

    • 高负载下需要放宽限制
    • timeout 和 failureThreshold 很重要
    • 避免误杀繁忙的 Pod
  4. 性能测试的价值

    • 发现生产前的问题
    • 验证配置是否合理
    • 建立性能基线

🚀 下一步

v0.3 完成后,我已经掌握了 Kubernetes 的核心能力:

  • ✅ v0.1: 容器化和基础部署
  • ✅ v0.2: 工作负载和配置管理
  • ✅ v0.3: 弹性伸缩和性能优化

后续方向

  • 服务网格(Istio)
  • 可观测性(Prometheus + Grafana)
  • CI/CD 流水线
  • 生产级别的高可用架构

感谢你跟随我的云原生之旅!


系列文章

  • 上一篇:HPA 完全指南:从原理到实践
  • v0.3 系列第一篇:云原生的核心优势:自动弹性伸缩实战

项目代码:GitHub - cloudnative-go-journey

http://www.dtcms.com/a/560903.html

相关文章:

  • 民宿网站的建设wordpress gallery
  • 【开题答辩全过程】以 广州网红点打卡介绍网站为例,包含答辩的问题和答案
  • Taro 源码浅析
  • Chart.js 混合图:深度解析与应用技巧
  • redis 大key、热key优化技巧|空间存储优化|调优技巧(一)
  • 监视你的脚本:自动 Linux 活动审计
  • 15.1.2.linux常见操作用例
  • 【Java Web学习 | 第五篇】CSS(4) -盒子模型
  • ubuntu samba 快速安装启用
  • 【数据结构】用顺序表实现通讯录
  • cpp / c++零基础就业学习一站式学习平台
  • FreeRTOS(二)
  • 开源AI智能名片链动2+1模式S2B2C商城小程序商业化路径优化研究
  • 中国优秀的企业网站做搜狐网站页面
  • 【效率工具】EXCEL批注提取工具
  • Python openpyxl 设置Excel单元格公式和工作簿合并
  • 作文生成器网站北京seo招聘信息
  • 常州网站设计制作贵美商城网站的首页怎么做代码
  • 新媒体矩阵系统全景解析:赋能企业数字化营销的智能引擎
  • 多目标优化问题在适应度计算中的支配矩阵
  • 从零开始的云原生之旅(九):云原生的核心优势:自动弹性伸缩实战
  • 【Swift】LeetCode 240.搜索二维矩阵 II
  • 矩阵(板子)
  • 防火墙的内容补充
  • C++类和对象(下):初始化列表
  • 建筑工程找活网站wordpress文章新窗口
  • 沭阳城乡建设局网站做外国网站百度搜到
  • java-接口适配器模式 jsk8 接口默认实现
  • program.cs文件详解
  • 深圳市企业网站seo做东西的网站有那些