3、资源监控与基准测试:用数据说话,别靠感觉
说实话,我见过太多团队在容器资源规划上翻车了。要么给多了浪费钱,要么给少了频繁 OOM。你想想看,没有数据支撑的规划,不就是拍脑袋吗?
这一章,我们就来聊聊怎么用监控工具和压力测试,摸清你应用的「真实胃口」。我个人习惯把这步叫做「摸底考试」——考过了,你才知道该给多少资源。
3.1 实时监控三板斧:docker stats、cAdvisor、Prometheus
监控工具很多,但真正在生产环境里用得顺手的,其实就那么几个。我按使用场景给你排个序:
3.1.1 docker stats:快速上手,适合临时排查
这是 Docker 自带的命令,不需要额外安装。我经常在排查问题时先用它瞄一眼:
# 查看所有运行中容器的实时资源
docker stats
# 只看某个容器
docker stats <container_name>
# 输出为 JSON 格式,方便脚本处理
docker stats --no-stream --format "{{json .}}"
输出里能看到 CPU 百分比、内存使用、网络 I/O、磁盘 I/O。嗯,这里要注意:docker stats 显示的是瞬时值,不是平均值。你盯着看 5 秒和看 5 分钟,结果可能差很多。
3.1.2 cAdvisor:容器级别的「体检报告」
cAdvisor 是 Google 开源的容器监控工具。它比 docker stats 强在哪?说白了,它能给你历史数据、图表、以及更细粒度的指标。
部署起来很简单:
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--volume=/dev/disk/:/dev/disk:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
--privileged \
--device=/dev/kmsg \
gcr.io/cadvisor/cadvisor:latest
启动后访问 http://localhost:8080,就能看到每个容器的 CPU、内存、网络、文件系统使用情况。我个人习惯用它的「历史趋势图」来判断资源峰值——这比 docker stats 靠谱多了。
3.1.3 Prometheus + Grafana:生产级监控方案
这才是真正的「大杀器」。Prometheus 负责采集和存储,Grafana 负责可视化。我建议你直接上这套组合拳:
# prometheus.yml 配置示例
scrape_configs:
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
metrics_path: '/metrics'
scrape_interval: 15s
- job_name: 'node_exporter'
static_configs:
- targets: ['node_exporter:9100']
scrape_interval: 15s
用 docker-compose 一键部署:
version: '3'
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
有了 Prometheus,你可以查任意时间段的资源使用情况。比如:
# 查询过去 24 小时容器的 CPU 使用率(平均值)
rate(container_cpu_usage_seconds_total{name="my-app"}[5m])
# 查询内存使用峰值
max_over_time(container_memory_usage_bytes{name="my-app"}[24h])
为什么我推荐 Prometheus?因为它能帮你回答三个关键问题:
- 峰值是多少?——决定资源上限
- 平均值是多少?——决定资源预留
- 波动有多大?——决定是否需要弹性伸缩
3.2 压力测试:给应用「上强度」
监控只能看到「日常表现」,但你要知道应用的极限在哪。这就得靠压力测试了。我一般用两个工具:stress 和 sysbench。
3.2.1 stress:简单粗暴的 CPU/内存压测
stress 是个轻量级工具,适合快速验证容器的资源限制是否生效:
# 模拟 4 个 CPU 核满载 60 秒
stress --cpu 4 --timeout 60
# 模拟 2 个 CPU 核 + 512MB 内存压力
stress --cpu 2 --vm 1 --vm-bytes 512M --timeout 30
在容器里跑:
docker run --rm --cpus="2" --memory="1g" \
polinux/stress stress --cpu 2 --vm 1 --vm-bytes 800M --timeout 60
然后打开 cAdvisor 或 Prometheus,观察 CPU 和内存曲线。你会发现:
- CPU 限制为 2 核时,即使 stress 请求 4 核,实际使用也不会超过 200%
- 内存超过 800MB 时,容器会被 OOM Kill
3.2.2 sysbench:更专业的基准测试
sysbench 能测试 CPU、内存、磁盘 I/O、数据库等。我一般用它来做「基准线」测试:
# CPU 基准测试(计算素数)
sysbench cpu --cpu-max-prime=20000 run
# 内存基准测试
sysbench memory --memory-block-size=1M --memory-total-size=10G run
# 磁盘 I/O 测试
sysbench fileio --file-total-size=10G prepare
sysbench fileio --file-total-size=10G --file-test-mode=rndrw run
sysbench fileio --file-total-size=10G cleanup
在容器里跑,对比不同资源限制下的性能差异:
# 测试 1 核 vs 2 核的 CPU 性能
docker run --rm --cpus="1" someimage sysbench cpu run
docker run --rm --cpus="2" someimage sysbench cpu run
你会看到类似这样的结果:
| CPU 限制 | 事件数(越高越好) | 延迟(越低越好) |
|---|---|---|
| 1 核 | 10,000 | 10.02ms |
| 2 核 | 19,800 | 5.05ms |
| 4 核 | 39,100 | 2.56ms |
看到没?2 核的性能几乎是 1 核的两倍,但 4 核并没有翻倍——因为应用本身可能无法充分利用多核。这就是为什么我强调「不要盲目给资源」。
3.3 确定真实资源需求:三步法
好了,监控有了,压测也做了。怎么确定最终值?我总结了一个三步法:
- 收集日常峰值:用 Prometheus 查过去 7 天的 CPU 和内存峰值(去掉异常值)
- 压测极限值:用 stress/sysbench 模拟业务高峰,记录资源使用上限
- 加 20% 余量:在峰值基础上增加 20% 作为 requests,再加 50% 作为 limits
举个例子:
# 假设压测结果
CPU 峰值: 1.2 核
内存峰值: 512 MB
# 最终配置
resources:
requests:
cpu: "1.5" # 1.2 * 1.2 ≈ 1.44,向上取整
memory: "640Mi" # 512 * 1.25 = 640
limits:
cpu: "2" # 1.2 * 1.5 = 1.8,向上取整
memory: "1Gi" # 512 * 2 = 1024
最后说一句:资源规划不是一劳永逸的事。应用在迭代,流量在变化,你的资源配比也得跟着调整。我建议每季度做一次「资源复盘」,用 Prometheus 拉数据,看看有没有「资源过剩」或「资源不足」的容器。
嗯,这一章的内容就到这。下一章我们聊聊怎么用 Kubernetes 的 HPA 和 VPA 做自动伸缩——那才是真正的「降本增效」利器。