文章目录
- [1. 实战概述](#1. 实战概述)
- [2. 实战步骤](#2. 实战步骤)
-
- [2.1 构建带stress-ng的alpine镜像](#2.1 构建带stress-ng的alpine镜像)
- [2.2 设置CPU周期与配额](#2.2 设置CPU周期与配额)
-
- [2.2.1 提出任务](#2.2.1 提出任务)
- [2.2.2 完成任务](#2.2.2 完成任务)
- [2.2.3 压力测试](#2.2.3 压力测试)
- [2.3 设置容器CPU使用率](#2.3 设置容器CPU使用率)
-
- [2.3.1 提出任务](#2.3.1 提出任务)
- [2.3.2 完成任务](#2.3.2 完成任务)
- [2.4 设置容器内存配额](#2.4 设置容器内存配额)
-
- [2.4.1 提出任务](#2.4.1 提出任务)
- [2.4.2 完成任务](#2.4.2 完成任务)
- [2.4.3 压力测试](#2.4.3 压力测试)
- [2.5 设置容器写磁盘的带宽](#2.5 设置容器写磁盘的带宽)
-
- [2.5.1 提出任务](#2.5.1 提出任务)
- [2.5.2 完成任务](#2.5.2 完成任务)
- [3. 实战总结](#3. 实战总结)
1. 实战概述
- 本次实战基于 EulerOS 系统,使用自建
alpine-stress镜像,依次完成 CPU 周期配额、CPU 权重分配、内存限制及磁盘 I/O 带宽控制等容器资源管理实验。通过docker run参数结合stress-ng压测工具,验证了 CGroups 对计算与存储资源的调度能力,同时揭示了在 cgroup v2 环境下磁盘限速的局限性。
2. 实战步骤
2.1 构建带stress-ng的alpine镜像
-
执行命令:
vim Dockerfile

-
执行命令:
docker build -t alpine-stress .

-
执行命令:
docker run --rm alpine-stress stress-ng --cpu 1 --timeout 10s

-
结果说明 :执行成功,
stress-ng在 10 秒内对 1 个 CPU 核心施加压力,系统内存充足未触发 OOM,验证了容器资源压测工具正常工作。
2.2 设置CPU周期与配额
2.2.1 提出任务
- 利用
alpine-stress镜像生成容器,设置容器调度的周期为50000,将容器在每个周期内的CPU配额设置为25000
2.2.2 完成任务
- 执行命令:
docker run -it --cpu-period=50000 --cpu-quota=25000 alpine-stress sh

- 结果说明 :容器以
--cpu-period=50000和--cpu-quota=25000启动,限制其最多使用 50% 的 CPU 时间(即 0.5 核),成功实现 CPU 资源控制,验证了 CGroups 对容器 CPU 占用的精细化管理。 - 参数说明 :
--cpu-period和--cpu-quota是基于 Linux 内核 CFS(Completely Fair Scheduler) 的机制;默认情况下,--cpu-period=100000(100ms),--cpu-quota=-1(不限制);本任务中, CPU \text{CPU} CPU限制 = quota period = 25000 50000 = 0.5 = \displaystyle\frac{\text{quota}}{\text{period}} = \frac{25000}{50000} = 0.5 =periodquota=5000025000=0.5核
2.2.3 压力测试
- 在容器内启动 CPU 压力负载
- 执行命令:
stress-ng --cpu 4 --timeout 30s --metrics-brief

- 结果说明 :在 CPU 配额限制为 0.5 核的容器中运行
stress-ng --cpu 4,成功完成 30 秒压测,bogo ops 达 988.64/s,验证了多线程负载下 CGroups 对 CPU 使用率的有效控制,实际占用未突破配额限制。
- 执行命令:
- 在宿主机监控 CPU 使用情况
- 在压力负载测试期间新开
Eluer终端,执行命令:docker stats

- 结果说明 :容器
thirsty_sammet的 CPU 使用率稳定在 49.56%,接近设定的 50% 配额上限,验证了--cpu-period=50000 --cpu-quota=25000对 CPU 资源的精确限制,成功实现 CGroups 的精细化调度控制。
- 在压力负载测试期间新开
2.3 设置容器CPU使用率
2.3.1 提出任务
- 利用
alpine-stress镜像生成两个容器,设置第二个容器的CPU使用率是第一个容器的两倍
2.3.2 完成任务
-
终端1:启动第一个容器(CPU 权重 1024,绑定到CPU 0)
- 执行命令:
docker run -it --name cpu-test-1 --cpuset-cpus=0 --cpu-shares=1024 alpine-stress stress-ng --cpu 1 --timeout 60s

- 结果说明 :容器
cpu-test-1成功在 CPU 0 上运行,执行了 60 秒的单线程压力测试,验证了其被绑定至指定 CPU 核心并正常工作,为后续多容器 CPU 资源竞争实验奠定了基础。
- 执行命令:
-
终端2:启动第二个容器(CPU 权重 2048,绑定到CPU 0)
- 执行命令:
docker run -it --name cpu-test-2 --cpuset-cpus=0 --cpu-shares=2048 alpine-stress stress-ng --cpu 1 --timeout 60s

- 结果说明 :容器
cpu-test-2成功绑定至 CPU 0 并执行 60 秒单线程压测,验证其在指定核心上运行正常,为后续与同核容器进行 CPU 权重对比实验做好准备。
- 执行命令:
-
终端3:在两个容器运行期间查看容器状态
- 执行命令:
docker stats

- 结果说明 :在 CPU 0 上运行的两个容器中,
cpu-test-2的 CPU 使用率为 66.82%,cpu-test-1为 33.36%,比例接近 2:1,验证了--cpu-shares=2048与1024在资源竞争下实现 CPU 时间按权重分配的有效性。
- 执行命令:
2.4 设置容器内存配额
2.4.1 提出任务
- 利用
alpine-stress镜像生成容器,设置容器使用的最大内存为256MB
2.4.2 完成任务
-
执行命令:
docker run -it --name test-memory --memory="256m" --memory-swap="256m" alpine-stress sh

-
结果说明 :容器
test-memory成功以 256MB 内存和 256MB 总虚拟内存(禁用 swap)启动,验证了--memory-swap参数配置生效,为后续触发 OOM 的内存压测实验做好准备。
2.4.3 压力测试
- 在容器内执行命令:
stress-ng --vm 1 --vm-bytes 300M --timeout 30s,超过256M内存限制

- 在终端2上执行命令:
docker ps -a --filter "name=test-memory",获取容器ID:ca3845b91025

- 执行命令:
docker inspect ca3845b91025 | grep -i oom

- 结果说明 :容器
ca3845b91025的OOMKilled字段为true,表明其因内存超限被内核 OOM Killer 强制终止,验证了在严格内存限制(如--memory=256m --memory-swap=256m)下,容器无法分配超过配额的内存,成功触发资源保护机制。
2.5 设置容器写磁盘的带宽
2.5.1 提出任务
- 利用
alpine-stress镜像生成两个容器,设置第二个容器写磁盘的带宽是第一个容器的两倍
2.5.2 完成任务
- 获取根文件系统设备
- 执行命令:
ROOT_DEV=$(readlink -f /dev/mapper/openeuler-root)

- 执行命令:
echo $ROOT_DEV

- 执行命令:
- 启动第一个容器(写带宽限制为 10 MB/s)
- 执行命令:
docker run -d --name io-test-1 --device-write-bps /dev/dm-0:10mb alpine-stress sh -c "dd if=/dev/zero of=/tmp/test1 bs=1M count=100 oflag=direct"

- 执行命令:
- 启动第二个容器(写带宽限制为 20 MB/s)
- 执行命令:
docker run -d --name io-test-2 --device-write-bps /dev/dm-0:20mb alpine-stress sh -c "dd if=/dev/zero of=/tmp/test2 bs=1M count=100 oflag=direct"

- 执行命令:
- 验证是否生效
- 执行命令:
docker logs io-test-1与docker logs io-test-2

- 结果说明 :尽管设置了
--device-write-bps /dev/dm-0:10mb和20mb的写带宽限制,但容器实际写入速度分别达到 1.2GB/s 和 2.1GB/s,远超设定值。这表明在 cgroup v2 环境下,Docker 的--device-write-bps参数未生效,无法实现对磁盘 I/O 带宽的精确控制,需改用其他方式(如ionice)进行相对优先级管理。
- 执行命令:
3. 实战总结
- 本次实战系统验证了 Docker 容器在 CPU、内存和磁盘 I/O 三个维度的资源控制机制。CPU 方面,通过
--cpu-period/--cpu-quota精确限制核数,--cpu-shares实现多容器按权重分配 CPU 时间,docker stats显示比例接近理论值;内存方面,设置--memory=256m并禁用 swap 后,超限进程被 OOM Killer 正确终止,证明内存隔离有效;磁盘 I/O 方面,尽管配置--device-write-bps,但因系统启用 cgroup v2,该参数失效,实际写速达 GB/s 级。最终改用ionice可实现相对优先级控制。实验表明:CPU 与内存限制可靠,而磁盘带宽精确限速在现代 Linux 发行版中需依赖替代方案。