JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

Docker资源限制指南:CPU、内存与磁盘I/O控制详解

wys521 2024-10-18 11:23:48 精选教程 37 ℃ 0 评论

Docker为我们提供了丰富的参数选项限制容器使用宿主机的资源,包括内存、CPU、磁盘I/O等。限制资源通过cgroups实现,cgroups(control groups)是Linux内核提供的一个功能,它能实现限制进程的资源。提供以下是一些资源限制方法:

CPU限制

?  ~ docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Create and run a new container from an image
     --cpu-period int                   Limit CPU CFS (Completely Fair Scheduler) period
     --cpu-quota int                    Limit CPU CFS (Completely Fair Scheduler) quota
     --cpu-rt-period int                Limit CPU real-time period in microseconds
     --cpu-rt-runtime int               Limit CPU real-time runtime in microseconds
 -c, --cpu-shares int                   CPU shares (relative weight)
     --cpus decimal                     Number of CPUs
     --cpuset-cpus string               CPUs in which to allow execution (0-3, 0,1)
     --cpuset-mems string               MEMs in which to allow execution (0-3, 0,1)

以上为docker run可以使用的限制CPU资源的部分。

--cpu-period: 限制CPU CFS周期

--cpu-quota: 限制CPU配额

--cpu-rt-period: 限制 CPU 实时周期(单位:微秒)

--cpu-rt-runtime: 限制 CPU 实时运行时间(单位:微秒)

--cpu-shares: CPU 配额(相对权重)。默认每个容器的份额是1024,较高的值意味着更多的CPU时间。例,--cpu-shares 512 给容器分配相对较低的CPU份额。

--cpus: CPU 数量。例:--cpus=0.3,限制容器可以使用宿主机0.3个CPU配额

--cpuset-cpus: 限制只可以使用指定的CPU核心。例:--cpuset-cpus="0-3",限制容器可以使用宿主机CPU编号为0、1、2、3的四个核心。

--cpuset-mems: 限制容器可以在哪些内存节点上使用内存。例:--cpuset-mems="0-2",限制容器可以使用编号为0、1、2的三个内存节点,总共是三个节点。

演示:

?  ~ docker images
REPOSITORY            TAG               IMAGE ID       CREATED       SIZE
nginx                 latest            7383c266ef25   8 days ago    188MB
dockerswarmdemo-app   v2                640c0a108907   11 days ago   18.1MB
hello-go-db-app       latest            332f5045340c   13 days ago   26MB
postgres              latest            07e2ee723e2d   2 years ago   374MB
moby/buildkit         buildx-stable-1   19340e24de14   2 years ago   144MB
hello-world           latest            feb5d9fea6a5   2 years ago   13.3kB
?  ~ docker run -dP dockerswarmdemo-app:v2
65477b5f7e4504ce53f8b1a3838460ca9dc20dd48da945ede59677f56e7a51bd

运行一个dockerswarmdemo-app:v2 镜像的容器(一个go hello world程序)。

?  ~ docker ps
CONTAINER ID   IMAGE                    COMMAND              CREATED         STATUS         PORTS                                         NAMES
65477b5f7e45   dockerswarmdemo-app:v2   "/bin/sh -c ./app"   2 minutes ago   Up 2 minutes   0.0.0.0:32769->3003/tcp, :::32769->3003/tcp   peaceful_meninsky
// oha测试http负载的小程序,1000条连接,1000个请求数
?  ~ oha --no-tui -c 1000 -n 1000 http://localhost:32769 

// CPU % 达到了28.17%,空闲无请求时为0
?  ~ docker stats 65477b5f7e
CONTAINER ID   NAME                CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O   PIDS
65477b5f7e45   peaceful_meninsky   28.17%     31.55MiB / 3.823GiB   0.81%     2.07MB / 1.73MB   0B / 0B     17

oha测试http负载的小程序,1000条连接,1000个请求数对容器中的http服务进行请求测试。CPU % 达到了28.17%。

?  ~ oha --no-tui -c 1000 -n 1000 http://localhost:32769
Summary:
  Success rate: 100.00%
  Total:        0.2411 secs
  Slowest:      0.1886 secs
  Fastest:      0.0386 secs
  Average:      0.0987 secs
  Requests/sec: 4147.4276

  Total data:   43.95 KiB
  Size/request: 45 B
  Size/sec:     182.26 KiB

以上为精简的oha结果。

?  ~ docker update --cpus=0.1 65477b5f7e4504ce53f8b1a3838460ca9dc20dd48da945ed
e59677f56e7a51bd
65477b5f7e4504ce53f8b1a3838460ca9dc20dd48da945ede59677f56e7a51bd

使用docker update --cpus=0.1限制容器CPU配额为0.1。再次,运行请求测试。

?  ~ docker stats 65477b5f7e
CONTAINER ID   NAME                CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O   PIDS
65477b5f7e45   peaceful_meninsky   9.71%     38.96MiB / 3.823GiB   1.00%     4.66MB / 4.01MB   41kB / 0B   17

再次观察CPU占用,会始终限制在10%以下在运行。

?  ~ oha --no-tui -c 1000 -n 1000 http://localhost:32769
Summary:
  Success rate: 100.00%
  Total:        2.6537 secs
  Slowest:      2.5453 secs
  Fastest:      0.0435 secs
  Average:      1.1574 secs
  Requests/sec: 376.8302

  Total data:   43.95 KiB
  Size/request: 45 B
  Size/sec:     16.56 KiB

以上为精简的oha结果。

通过两次使用oha请求测试结果可以发现,被限制后的平均请求时间为2.6537秒,远高于未限制时的平均请求时间0.2411秒。

?  ~ docker exec -it 65477b5f7e45 sh
/app # cat /sys/fs/cgroup/cpu.max
10000 100000

在容器内部可以查看到cgroups CPU限制配置文件。100000/10000=10。

内存限制

?  ~ docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Create and run a new container from an image
      -m, --memory bytes                     Memory limit
      --memory-reservation bytes         Memory soft limit
      --memory-swap bytes                Swap limit equal to memory
                                         plus swap: '-1' to enable
                                         unlimited swap
      --memory-swappiness int            Tune container memory

以上为docker run可以使用的限制内存资源的部分。

-m--memory:限制容器可以使用的最大内存总量。例,-m 128m表示限制容器可使用内存为128MB。

--memory-swap:交换空间大小。不设置默认不使用。

--memory-reservation:内存软限制

演示:

?  ~ docker run -dP -m 128m dockerswarmdemo-app:v2
79874665ff0d2998dccbd691c173f53ad1a705503c4d63bbed21e3e74c109f0e
?  ~ docker ps
CONTAINER ID   IMAGE                    COMMAND              CREATED
STATUS          PORTS                                         NAMES
79874665ff0d   dockerswarmdemo-app:v2   "/bin/sh -c ./app"   28 seconds ago   Up 26 seconds   0.0.0.0:32770->3003/tcp, :::32770->3003/tcp   infallible_goldwasser

?  ~ docker stats 79874665ff0d
CONTAINER ID   NAME                    CPU %     MEM USAGE / LIMIT   MEM %     NET I/O          BLOCK I/O   PIDS
79874665ff0d   infallible_goldwasser   0.00%     39.37MiB / 128MiB   30.76%    1.05MB / 883kB   0B / 0B     12

通过docker run添加参数-m 128m,运行了一个基于dockerswarmdemo-app:v2镜像的容器,使用docker stats查看容器占用可以看到MEM USAGE/LIMIT栏的LIMIT部分与-m 128m一致。

?  ~ docker exec -it 79874665ff0d sh
/app # cat /sys/fs/cgroup/memory.max
134217728

在容器内部可以查看到cgroups内存限制配置文件。134217728/1024/1024=128MB

磁盘I/O限制

Block I/O权重 (--blkio-weight): 设置容器块设备I/O的权重,范围是10到1000,影响I/O调度器分配带宽的优先级。

?  ~ docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Create and run a new container from an image
      --blkio-weight uint16              Block IO (relative weight),
                                         between 10 and 1000, or 0 to
                                         disable (default 0)
      --blkio-weight-device list         Block IO weight (relative
                                         device weight) (default [])

--blkio-weight: 磁盘I/O的权重,默认0,范围10-1000,0为关闭。决定在磁盘负载情况下的优先级,1000为最高优先级。

--blkio-weight-device: 针对指定磁盘设置I/O权重。例,--blkio-weight-device 800,/dev/sda,/dev/sda磁盘权重设置为800。

示例:

启动两个容器进行对比测试
docker run -dP --name low-blkio --blkio-weight 10 dockerswarmdemo-app:v2
docker run -dP --name high-blkio dockerswarmdemo-app:v2
分别进入两个容器内的sh
docker exec -it high-blkio|low-blkio sh
镜像dockerswarmdemo-app:v2基于alpine制作
所有,使用apk add --no-cache fio 在2个容器内, 安装fio

在两个容器内同时执行
fio --name=test --ioengine=libaio --iodepth=64 --rw=randwrite --bs=4k --size=1G --numjobs=4 --runtime=60 --time_based --filename=/testfile

high-blkio结果
Run status group 0 (all jobs):
  WRITE: bw=3635KiB/s (3722kB/s), 800KiB/s-1022KiB/s (819kB/s-1047kB/s), io=513MiB (538MB), run=144588-144588msec
  
low-blkio结果
Run status group 0 (all jobs):
  WRITE: bw=391KiB/s (401kB/s), 4B/s-1461KiB/s (4B/s-1496kB/s), io=323MiB (339MB), run=114425-846839msec

high-blkio容器很快执行完了,low-blkio等了十几分钟迟迟未完成执行。通过结果可以看出未被限制的high-blkio拥有更高的磁盘I/O优先级。

通过上述解释和演示,我们了解Docker中如何利用cgroups机制对容器的CPU、内存和磁盘I/O资源进行限制,提供了强大的灵活性和控制能力。在实际部署中,合理配置参数可以保障应用在各种负载条件下都能稳定运行。


读完后,忍不住要加个关注!不是我吹,但你会后悔没关注的!

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表