Docker 管理之 --- 资源限制

目录

前言

一、CPU 资源控制

1、cgroup 介绍

2、cgroup 的功能

3、Cgroup子系统

4、CPU使用率控制

5、限制cpu时间周期

5.1  方式1

5.2  方式2

6、设置容器的权重

7、限制容器使用的cpu(指定使用第2第4个)

8、CPU配额控制参数的混合使用

二、内存资源限制

三、磁盘 IO 配额控制

1、创建容器并限制写速度

2、创建容器并限制写次数

3、清理 docker 占用的磁盘空间

四、构建镜像(docker build)时指定资源限制

总结


前言

在使用 docker 运行容器时,默认的情况下,docker没有对容器进行硬件资源的限制,当一台主机上运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制,那么容器之间会互相影响,小的来说会导致容器资源使用不公平;大的来说,可能会导致主机和集群资源耗尽,服务完全不可用。

一、CPU 资源控制

1、cgroup 介绍

 Cgroup 是 Control group 的简称,是 Linux 内核提供的一个特性,用于限制和隔离一组进程对系统资源的使用。对不同资源的具体管理是由各个子系统分工完成的。

2、cgroup 的功能

限制资源使用,比如内存使用上限以及文件系统的缓存限制。

优先级控制,CPU利用和磁盘IO吞吐。

资源统计,主要目的是为了计费。

任务控制,挂起进程,恢复执行进程。

3、Cgroup子系统

blkio 设置限制每个块设备的输入输出控制,例如:磁盘、光盘、usb等等
CPU 使用调度程序为cgroup任务提供CPU的访问
cpuacct 产生cgroup任务的CPU资源报告
cpuset 如果是多核心的CPU,这个子系统会为cgroup任务分配单独的CPU和内存
devices 允许或拒绝cgroup任务对设备的访问
freezer 暂停和恢复cgroup任务
memory 设置每个cgroup的内存限制以及产生内存资源报告
net_cls 标记每个网络包以供cgroup方便使用
ns 命名空间子系统
perf_event 增加了对每个group的检测跟踪能力,可以检测属于某个特定的group的所有线程以及运行在特定CPU上的线程

4、CPU使用率控制

[root@localhost docker]# cat /sys/fs/cgroup/cpu/docker/容器ID/cpu.cfs_quota_us
-1
#-1:代表此容器可以使用得资源不受限制
  • 查看
[root@localhost ~]# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O     PIDS
01e51947aa64   t10       0.00%     82.71MiB / 3.683GiB   2.19%     13.5MB / 272kB   0B / 49.1MB   1

5、限制cpu时间周期

5.1  方式1

假如需要给此容器分配cpu使用率的20%,则参数需要设置为20000,相当于每个周期分配给这个容器0.2s

[root@localhost ~]# docker run -itd --name=t1 --cpu-quota 20000 centos:7 /bin/bash
8167c75eef1a67baaef63e0b8575b9aac91be5ab79edbb51abe7028388f923f2

压力测试

[root@localhost ~]# docker exec -it 8167c75eef1a /bin/bash
[root@8167c75eef1a /]# yum -y install bc
#计算圆周率
[root@8167c75eef1a /]# echo "scale=5000;4*a(1)"| bc -l -q
[root@localhost ~]# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O     PIDS
8167c75eef1a   t1        20.00%    74.42MiB / 3.683GiB   1.97%     13.1MB / 223kB   0B / 47.6MB   3
01e51947aa64   t10       0.00%     82.71MiB / 3.683GiB   2.19%     13.5MB / 272kB   0B / 49.1MB   1

5.2  方式2

[root@localhost ~]# cd /sys/fs/cgroup/cpu/docker/
[root@localhost docker]# echo "20000" > 01e51947aa6402395f05a2573efa48191e3d8b85a67caf1ed58746a44e68d347/cpu.cfs_quota_us

6、设置容器的权重

按比例分配设置容器的权重,此处权重是所有值相加然后看占用百分比

[root@localhost docker]# docker run -itd --name=c1 --cpu-shares 512 centos:7 /bin/bash
4421cdb3f44c091ac88a6538725141a627cf0645b5a8917fab1e2425786fc777
[root@localhost docker]# docker run -itd --name=c2 --cpu-shares 1024 centos:7 /bin/bash
ba70c6b4b47e9d77c47ea750a521a83ffd4438f03303835696d6d25f81554048
#创建以上容器,设置权重。会使用512+1024的合,按占比分配权重

压力测试

[root@localhost ~]# docker exec -it 4421cdb3f44c /bin/bash
[root@4421cdb3f44c /]# yum -y install epel-release   #依赖包
[root@4421cdb3f44c /]# yum -y install stress
[root@ba70c6b4b47e /]# stress -c 4  #模拟4个CPU工作
###容器B操作相同
[root@localhost ~]# docker stats
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O        BLOCK I/O     PIDS
ba70c6b4b47e   c2        269.75%   120.8MiB / 3.683GiB   3.20%     22MB / 440kB   0B / 49.7MB   7
4421cdb3f44c   c1        129.27%   120.9MiB / 3.683GiB   3.21%     22MB / 436kB   0B / 49.8MB   7

7、限制容器使用的cpu(指定使用第2第4个)

[root@localhost ~]# docker run -itd --name=test1 --cpuset-cpus 1,3 centos:7 /bin/bash
5fe80298d3c14087cf9855dcccac0717eebb287588bf9d07786102a03044240a

 压力测试

[root@localhost ~]# docker exec -it 5fe80298d3c1 /bin/bash
[root@5fe80298d3c1 /]# yum -y install epel-release 
[root@5fe80298d3c1 /]# yum -y install stress
##查看
[root@localhost ~]# top
top - 00:45:27 up  3:19,  3 users,  load average: 0.16, 0.08, 0.14
Tasks: 132 total,   3 running, 129 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

8、CPU配额控制参数的混合使用

通过cpuset-cpus参数指定容器A使用CPU内核0,容器B只是用CPU内核1
在主机上只有这两个容器使用对应CPU内核的情况,它们各自占用全部的内核资源,cpu-shares 没有明显效果。
cpuset-cpus. cpuset-mems 参数只在多核、多内存节点上的服务器上有效,并且必须与实际的物理配置匹配,否则也无法达到资源控制的目的。
在系统具有多个CPU内核的情况下,需要通过cpuset-cpus参数为设置容器CPU内核才能方便地进行测试。

docker stop `docker ps -qa`
docker run -itd --name cpu3 --cpuset-cpus 0 --cpu-shares 512 centos:stress stress -c 1

docker run -itd --name cpu4 --cpuset-cpus 2 --cpu-shares 1024 centos:stress stress -c 1

Docker 管理之 --- 资源限制_第1张图片 

Docker 管理之 --- 资源限制_第2张图片 

二、内存资源限制

与操作系统类似,容器可使用的内存包括两部分:物理内存和Swap.
Docker通过下面两组参数来控制容器内存的使用量。

-m或–memory: 设置(物理)内存的使用限额,例如100M、 1024M.
–memory-swap: 设置内存+ swap的使用限额。
执行如”下命令允许该容器最多使用200M的内存和300M的swap

 

docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M

--vm 1:启动一个内存工作线程
--vm-bytes 280M:每个线程分配280M内存

Docker 管理之 --- 资源限制_第3张图片 

默认情况下,容器可以使用主机上的所有空闲内存
与CPU的cgroups配置类似,Docker会自动为容器再目录/sys/fs/cgroup/memory/docker/<容器完整id>中创建相应cgroup配置文件。

如果让线程分配的内存大于等于设定的300M,stress线程报错,容器退出。

docker run -it -m 200M --momory-swap=300M progrium/stress --vm 1 --vm-bytes 300M

Docker 管理之 --- 资源限制_第4张图片 

三、磁盘 IO 配额控制

 –device-read-bps:限制某个设备上的读速度 bps(数据量),单位可以是 kb、mb(M) 或者 gb。
例:docker run -itd --name test1 --device-read-bps /dev/sda:1M centos:7 bash
–device-write-bps:限制某个设备上的写速度 bps(数据量),单位可以是 kb、mb(M) 或者 gb。
例:docker run -itd --name test2 --device-write-bps /dev/sda:1mb centos:7 bash
–device-read-iops:限制读某个设备的 iops(次数)
–device-write-iops:限制写入某个设备的 iops(次数)
 

1、创建容器并限制写速度

[root@docker ~]# docker run -it --name test --device-write-bps /dev/sda:1mb centos:7 bash
[root@d638b2689beb /]# dd if=/dev/zero of=write_test bs=1M count=10 oflag=direct
##添加oflag参数以规避掉文件系统cash
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 10.003 s, 1.0 MB/s

2、创建容器并限制写次数

[root@docker ~]# docker run -itd --name test --device-write-iops /dev/sda:10 centos:7 bash
480096c14d1a13953a03573097826b2c151f63a8942998316a67ba45403e6177
[root@docker ~]# docker inspect test
······
            "BlkioDeviceWriteIOps": [
                {
                    "Path": "/dev/sda",
                    "Rate": 10
                }
            ],
······

3、清理 docker 占用的磁盘空间

清除停止的容器以及未被使用的镜像

[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    87a94228f133   9 hours ago   133MB
centos       7         eeb6ee3f44bd   3 weeks ago   204MB
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED         STATUS                       PORTS     NAMES
8c754e5c5f4f   centos:7   "bash"    6 minutes ago   Up 6 minutes                           test1
480096c14d1a   centos:7   "bash"    7 minutes ago   Exited (137) 5 seconds ago             test
[root@docker ~]# docker system prune -a
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all images without at least one container associated to them
  - all build cache
 
Are you sure you want to continue? [y/N] y
Deleted Containers:
480096c14d1a13953a03573097826b2c151f63a8942998316a67ba45403e6177
 
Deleted Images:
untagged: nginx:latest
untagged: nginx@sha256:b0c17557e2a3a17bcf18498222824312832f69dbf78edab10f08334900bd7fda
deleted: sha256:87a94228f133e2da99cb16d653cd1373c5b4e8689956386c1c12b60a20421a02
deleted: sha256:55b6972054b24c53054322a52748324df5797eefbb6dc374e41522a91d532dd5
deleted: sha256:6b88aa6f4485486bfc779cccfbe4a7a47a502a7cff2cd70be89c59dcd0db12a8
deleted: sha256:472c64059965c7b6b1b534ba07374c1d034b17c99acb3cf4534fe78abed41101
deleted: sha256:788a5cf1e4599312b5923694f53e556ba0e2eb4a6bbb51958e0ec2b510345a49
deleted: sha256:410f31f9ae37c62af85e8f9575c5f4d75542be1739ac1ca5982cf461be0b13bc
deleted: sha256:e81bff2725dbc0bf2003db10272fef362e882eb96353055778a66cda430cf81b
 
Total reclaimed space: 133.3MB
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
centos       7         eeb6ee3f44bd   3 weeks ago   204MB
[root@docker ~]# docker ps -a
CONTAINER ID   IMAGE      COMMAND   CREATED         STATUS         PORTS     NAMES
8c754e5c5f4f   centos:7   "bash"    6 minutes ago   Up 6 minutes    

四、构建镜像(docker build)时指定资源限制

--build-arg=[] :           设置镜像创建时的变量
--cpu-shares :             设置 cpu 使用权重
--cpu-period :             限制 CPU CFS 周期
--cpu-quota :              限制 CPU CFS 配额
--cpuset-cpus :            指定使用的CPU id
--cpuset-mems :            指定使用的内存 id
--disable-content-trust :  忽略校验,默认开启
-f :                       指定要使用的 Dockerfile 路径
--force-rm :               设置镜像过程中删除中间容器
--isolation :              使用容器隔离技术
--label=[] :               设置镜像使用的元数据
-m :                       设置内存最大值
--memory-swap :            设置 Swap 的最大值为内存 +swap,"-1"表示不限 swap
--no-cache :               创建镜像的过程不使用缓存
--pull :                   尝试去更新镜像的新版本
--quiet, -q :              安静模式,成功后只输出镜像 ID
--rm :                     设置镜像成功后删除中间容器
--shm-size :               设置 /dev/shm 的大小,默认值是 64M
--ulimit :                 Ulimit 配置
--squash :                 将 Dockerfile 中所有的操作压缩为一层
--tag, -t:                 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签
--network:                 默认 default。在构建期间设置 RUN 指令的网络模式

总结

资源限制的主要类型
① CPU 权重 shares、quota、cpuset、周期 cpu-period
② 磁盘 BPS、TPS 限制,指定使用哪个磁盘、磁盘分区
③ 内存 -m -swap 内存、交换分区
大部分做的是上限的限制

资源限制的几种方式
① build 构建镜像时,可以指定该镜像的资源限制
② run 将镜像跑为容器的时候,可以指定容器的资源限制
③ 容器启动之后,可以在宿主机对应容器的目录下。修改资源限制,然后重载
/sys/fs/cgroup/*(cpu、blk、mem)/docker/容器ID/--->修改对应的资源限制文件参数就可以

资源限制的状态查询
① docker inspect 镜像ID/容器ID
② 直接查看宿主机对应容器 ID 资源限制的文

 

 

 

 

 

 

 

 

 

 

 
  

 

 

 

 

你可能感兴趣的:(docker,容器,运维)