Docker容器资源限制核心是“预留+硬限+动态反馈”三层配合:通过reservations/requests保障基础资源,limits/limits设硬上限,结合cgroup v2、内核调优与监控告警实现精准管控。
核心是让容器“用得上、但不抢光”,关键在预留+硬限+动态反馈三层配合——只设上限不管底,等于把门开着却锁了窗,资源仍会挤兑到临界点。
预留基础资源,确保系统服务不被挤占
宿主机必须为关键系统进程(如 systemd、sshd、dockerd、kubelet)保留最低可用资源,不能全盘交给容器调度:
- 内存层面:通过内核参数 vm.min_free_kbytes 强制预留物理内存(例如设为 1024000,即预留约1GB),避免 OOM Killer 在压力下误杀系统进程
- CPU 层面:启动关键守护进程时加 --cpu-shares=2048 或绑定独占 CPU 核(--cpuset-cpus="0-1"),使其始终有确定的调度保障
- 磁盘空间:用 tmpfs 挂载 /var/lib/docker/tmp 和 /run 目录,防止容器日志或构建缓存写满根分区
在编排层统一声明“预留+上限”双阈值
Docker Compose 和 Kubernetes 都支持软硬两级资源定义,仅设 limits 是单腿走路,必须补全 reservations / requests:
- Compose 中:reservations 告诉调度器“这个服务至少要这么多才肯启动”,limits 告诉内核“最多只能用这么多”
- K8s 中:requests 是调度准入门槛(节点必须空闲出这么多才允许调度),limits 是运行时铁律;两者缺一,Pod 就被打入 BestEffort QoS,失去任何资源保护
- 示例(K8s):
requests: {memory: "256Mi", cpu: "100m"}+limits: {memory: "512Mi", cpu: "300m"}—— 启动前就锁定基础配额,运行中再用上限兜底
用 cgroup v2 + 内核调优堵住隐性泄漏口
旧版 cgroup v1 存在内存统计不准、子组继承混乱等问题,易导致“看着没超,实际已挤爆”。必须启用并验证 cgroup v2:
- 确认生效:
stat -fc %T /sys/fs/cgroup输出应为 cgroup2fs - 禁用 swap 倾向:
vm.swappiness=1(而非默认60),避免内存压力下疯狂换页拖垮 I/O - 收紧缓存回收:
vm.vfs_cache_pressure=50,减少因 dentry/inode 缓存被大量回收引发的文件系统抖动 - 对 Java 容器额外注意:JVM -Xmx 必须比 --memory 至少小 20%,为元空间、线程栈、JNI 调用等留出余量
监控触发自动降级,把雪崩拦在临界点之前
限额不是摆设,得和可观测性联动才能起效:
- 采集指标:container_memory_working_set_bytes(真实活跃内存)比 usage 更准;container_cpu_cfs_throttled_periods_total 突增说明 CPU 已被强限,服务开始卡顿
- 告警策略:内存持续 > 85% 超过2分钟,或 CPU throttling 率 > 15% 持续3分钟,立即触发响应
- 自动动作:不是直接 kill,而是先发 SIGUSR2 触发应用优雅降级(如关闭健康检查、限流非核心接口),再根据负载趋势决定是否缩容副本


















