docker资源限额与监控依赖linux cgroups和namespace机制,通过-m/--cpus等参数实现内存cpu限制,结合docker stats、cadvisor+prometheus+grafana完成监控闭环。

Docker 实现容器资源限额与监控,核心依赖 Linux 内核的 cgroups(Control Groups) 和 namespace 机制,配合运行时工具与可观测性组件完成闭环管理。这不是 Docker 自己“发明”的能力,而是它对底层内核特性的标准化封装和易用化暴露。
资源限额:靠 cgroups 精确划界
Docker 在启动容器时,会自动为该容器创建一组 cgroup 子系统(如 cpu, memory, blkio, pids),并将容器内所有进程加入其中。你通过命令行或配置文件设置的参数,最终都会写入对应 cgroup 文件。
内存限额:防 OOM 的关键防线
-
-m或--memory:硬上限。比如-m 1g表示容器最多用 1GB 物理内存,超限即被内核 OOM Killer 杀死。 -
--memory-swap:内存 + swap 总量限制。设为-m 512m --memory-swap 512m就等于禁用 swap。 -
--memory-reservation:软限制。比如设为256m,当宿主机内存紧张时,系统会优先压缩这个容器的内存使用,但平时可突破该值。 -
--oom-score-adj:调整容器内进程被 OOM Kill 的倾向。数值范围 -1000(永不杀)到 1000(最优先杀),默认不设,由内核按实际内存占用动态评分。
⚠️ 注意:若宿主机未开启 swap 限制支持(
docker info中提示WARNING: No swap limit support),--memory-swap可能不生效。
CPU 限额:控制时间片分配
-
--cpus 1.5:最直观的方式,表示最多占用 1.5 个逻辑 CPU 核心(支持小数,Docker 自动换算为cpu.cfs_quota_us/cpu.cfs_period_us)。 -
--cpu-shares 512:相对权重,默认是 1024。仅在 CPU 竞争时起作用,不设上限——两个--cpu-shares 512的容器,在空闲宿主机上都能跑满 100% CPU。 -
--cpuset-cpus "0-2":绑定到特定 CPU 核心,适合 NUMA 场景或隔离关键服务。
其他资源限制
- I/O 限速:
--device-read-bps /dev/sda:10mb限制读取带宽为 10MB/s。 - 进程数限制:
--pids-limit 100防止 fork bomb 类攻击。 - 网络带宽:Docker 原生不支持,需结合
tc(Traffic Control)或 CNI 插件(如 Calico、Cilium)实现。
容器监控:从实时查看到长期观测
1. 命令行快速诊断:docker stats
docker stats --no-stream nginx-app # 查看单个容器实时资源占用
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" # 自定义输出
显示字段包括 CPU %、内存用量/限额、网络收发、磁盘 IO、PIDs 数量。数据来自 /sys/fs/cgroup/ 下的实时统计,轻量、无存储、无告警。
2. 深度指标采集:cAdvisor + Prometheus + Grafana
-
cAdvisor:Google 开源的容器监控代理,内置 Web UI(默认
:8080),自动发现所有容器,采集 CPU、内存、网络、磁盘、PID、文件系统等数十项指标。 -
Prometheus:拉取 cAdvisor 的
/metrics接口(如http://cadvisor:8080/metrics),持久化存储时序数据,支持 PromQL 查询与告警规则。 - Grafana:对接 Prometheus 数据源,可视化展示容器 CPU 使用率趋势、内存增长曲线、OOM 事件计数、容器重启频次等。
✅ 示例告警规则(Prometheus):
- alert: ContainerMemoryHigh expr: container_memory_usage_bytes{container!=""} / container_spec_memory_limit_bytes{container!=""} > 0.9 for: 2m labels: severity: warning annotations: summary: "High memory usage in {{ $labels.container }}"
3. 日志与事件辅助判断
-
docker events --filter 'event=start' --filter 'event=die':监听容器启停、退出事件,结合退出码(如137= OOM Kill)快速定位问题。 -
docker logs -t --tail 100 app-container:查看应用日志,常与资源异常时间点交叉分析。
实际配置建议(避免踩坑)
- 不要只设
--cpus或只设--cpu-shares:前者控绝对上限,后者管争抢公平性,生产环境建议两者结合。 - 内存限制必须配
--memory-swap显式设值,否则默认允许翻倍 swap,可能掩盖真实内存压力。 -
docker-compose.yml中的resources.limits仅在 Swarm 模式下生效;单机部署请用docker run参数或改用docker compose(v2.20+ 支持部分资源限制)。 - 监控采集间隔别设太短(如 1s),cAdvisor 默认 10s 采样已足够;高频拉取反而增加宿主机负载。
- 所有资源限制都应在压测后设定:先观察基线用量,再预留 20–30% 缓冲,避免误杀或性能抖动。
不复杂但容易忽略。











