容器资源限制介绍
下面我将详细讲解 Docker 的各种资源限制及其在生产环境中的实际应用案例。我们将逐一探讨 CPU、内存、磁盘 I/O 和网络带宽的限制,并提供具体的配置示例和解释。
1. CPU 限制
1.1 设置 CPU 份额
--cpu-shares
:设置容器的 CPU 优先级权重。默认值为 1024。较高的值表示更高的优先级。- 作用:当多个容器竞争 CPU 资源时,CPU 份额决定了每个容器可以获得的 CPU 时间比例。
- 示例:
docker run -d --name container1 --cpu-shares 512 my_image docker run -d --name container2 --cpu-shares 1024 my_image
- 解释:假设宿主机有 1 个 CPU 核心,
container1
和container2
同时需要 CPU 资源,那么container2
将获得两倍于container1
的 CPU 时间。
1.2 设置 CPU 配额
-
--cpus
:限制容器可以使用的 CPU 核心数。例如,设置为 1.5 表示容器最多可以使用 1.5 个核心。- 作用:直接限制容器可以使用的 CPU 核心数,确保容器不会超过指定的核心数。
- 示例:
docker run -d --name container1 --cpus 1.5 my_image
- 解释:
container1
最多可以使用 1.5 个 CPU 核心,即使宿主机有更多的核心可用。
-
--cpu-period
和--cpu-quota
:更细粒度地控制 CPU 时间片。--cpu-period
:设置 CPU CFS(Completely Fair Scheduler)调度器的时间周期(单位为微秒,默认为 100000 微秒)。--cpu-quota
:设置在每个周期内容器可以使用的 CPU 时间(单位为微秒)。- 作用:通过设置周期和配额,可以更精确地控制容器的 CPU 使用。
- 示例:
docker run -d --name container1 --cpu-period 50000 --cpu-quota 25000 my_image
- 解释:
container1
每 50000 微秒可以使用 25000 微秒的 CPU 时间,相当于 50% 的 CPU 使用率。
2. 内存限制
2.1 设置内存限制
-
--memory
:限制容器可以使用的最大内存量(单位为字节或带单位的字符串,如1g
表示 1GB)。- 作用:确保容器不会消耗超过指定的内存,防止 OOM(Out of Memory)错误。
- 示例:
docker run -d --name container1 --memory 512m my_image
- 解释:
container1
最多可以使用 512MB 的内存。
-
--memory-swap
:设置容器可以使用的总内存(包括物理内存和交换空间)。如果设置为-1
,则不限制交换空间。- 作用:控制容器可以使用的总内存,包括物理内存和交换空间。
- 示例:
docker run -d --name container1 --memory 512m --memory-swap 1g my_image
- 解释:
container1
最多可以使用 512MB 的物理内存和 512MB 的交换空间,总共 1GB。
2.2 设置内存预留
--memory-reservation
:设置容器的内存预留量。当系统内存紧张时,优先保证预留量。- 作用:在系统内存紧张时,优先保证某些容器的内存需求。
- 示例:
docker run -d --name container1 --memory 512m --memory-reservation 256m my_image
- 解释:
container1
最多可以使用 512MB 的内存,但在系统内存紧张时,至少保证 256MB 的内存。
3. 磁盘 I/O 限制
3.1 设置块设备 I/O 限制
-
--blkio-weight
:设置容器的块设备 I/O 权重(范围为 10 到 1000,默认为 500)。- 作用:控制容器的 I/O 优先级。
- 示例:
docker run -d --name container1 --blkio-weight 300 my_image
- 解释:
container1
的 I/O 权重为 300,较低的权重意味着较低的 I/O 优先级。
-
--device-read-bps
和--device-write-bps
:限制容器对特定设备的读写速度(单位为字节/秒)。- 作用:控制容器对特定设备的读写速度,防止 I/O 负载过高。
- 示例:
docker run -d --name container1 --device-read-bps /dev/sda:1mb --device-write-bps /dev/sda:1mb my_image
- 解释:
container1
对/dev/sda
设备的读写速度分别限制为 1MB/s。
-
--device-read-iops
和--device-write-iops
:限制容器对特定设备的读写 IOPS(每秒 I/O 操作次数)。- 作用:控制容器对特定设备的 I/O 操作次数,防止 I/O 负载过高。
- 示例:
docker run -d --name container1 --device-read-iops /dev/sda:1000 --device-write-iops /dev/sda:1000 my_image
- 解释:
container1
对/dev/sda
设备的读写 IOPS 分别限制为 1000 次/秒。
4. 网络带宽限制
4.1 使用 tc
工具
Docker 本身没有直接提供网络带宽限制的功能,但可以通过 tc
(Traffic Control)工具来实现。
-
安装
tc
工具:apt-get update && apt-get install -y iproute2
-
设置网络带宽限制:
tc qdisc add dev eth0 root handle 1: htb default 11 tc class add dev eth0 parent 1: classid 1:1 htb rate 1mbit tc class add dev eth0 parent 1:1 classid 1:11 htb rate 1mbit
-
将容器的网络接口绑定到
tc
规则:docker run -d --name my_container --net=none my_image container_id=$(docker inspect -f '{{.Id}}' my_container) veth_pair=$(ip link show | grep $container_id | awk '{print $2}' | cut -d '@' -f 1) ip link set $veth_pair netns $(docker inspect -f '{{.State.Pid}}' my_container) ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) ip link set lo up ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) ip link set $veth_pair up ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) tc qdisc add dev $veth_pair root handle 1: htb default 11 ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) tc class add dev $veth_pair parent 1: classid 1:1 htb rate 1mbit ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) tc class add dev $veth_pair parent 1:1 classid 1:11 htb rate 1mbit
5. 其他资源限制
5.1 设置 PIDs 限制
--pids-limit
:限制容器可以创建的最大进程数。- 作用:防止容器创建过多的进程,导致系统资源耗尽。
- 示例:
docker run -d --name container1 --pids-limit 100 my_image
- 解释:
container1
最多可以创建 100 个进程。
5.2 设置内核参数
--ulimit
:设置容器的 ulimit 参数,如文件描述符数量。- 作用:控制容器的资源使用,防止资源耗尽。
- 示例:
docker run -d --name container1 --ulimit nofile=1024:1024 my_image
- 解释:
container1
的文件描述符数量限制为 1024。
生产实际案例
案例 1:Web 应用服务器
假设你有一个 Web 应用服务器,需要确保其不会消耗过多的 CPU 和内存资源,同时限制其磁盘 I/O 操作。
docker run -d --name web_app \--cpus 2 \--memory 1g \--memory-swap 2g \--device-read-bps /dev/sda:10mb \--device-write-bps /dev/sda:10mb \my_web_app_image
- 解释:
--cpus 2
:限制web_app
容器最多使用 2 个 CPU 核心。--memory 1g
:限制web_app
容器最多使用 1GB 的内存。--memory-swap 2g
:限制web_app
容器最多使用 2GB 的总内存(包括物理内存和交换空间)。--device-read-bps /dev/sda:10mb
和--device-write-bps /dev/sda:10mb
:限制web_app
容器对/dev/sda
设备的读写速度分别为 10MB/s。
案例 2:数据库服务器
假设你有一个数据库服务器,需要确保其有足够的内存和 CPU 资源,同时限制其磁盘 I/O 操作。
docker run -d --name db_server \--cpus 4 \--memory 8g \--memory-swap -1 \--device-read-bps /dev/sda:50mb \--device-write-bps /dev/sda:50mb \my_db_image
- 解释:
--cpus 4
:限制db_server
容器最多使用 4 个 CPU 核心。--memory 8g
:限制db_server
容器最多使用 8GB 的内存。--memory-swap -1
:不限制db_server
容器的交换空间。--device-read-bps /dev/sda:50mb
和--device-write-bps /dev/sda:50mb
:限制db_server
容器对/dev/sda
设备的读写速度分别为 50MB/s。
案例 3:批处理作业
假设你有一个批处理作业,需要在短时间内消耗大量 CPU 和内存资源,但不需要长期运行。
docker run -d --name batch_job \--cpus 8 \--memory 16g \--memory-swap -1 \--pids-limit 500 \my_batch_job_image
- 解释:
--cpus 8
:限制batch_job
容器最多使用 8 个 CPU 核心。--memory 16g
:限制batch_job
容器最多使用 16GB 的内存。--memory-swap -1
:不限制batch_job
容器的交换空间。--pids-limit 500
:限制batch_job
容器最多创建 500 个进程。
案例 4:缓存服务
假设你有一个缓存服务,需要确保其不会消耗过多的内存资源,同时限制其网络带宽。
docker run -d --name cache_service \--memory 2g \--memory-swap 2g \--ulimit nofile=65536:65536 \my_cache_image
- 解释:
--memory 2g
:限制cache_service
容器最多使用 2GB 的内存。--memory-swap 2g
:限制cache_service
容器最多使用 2GB 的总内存(包括物理内存和交换空间)。--ulimit nofile=65536:65536
:限制cache_service
容器的文件描述符数量为 65536。
最后,完结撒花~后续会有更多内容 ,敬请期待