15.10.2 CPU与内存限制配置与验证
本节聚焦 Docker 中 CPU 与内存限制的配置与验证,包含原理草图、关键参数说明、完整命令示例、安装与排错步骤以及练习,确保资源可控、性能可预期。
原理草图(cgroups 资源限制路径)
关键参数说明(命令与含义)
- --cpus:限制可用 CPU 核心数(小数支持),内部映射到 cpu.cfs_quota_us/cpu.cfs_period_us。
- --cpu-quota 与 --cpu-period:CFS 配额控制,配额/周期=可用比例。
- --cpuset-cpus:绑定到指定 CPU 核心,隔离性能。
- --cpu-shares:相对权重(竞争场景有效),默认 1024。
- --memory:内存上限。
- --memory-swap:内存+swap 上限。
- --memory-swappiness:swap 倾向(0-100)。
- --oom-kill-disable:禁用 OOM killer(谨慎)。
安装准备与验证工具#
安装 stress 工具(用于压测验证)
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y stress
# RHEL/CentOS
sudo yum install -y epel-release
sudo yum install -y stress
说明
- stress 用于在容器内制造 CPU/内存负载。
- 也可用 stress-ng,但本文以 stress 为例。
CPU 限制配置与验证(完整示例)#
1)启动容器并限制 CPU
docker run -d --name cpu_demo \
--cpus=1.5 \
--cpu-period=100000 \
--cpu-quota=150000 \
--cpuset-cpus="0-1" \
alpine sleep 3600
命令解释
- --cpus=1.5:限制容器最多使用 1.5 个核心。
- --cpu-period=100000 + --cpu-quota=150000:配额为 150%,与 --cpus=1.5 语义一致。
- --cpuset-cpus="0-1":绑定 CPU0-CPU1,避免跨核抖动。
2)查看限制是否生效
docker inspect cpu_demo --format '{{.HostConfig.CpuQuota}} {{.HostConfig.CpuPeriod}} {{.HostConfig.CpusetCpus}}'
预期输出
150000 100000 0-1
3)容器内压测验证
docker exec -it cpu_demo sh -c "apk add --no-cache stress && stress --cpu 4 --timeout 20"
预期效果
- docker stats 中 CPU 使用率稳定在 ~150%(相对单核)。
4)宿主机 cgroup 验证
ID=$(docker inspect -f '{{.Id}}' cpu_demo)
cat /sys/fs/cgroup/cpu/docker/$ID/cpu.cfs_quota_us
cat /sys/fs/cgroup/cpu/docker/$ID/cpu.cfs_period_us
cat /sys/fs/cgroup/cpuset/docker/$ID/cpuset.cpus
内存限制配置与验证(完整示例)#
1)启动容器并限制内存
docker run -d --name mem_demo \
--memory=256m \
--memory-swap=512m \
--memory-swappiness=10 \
alpine sleep 3600
2)查看限制是否生效
docker inspect mem_demo --format '{{.HostConfig.Memory}} {{.HostConfig.MemorySwap}} {{.HostConfig.MemorySwappiness}}'
预期输出
268435456 536870912 10
3)容器内压测验证(触发 OOM)
docker exec -it mem_demo sh -c "apk add --no-cache stress && stress --vm 1 --vm-bytes 400m --timeout 20"
预期效果
- 内存耗尽时容器可能被 OOM kill,docker logs 或 dmesg 可见 OOM 记录。
4)宿主机 cgroup 验证
ID=$(docker inspect -f '{{.Id}}' mem_demo)
cat /sys/fs/cgroup/memory/docker/$ID/memory.limit_in_bytes
cat /sys/fs/cgroup/memory/docker/$ID/memory.memsw.limit_in_bytes
常见问题与排错#
1)CPU 限制无效
- 排查步骤:
docker inspect cpu_demo --format '{{.HostConfig.CpuQuota}}'
- 说明:
- 若为
-1表示未限制。 cpuset绑定到不存在或离线 CPU 会导致限制不生效。
2)内存限制不生效
- 排查步骤:
docker inspect mem_demo --format '{{.HostConfig.Memory}}'
- 说明:
- 未设置
--memory则默认无限制。 - 部分内核/容器环境需确认启用 memory cgroup。
3)频繁 OOM
- 处理建议:
- 适当提高 --memory 或 --memory-swap。
- 避免使用 --oom-kill-disable,可能导致宿主机风险。
练习与验证清单#
- 启动一个容器限制
--cpus=0.5,用stress --cpu 2验证 CPU 限制是否稳定在 50% 左右。 - 设置
--memory=128m --memory-swap=256m,用stress --vm-bytes 200m触发 OOM,观察容器退出原因。 - 使用
--cpu-shares=512与--cpu-shares=2048启动两个容器,运行同样的 CPU 压测,比较docker stats中 CPU 分配比例。