目录
[1.CPU 资源控制](#1.CPU 资源控制)
[cgroups 的核心功能](#cgroups 的核心功能)
[①设置 CPU 使用率上限( --cpu-period / --cpu-quota )](#①设置 CPU 使用率上限( --cpu-period / --cpu-quota ))
[②设置 CPU 占用比(权重 --- --cpu-shares )](#②设置 CPU 占用比(权重 — --cpu-shares ))
[③绑定指定 CPU( --cpuset-cpus )](#③绑定指定 CPU( --cpuset-cpus ))
[4.CPU 限制关键参数说明](#4.CPU 限制关键参数说明)
[①memory 与 --memory-swap 规则](#①memory 与 --memory-swap 规则)
[②磁盘 IO(blkio / io)控制](#②磁盘 IO(blkio / io)控制)
[③验证(用 dd 测试写速)](#③验证(用 dd 测试写速))
[6.清理 Docker 占用的磁盘空间](#6.清理 Docker 占用的磁盘空间)
[③使用 --volumes-from 共享数据卷](#③使用 --volumes-from 共享数据卷)
[三、容器互联(使用 CentOS 镜像)](#三、容器互联(使用 CentOS 镜像))
前言
在容器化技术中,资源限制、数据卷容器和容器互联是构建高效、可扩展应用的关键要素。资源限制确保容器不会过度消耗系统资源,从而维持宿主机的稳定性;数据卷容器提供了持久化存储的解决方案,使数据在容器间共享和重用成为可能;容器互联则简化了多容器应用的网络通信,提升了服务间的协同效率。这些机制共同为容器编排和微服务架构奠定了坚实的基础,帮助开发者在复杂环境中实现资源的合理分配和高效管理。
一、资源限制
1.CPU****资源控制
CPU 资源控制是指通过技术手段管理和分配 CPU 的计算能力,确保系统资源的合理利用。常见的应用场景包括多任务调度、虚拟化环境、容器化部署等。核心目标包括避免资源争用、保障关键任务性能、优化整体系统效率。
2.什么是cgroup
cgroups(Control Groups)是 Linux 内核提供的一种机制,用于限制、记录和隔离进程组的资源使用(如 CPU、内存、磁盘 I/O、网络等)。它主要用于实现资源管理和进程隔离,是容器技术(如 Docker、LXC)的核心基础之一。
cgroups 的核心功能
- 资源限制:限制进程组使用的资源量(如内存上限、CPU 份额)。
- 优先级控制:为进程组分配不同的资源优先级(如 CPU 时间片权重)。
- 资源统计:记录进程组的资源使用情况(如 CPU 时间、内存占用)。
- 进程隔离:将进程组隔离到独立的命名空间,避免相互影响。
3.cgroup对cpu的限制
①设置 CPU 使用率上限( -- cpu**-** period**/** -- cpu**-** quota )
在容器化环境中(如 Docker 或 Kubernetes),可以通过 --cpu-period 和 --cpu-quota 参数限制容器的 CPU 使用率上限。以下是具体实现方式:
--cpu-period
定义 CPU 分配的周期(单位:微秒),默认值为 100000(即 100 毫秒)。该参数决定了 CPU 时间片的划分粒度。
--cpu-quota
指定容器在一个 cpu-period 周期内可使用的最大 CPU 时间(单位:微秒)。例如,若需限制容器使用 1 个 CPU 核心的 50%,则设置为 50000(即 50% × 100000)。
示例配置
限制容器使用单核 CPU 的 50%:
bash
docker run --cpu-period=100000 --cpu-quota=50000 your_image
限制容器使用双核 CPU 的 75%:
bash
docker run --cpu-period=100000 --cpu-quota=150000 your_image
计算公式
实际 CPU 使用率上限可通过以下公式计算: [ \text{CPU 上限} = \frac{\text{cpu-quota}}{\text{cpu-period}} \times 100% ] 例如,cpu-quota=50000 且 cpu-period=100000 时,上限为 50%。
注意事项
-
兼容性 :
--cpu-period和--cpu-quota需与 CFS(Completely Fair Scheduler)调度器配合使用。 -
动态调整 :运行时可通过
docker update修改配额:bashdocker update --cpu-quota=60000 container_id -
替代参数 :Docker 也支持
--cpus简化配置(如--cpus=1.5表示 1.5 核)。
②设置CPU占用比(权重**---****--cpu-**shares )
在 Linux 系统中,可以通过 --cpu-shares 参数为容器或进程分配 CPU 资源的相对权重。该参数不直接限制 CPU 使用率,而是用于在资源竞争时确定优先级。
使用方法(Docker 示例)
通过 docker run 命令启动容器时,使用 --cpu-shares 参数设置权重值。默认值为 1024,数值越高表示权重越大。
bash
docker run -d --cpu-shares 512 ubuntu:latest
权重分配示例
- 容器 A 设置
--cpu-shares 1024 - 容器 B 设置
--cpu-shares 2048
当 CPU 资源紧张时,容器 B 获得的 CPU 时间是容器 A 的两倍。
验证设置
通过 docker inspect 查看容器的 CPU 份额配置:
bash
docker inspect <容器ID> --format='{{.HostConfig.CpuShares}}'
注意事项
--cpu-shares仅在多个容器竞争 CPU 资源时生效。若系统有充足 CPU 资源,所有容器均可满载运行。- 该参数是相对权重,不是绝对值。例如,设置 512 表示权重是默认值(1024)的一半。
- 在 cgroups v2 系统中,
cpu.weight替代了cpu.shares,但 Docker 仍兼容旧参数。
**③绑定指定CPU(****--cpuset-**cpus )
在 Linux 系统中,可以使用 --cpuset-cpus 参数将进程或容器绑定到特定的 CPU 核心上运行。这种方法可以提高性能,减少上下文切换,并优化资源利用率。
使用 Docker 绑定 CPU
在 Docker 中,可以通过 --cpuset-cpus 参数将容器限制在特定的 CPU 核心上运行。语法如下:
bash
docker run --cpuset-cpus="0,1" <image_name>
上述命令将容器绑定到 CPU 核心 0 和 1 上运行。可以指定单个核心或多个核心,用逗号分隔。
验证 :在宿主机运行 top 或 htop (按 1 )查看各核利用率,或进入容器运行 taskset - p
<pid> 。
④压力测试与验证示例(CPU)
创建 cpu.sh 脚本并赋予执行权限:
bash
#!/bin/bash
i=0
while true; do let i++; done
chmod +x cpu.sh
启动两个权重不同的容器:
bash
docker run -itd --name c1 --cpu-shares 512 centos:7
docker run -itd --name c2 --cpu-shares 1024 centos:7
启动绑定特定 CPU 核心的容器:
bash
docker run -itd --name test7 --cpuset-cpus "1,3" centos:7 /bin/bash
进入容器执行压力测试:
bash
docker exec -it <container> bash
./cpu.sh
使用 stress 工具进行多核压力测试:
bash
yum install -y epel-release stress
stress -c 4
4.CPU 限制关键参数说明
--cpu-shares 参数仅设置相对权重(默认 1024),非绝对限制。实际 CPU 分配比例取决于所有容器的总权重值。
--cpuset-cpus 可绑定特定 CPU 核心,避免资源争抢。示例 "1,3" 表示仅使用第 2 和第 4 个 CPU 核心。
硬限制需组合使用:
bash
--cpu-period=100000 # 单位微秒(默认值)
--cpu-quota=50000 # 表示限制为 0.5 个 CPU
5.cgroup对内存的限制
cgroup(Control Group)是 Linux 内核提供的一种资源管理机制,用于限制、记录和隔离进程组的资源使用。在内存管理方面,cgroup 提供了对内存使用量的限制和统计功能,主要通过以下子系统实现:
-
memory 子系统
负责限制进程组的内存使用量,包括物理内存和交换空间(swap)。通过设置
memory.limit_in_bytes文件,可以限制 cgroup 中进程的最大内存使用量。 -
memory+swap 限制
通过
memory.memsw.limit_in_bytes可以限制内存和交换空间的总使用量。
①memory 与**--memory-**swap 规则
--memory 和 --memory-swap 是 Docker 容器中用于限制内存使用的关键参数。--memory 指定容器可用的物理内存上限,而 --memory-swap 控制容器可用的总内存(物理内存 + 交换分区)。默认情况下,--memory-swap 的值与 --memory 相同,表示禁用交换分区。
--memory 参数规则
--memory(或 -m)参数用于限制容器可用的物理内存。例如,--memory=1g 表示容器最多使用 1GB 物理内存。如果容器尝试分配超过此限制的内存,可能会被 OOM Killer 终止。
routeros
docker run -it --memory=1g ubuntu /bin/bash
--memory-swap 参数规则
--memory-swap 表示容器可用的总内存(物理内存 + 交换分区)。其行为取决于与 --memory 的关系:
- 如果
--memory-swap未设置,默认值与--memory相同,表示禁用交换分区。 - 如果
--memory-swap设置为-1,容器可以使用主机上无限制的交换分区(但物理内存仍受--memory限制)。 - 如果
--memory-swap大于--memory,差值即为可用的交换分区大小。
示例:
--memory=1g --memory-swap=2g:容器可使用 1GB 物理内存和 1GB 交换分区。--memory=1g --memory-swap=1g:禁用交换分区,仅允许 1GB 物理内存。--memory=1g --memory-swap=-1:物理内存限制为 1GB,交换分区无限制。
实际应用场景
限制容器的物理内存为 500MB,交换分区为 1GB:
routeros
docker run -it --memory=500m --memory-swap=1500m ubuntu /bin/bash
禁用交换分区,仅允许 500MB 物理内存:
routeros
docker run -it --memory=500m ubuntu /bin/bash
允许 500MB 物理内存,交换分区无限制:
routeros
docker run -it --memory=500m --memory-swap=-1 ubuntu /bin/bash
注意事项
- 交换分区的性能远低于物理内存,过度依赖可能导致性能下降。
- 如果
--memory-swap小于--memory,Docker 会报错。 - 在 Linux 主机上,需确保交换分区已启用(通过
free -m检查)。
②磁盘IO(blkio / io)控制
Docker 提供对块设备读写带宽与 IOPS 的限制选项(基于 cgroups 的 blkio 控制器)。
注意:在 cgroup v2 中, blkio 功能被 io 控制器取代,语义与文件名有所不同(如果你运行的是
较新内核 / 系统,请参考对应 cgroup 版本文档)
限制设备读写速率(BPS)
使用 --device-read-bps 和 --device-write-bps 参数可以限制容器对指定设备的读写速率(单位:字节/秒)。例如,限制 /dev/sda 的读取速率为 1MB/s,写入速率为 1MB/s:
bash
docker run --device-read-bps /dev/sda:1M --device-write-bps /dev/sda:1M <image>
限制设备读写 IOPS
通过 --device-read-iops 和 --device-write-iops 可以限制容器对设备的每秒读写操作次数(IOPS)。例如,限制 /dev/sda 的读取 IOPS 为 100,写入 IOPS 为 100:
bash
docker run --device-read-iops /dev/sda:100 --device-write-iops /dev/sda:100 <image>
参数单位说明
--device-read-bps/--device-write-bps:支持K(千字节)、M(兆字节)、G(吉字节)等单位。--device-read-iops/--device-write-iops:值为整数,表示每秒操作次数。
注意事项
- 需要确保目标设备路径(如
/dev/sda)在宿主机上存在。 - 仅对支持块设备 I/O 限制的系统有效(如 Linux 内核启用
CFQ或BFQ调度器)。 - 动态修改限制需重启容器。
③验证(用dd 测试写速)
dd 是一个常用的命令行工具,可用于测试磁盘的写入速度。以下是通过 dd 测试写入速度的具体方法:
测试方法
基本命令格式:
bash
dd if=/dev/zero of=testfile bs=1M count=1024 conv=fdatasync
参数说明:
if=/dev/zero:输入文件为/dev/zero(生成零数据流)。of=testfile:输出文件为当前目录下的testfile。bs=1M:块大小为 1MB。count=1024:写入 1024 个块,总大小为 1GB(1024 × 1MB)。conv=fdatasync:确保数据完全写入磁盘后再统计时间。
结果解读
命令执行完成后会输出类似以下信息:
basic
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 3.12345 s, 344 MB/s
- 关键指标 :最后一行的
344 MB/s即为写入速度。
6.清理Docker占用的磁盘空间
清理未使用的数据(可释放磁盘空间):
docker system prune -a
docker system prune -a 是一个用于清理 Docker 系统中未使用资源的命令。它会删除以下内容:
- 停止的容器
- 未被任何容器使用的网络
- 悬空(未被引用)的镜像
- 悬空的构建缓存
添加 -a 参数会进一步删除所有未被容器使用的镜像,而不仅仅是悬空镜像。
命令执行效果
执行该命令后,Docker 会列出将被删除的资源类型和数量,并提示确认。确认后,系统会清理这些资源并释放磁盘空间。
注意事项
使用该命令前需要注意:
- 该操作不可逆,删除的资源无法恢复
- 确保没有重要的停止容器或镜像需要保留
- 系统可能会提示需要额外参数来删除卷,因为默认不删除卷
二、数据卷容器
1.数据卷概念
数据卷(Volume)是容器技术中用于持久化存储数据的机制,允许容器与宿主机或其他容器共享数据。其核心特点是独立于容器的生命周期,即使容器被删除,数据卷中的数据仍会保留。
①创建与挂载数据卷
使用Docker命令行工具创建数据卷,命令格式如下:
bash
docker volume create [卷名称]
不指定名称时,Docker会自动生成随机名称。创建后可通过docker volume ls查看已有数据卷列表。
挂载数据卷到容器
运行容器时通过-v或--mount参数挂载数据卷。-v为传统语法,--mount为新推荐语法,支持更详细的配置选项。
传统语法示例:
bash
docker run -d -v [卷名称]:[容器内路径] [镜像名称]
将指定数据卷挂载到容器内的目标路径。若卷不存在会自动创建。
②在数据卷中写入数据并查看
echo "this is web1" > /data1/abc.txt
将字符串 "this is web1" 写入 /data1/abc.txt 文件。如果文件不存在,会自动创建;如果文件已存在,会覆盖原有内容。
bash
echo "this is web1" > /data1/abc.txt
检查文件内容
使用 cat 命令查看文件内容,确认写入是否成功:
bash
cat /data1/abc.txt
确保目录存在
如果 /data1 目录不存在,需要先创建目录:
bash
mkdir -p /data1
2.数据卷容器的概念
数据卷容器(Data Volume Container)是一种特殊的 Docker 容器,专门用于管理持久化数据。它通过挂载数据卷(Volume)实现数据共享,供其他容器访问或备份。数据卷的生命周期独立于容器,即使容器被删除,数据仍会保留。
①创建数据卷容器
首先,创建一个数据卷容器 web2 ,并挂载多个数据卷:

-- name web2 : 给容器命名为 web2
- v /data1 - v /data2 : 在容器内部挂载了两个数据卷 /data1 和 /data2 。这些数据卷不依赖于
宿主机,而是仅仅存在于容器内
② 在数据卷容器中写入数据
进入 web2 容器后,可以在 /data1 和 /data2 目录下写入数据:

现在, web2 容器内的 /data1/abc.txt 和 /data2/ABC.txt 文件已经被创建。
③**使用****--volumes-**from 共享数据卷
接下来,创建一个新的容器 web3 ,并通过 -- volumes - from 选项将 web2 容器中的数据卷挂载到
web3 容器中:

-- volumes - from web2 : 这表示将容器 web2 中的所有数据卷挂载到新容器 web3 中
④在新容器中查看数据
进入 web3 容器后,查看 web2 容器中的数据:

你应该能看到如下输出:

这表明 web3 容器成功挂载了 web2 容器中的数据卷,并能够访问其中的文件。
三、容器互联(使用CentOS镜像)
使用 Docker 网络
创建自定义网络,将容器加入同一网络,实现互联。以下命令创建名为 my-network 的网络:
bash
docker network create my-network
运行容器时指定网络:
bash
docker run -d --name container1 --network my-network centos
docker run -d --name container2 --network my-network centos
容器间可通过容器名称直接通信,例如在 container1 中 ping container2:
bash
docker exec -it container1 ping container2
使用 --link 参数(已过时)
旧版 Docker 支持 --link 参数,但不推荐使用:
bash
docker run -d --name container1 centos
docker run -d --name container2 --link container1 centos
共享网络命名空间
让容器共享同一网络命名空间,直接使用主机网络:
bash
docker run -d --name container1 --network host centos
docker run -d --name container2 --network host centos
环境变量注入
通过环境变量传递连接信息:
bash
docker run -d --name container1 -e HOST=container1 centos
docker run -d --name container2 -e HOST=container1 centos
验证互联
进入容器测试连通性:
bash
docker exec -it container1 ping container2
若需安装 ping 工具,在 CentOS 容器中执行:
bash
yum install -y iputils
小结:
源容器 :通过 docker run 启动,并通过 -- name 指定一个唯一名称,例如 web1 。
接收容器 :通过 docker run 启动,并通过 -- link 选项将其与源容器 web1 连接。 -- link 会将
源容器暴露为别名,接收容器可以通过该别名与源容器进行通信。
容器间通信 :接收容器可以通过源容器的名称进行通信,如在 web2 中通过 ping web1 测试与
web1 的连通性。
这种容器互联的方式适用于简单的容器间网络通信,但在较复杂的场景中,建议使用 Docker 网络(如桥接网络或自定义网络)来管理容器间的通信。
总结
资源限制、数据卷容器和容器互联是 Docker 及类似容器技术的核心功能,为现代应用部署提供了灵活性和可控性。通过合理配置资源限制,可以避免容器间的资源争用,保障系统性能;数据卷容器解决了数据持久化和共享的难题,确保关键信息不会因容器生命周期而丢失;容器互联简化了服务间的通信,使分布式应用的部署更加便捷。掌握这些技术,能够显著提升容器化应用的可靠性、可维护性和扩展性,为开发和运维工作带来更高的效率。