15.4.4 容器资源限制与优先级

容器资源限制与优先级通过 Linux cgroups 实现,对 CPU、内存、I/O、进程数等进行配额与调度控制,减少“邻居噪声”,保障关键服务稳定。

文章图片

一、安装与环境检查#

资源限制依赖内核 cgroups 与 Docker cgroup driver,先确认环境。

# 1) 查看 Docker 运行信息(重点关注 Cgroup Driver)
docker info | grep -E "Cgroup Driver|Cgroup Version"

# 2) 查看系统是否启用 cgroup v2(可选)
cat /sys/fs/cgroup/cgroup.controllers

# 3) 查看容器当前资源配置(以正在运行的容器为例)
CID=$(docker ps -q | head -n1)
docker inspect "$CID" --format '{{json .HostConfig}}' | jq

预期效果
- Cgroup Driver 显示为 systemdcgroupfs 均可。
- cgroup.controllers 存在表示启用 v2。

二、CPU 资源限制(示例+解释)#

关键参数
- --cpus:限制可用 CPU 核数总和。
- --cpu-period/--cpu-quota:配额与周期,精细控制。
- --cpuset-cpus:绑定指定核心。
- --cpu-shares:相对权重(非硬限制)。

# 1) 限制最多使用 1.5 核
docker run -d --name cpu_limit_1 \
  --cpus=1.5 nginx:alpine

# 2) 50% CPU:period 100000us, quota 50000us
docker run -d --name cpu_limit_2 \
  --cpu-period=100000 --cpu-quota=50000 nginx:alpine

# 3) 绑定 CPU 0,2 并提高权重(对竞争时更有利)
docker run -d --name cpu_limit_3 \
  --cpuset-cpus="0,2" --cpu-shares=2048 nginx:alpine

命令解释
- --cpus=1.5:容器最多使用 1.5 核的计算能力。
- --cpu-period/--cpu-quota:quota/period=使用比例。
- --cpu-shares:默认 1024,提高到 2048 表示相对更高优先级。

三、内存资源限制(示例+解释)#

关键参数
- --memory:硬限制。
- --memory-reservation:软限制。
- --memory-swap:内存+swap 上限。
- --oom-kill-disable:禁用 OOM Killer(谨慎)。

# 1) 512MB 内存上限,禁用 swap(swap=memory)
docker run -d --name mem_limit_1 \
  --memory=512m --memory-swap=512m nginx:alpine

# 2) 软限制 300MB,上限 800MB
docker run -d --name mem_limit_2 \
  --memory=800m --memory-reservation=300m nginx:alpine

预期效果
- 超过 --memory 时触发 OOM。
- 软限制容器在系统压力大时优先被回收。

四、块设备 I/O 限制(示例+解释)#

关键参数
- --blkio-weight:10–1000,相对权重。
- --device-read-bps/--device-write-bps:按设备限速。
- --device-read-iops/--device-write-iops:IOPS 限制。

# 1) 设置块设备权重与读速限制
docker run -d --name io_limit_1 \
  --blkio-weight=300 \
  --device-read-bps /dev/sda:20mb \
  nginx:alpine

# 2) 设置 IOPS 限制(随机读写场景)
docker run -d --name io_limit_2 \
  --device-read-iops /dev/sda:1000 \
  --device-write-iops /dev/sda:500 \
  nginx:alpine

注意
- 设备路径需与宿主机块设备一致(如 /dev/sda)。

五、进程与文件句柄限制(示例+解释)#

关键参数
- --pids-limit:限制最大进程数。
- --ulimit:文件句柄、栈大小等。

# 1) 限制最多 200 个进程
docker run -d --name pids_limit \
  --pids-limit=200 nginx:alpine

# 2) 限制文件句柄数
docker run -d --name ulimit_nofile \
  --ulimit nofile=65535:65535 nginx:alpine

六、优先级与调度策略(示例)#

  • CPU Shares 作为软优先级:关键服务更高,批处理更低。
  • 结合内存软限制与 I/O 权重实现“软调度”。
# 关键服务:高 CPU 权重 + 更高 I/O 权重
docker run -d --name svc_core \
  --cpu-shares=4096 --blkio-weight=800 \
  --memory=2g --memory-reservation=1.5g \
  app:latest

# 非关键服务:低 CPU 权重 + 低 I/O 权重
docker run -d --name svc_batch \
  --cpu-shares=256 --blkio-weight=100 \
  --memory=1g --memory-reservation=300m \
  batch:latest

七、排错与验证#

1) 容器未生效的资源限制

# 查看容器 HostConfig,确认参数是否写入
docker inspect cpu_limit_1 --format '{{json .HostConfig}}' | jq

2) CPU 使用异常高

# 查看容器实时资源
docker stats --no-stream cpu_limit_1

# 查看宿主机对应 cgroup 限制(cgroup v2 路径)
CID=$(docker inspect -f '{{.Id}}' cpu_limit_1)
cat /sys/fs/cgroup/system.slice/docker-${CID}.scope/cpu.max

3) OOM 异常退出

# 查看容器退出原因
docker inspect mem_limit_1 --format '{{.State.OOMKilled}} {{.State.ExitCode}}'

# 查看内核日志(可能包含 OOM 记录)
dmesg | tail -n 50

八、练习#

  1. 启动一个容器限制 0.5 核、256MB 内存,并禁用 swap,验证 docker stats 的变化。
  2. 启动两个容器,分别设置 --cpu-shares=2048--cpu-shares=256,用压测工具验证优先级差异。
  3. 为一个 I/O 密集容器设置 --device-read-bps--device-write-iops,观察吞吐与延迟变化。