FIO 实战:Kubernetes 持久卷性能 Benchmark 指南

一、为什么需要测试 Kubernetes 持久卷性能?

在 Kubernetes 环境中,持久卷(Persistent Volume, PV)是存储的核心组件。无论是数据库、消息队列还是缓存服务,存储性能直接影响应用的整体表现。然而,实际生产环境中,存储性能常常成为性能瓶颈,主要原因包括:

  1. 存储类配置不当:不同的 StorageClass 提供了不同的性能特征(如 SSD vs HDD)。
  2. 资源争用:多个 Pod 共享同一存储后端时可能产生 I/O 争用。
  3. 网络延迟:特别是跨节点或云环境下的网络存储(如 AWS EBS、Azure Disk)。
  4. 配置错误:错误的挂载选项或文件系统选择可能导致性能下降。

通过科学的基准测试(Benchmark),我们可以:

  • 验证存储供应商承诺的性能指标
  • 识别性能瓶颈
  • 为应用选择合适的存储类
  • 优化持久卷声明(PVC)配置

二、FIO 工具简介

FIO(Flexible I/O Tester)是业界标准的存储性能测试工具,具有以下特点:

  • 支持多种 I/O 引擎(libaio、sync、psync 等)
  • 可模拟随机/顺序、读/写、同步/异步等多种 I/O 模式
  • 提供丰富的性能指标(IOPS、带宽、延迟)
  • 支持多线程/多进程测试
  • 可生成详细的统计报告

三、测试环境准备

1. 创建测试专用 Pod

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: fio-tester
  5. spec:
  6. containers:
  7. - name: fio
  8. image: ubuntu:22.04
  9. command: ["sleep", "infinity"]
  10. volumeMounts:
  11. - mountPath: /test
  12. name: test-volume
  13. volumes:
  14. - name: test-volume
  15. persistentVolumeClaim:
  16. claimName: <your-pvc-name>
  17. restartPolicy: Never

2. 安装 FIO

进入测试 Pod 后安装 FIO:

  1. apt update && apt install -y fio

3. 测试文件准备

建议使用测试专用文件,避免影响现有数据:

  1. fio --name=prep --filename=/test/fio-test-file --size=10G --rw=write --bs=1M --direct=1

四、核心测试场景与 FIO 参数配置

1. 顺序读写测试(带宽测试)

  1. fio --name=seq_read_write \
  2. --filename=/test/fio-test-file \
  3. --size=10G \
  4. --rw=readwrite \
  5. --bs=1M \
  6. --direct=1 \
  7. --ioengine=libaio \
  8. --runtime=60 \
  9. --time_based \
  10. --end_fsync=1 \
  11. --group_reporting

关键参数解析

  • rw=readwrite:同时进行读和写测试(可单独设置为 readwrite
  • bs=1M:1MB 的块大小,适合测试顺序 I/O
  • direct=1:绕过系统缓存,测试真实存储性能
  • runtime=60:测试持续 60 秒

预期结果

  • 带宽(MB/s):理想情况下应接近存储类承诺的吞吐量
  • 延迟(us):顺序 I/O 通常延迟较低

2. 随机读写测试(IOPS 测试)

  1. fio --name=rand_read_write \
  2. --filename=/test/fio-test-file \
  3. --size=10G \
  4. --rw=randrw \
  5. --rwmixread=70 \
  6. --bs=4k \
  7. --direct=1 \
  8. --ioengine=libaio \
  9. --numjobs=4 \
  10. --runtime=60 \
  11. --time_based \
  12. --group_reporting

关键参数解析

  • rw=randrw:随机读写混合
  • rwmixread=70:70% 读,30% 写
  • bs=4k:4KB 块大小,模拟数据库等小文件操作
  • numjobs=4:使用 4 个并发作业模拟多线程场景

预期结果

  • IOPS:随机小文件 I/O 的核心指标
  • 延迟(us):特别是 99th 百分位延迟,反映尾部延迟情况

3. 延迟敏感型测试

  1. fio --name=latency_test \
  2. --filename=/test/fio-test-file \
  3. --size=1G \
  4. --rw=randrw \
  5. --rwmixread=50 \
  6. --bs=4k \
  7. --direct=1 \
  8. --ioengine=libaio \
  9. --runtime=30 \
  10. --time_based \
  11. --latency_percentiles=1,5,10,20,50,90,95,99,99.9,99.99 \
  12. --group_reporting

关键参数解析

  • latency_percentiles:输出详细的延迟百分位统计
  • 较小的 size:减少预热时间,快速获取延迟数据

预期结果

  • 延迟分布:识别异常高延迟请求
  • 百分位延迟:特别是 99.9% 和 99.99% 延迟,对延迟敏感应用至关重要

五、结果分析与优化建议

1. 结果解读关键点

  • IOPS 达标情况:与存储类承诺的 IOPS 对比
  • 带宽利用率:实际带宽与理论最大值的比例
  • 延迟分布:特别是高百分位延迟是否在可接受范围内
  • 读写比例影响:不同读写混合比下的性能变化

2. 常见问题与优化

  1. IOPS 低于预期

    • 检查是否达到存储类的 IOPS 上限
    • 考虑增加 numjobs 数量(但不要超过存储类限制)
    • 检查文件系统选择(如 XFS 通常比 ext4 性能更好)
  2. 高延迟问题

    • 检查是否有其他 Pod 共享同一存储
    • 考虑使用更高级别的存储类
    • 检查网络存储的网络延迟(如 iSCSI、NFS)
  3. 带宽不足

    • 确认存储类的吞吐量限制
    • 检查是否有多路径配置问题
    • 考虑使用本地卷(如 hostPath 或 local volume)测试极限

3. 自动化测试脚本示例

  1. #!/bin/bash
  2. TEST_FILE="/test/fio-benchmark"
  3. SIZE="10G"
  4. RUNTIME=60
  5. OUTPUT_DIR="/results"
  6. mkdir -p $OUTPUT_DIR
  7. # 顺序读写测试
  8. fio --name=seq_rw \
  9. --filename=$TEST_FILE \
  10. --size=$SIZE \
  11. --rw=readwrite \
  12. --bs=1M \
  13. --direct=1 \
  14. --ioengine=libaio \
  15. --runtime=$RUNTIME \
  16. --time_based \
  17. --end_fsync=1 \
  18. --output-format=json \
  19. --output=$OUTPUT_DIR/seq_rw.json
  20. # 随机读写测试
  21. fio --name=rand_rw \
  22. --filename=$TEST_FILE \
  23. --size=$SIZE \
  24. --rw=randrw \
  25. --rwmixread=70 \
  26. --bs=4k \
  27. --direct=1 \
  28. --ioengine=libaio \
  29. --numjobs=4 \
  30. --runtime=$RUNTIME \
  31. --time_based \
  32. --output-format=json \
  33. --output=$OUTPUT_DIR/rand_rw.json
  34. # 清理测试文件
  35. rm -f $TEST_FILE

六、最佳实践总结

  1. 测试环境隔离:使用专用 Pod 和文件进行测试,避免干扰
  2. 多维度测试:覆盖顺序/随机、读/写、不同块大小等场景
  3. 长时间测试:特别是对于延迟测试,建议至少 30 分钟以上
  4. 多次测试取平均:消除偶然因素影响
  5. 监控系统资源:测试时监控节点 CPU、内存、网络等资源使用情况
  6. 与供应商指标对比:将测试结果与存储供应商提供的 SLA 对比

通过系统化的 FIO 测试,我们可以全面了解 Kubernetes 持久卷的真实性能特征,为应用选择合适的存储方案提供数据支持。记住,存储性能测试不是一次性的工作,而应该随着应用负载特征的变化和集群规模的扩展定期进行。