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 logsdmesg 可见 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,可能导致宿主机风险。


练习与验证清单#

  1. 启动一个容器限制 --cpus=0.5,用 stress --cpu 2 验证 CPU 限制是否稳定在 50% 左右。
  2. 设置 --memory=128m --memory-swap=256m,用 stress --vm-bytes 200m 触发 OOM,观察容器退出原因。
  3. 使用 --cpu-shares=512--cpu-shares=2048 启动两个容器,运行同样的 CPU 压测,比较 docker stats 中 CPU 分配比例。