目录

一、registry私有仓库建立

1、下载私有仓库镜像

2、创建私有仓库、并上传镜像包到仓库

二、cgroup资源控制

1、stress压力测试工具

2、对CPU的控制

3、对内存使用的限制

4、Block IO 的限制

5、bps 和 iops 的限制

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

总结


一、registry私有仓库建立

1、下载私有仓库镜像

[root@docker ~]# docker pull registry

[root@docker ~]# vim /etc/docker/daemon.json
#在docker引擎终端设置,创建并添加如下内容
{
 "insecure-registries":["192.168.35.70:5000"],   #私有仓库ip和默认端口
 "registry-mirrors": ["https://t466r8qg.mirror.aliyuncs.com"]  #加速地址
}

[root@docker ~]# systemctl daemon-reload   #重启守护进程
[root@docker ~]# systemctl restart docker   #重启docker

2、创建私有仓库、并上传镜像包到仓库

#创建私有仓库容器,并映射端口,让宿主机的/data/registry自动创建挂载容器中的/tmp/registry
[root@docker ~]# docker run -d -p 5000:5000 -v /data/registry:/tmp/registry registry 

[root@docker ~]# docker create -it registry /bin/bash  #创建私有仓库
6d83421169a5d153c739f91d7cd56e671eff26f0c2d9d41a7572250dc35846ae
[root@docker ~]# docker start 6d83421169a5   #注意,直接创建启动会是异常状态
6d83421169a5
[root@docker ~]# docker ps -a   #查看,现在是异常退出状态
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS    PORTS     NAMES
6d83421169a5   registry   "/entrypoint.sh /bin…"   26 seconds ago   Created             kind_kilby
#打包nginx镜像并更改标记为192.168.110.133:5000/nginx
[root@docker ~]# docker tag nginx:latest 192.168.110.133:5000/nginx
#上传镜像到我们创建的私有仓库,服务器会加载daemon.json文件,然后执行里面的程序,默认将上传文件放到私有仓库。
[root@docker ~]# docker push 192.168.110.133:5000/nginx
#获取registry的镜像仓库中的镜像信息,获取私有仓库镜像列表
[root@docker ~]# curl -XGET http://192.168.110.133:5000/v2/_catalog
{"repositories":["nginx"]}   #已有仓库以及仓库中的镜像nginx
#从私有仓库下载镜像
[root@docker ~]# docker pull 192.168.35.70:5000/nginx

二、cgroup资源控制

       cgroup是Linux内核提供的一种限制所使用物理资源的机制,这些资源主要包括CPU、内存、

blkio。Docker通过Cgroup来控制容器使用的资源配额,包括CPU、内存、磁盘三大方面,基本覆

盖了常见的资源配额和使用量控制。

1、stress压力测试工具

用来测试CPU和内存的使用情况。

这里我们使用使用 Dockerfile 来创建一个基于Centos 的stress工具镜像

[root@docker ~]# mkdir  /opt/stress
[root@docker ~]# cd /opt/stress/
[root@docker stress]# ls
[root@docker stress]# vim Dockerfile
                                                                                                 
FROM centos:7
RUN yum install -y wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum -y install stress

[root@docker stress]# docker build -t centos:stress   #生成sress镜像

2、对CPU的控制

        cpu周期: 1s为一个周期的定律,参数值一般为100000 (CPU衡量单位是秒),假如需要给此容

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

个时刻,只能给一个进程占用。CPU的百分比是以1000为单位的。

①、限制CPU使用速率

        容器获得资源的分配比例;用来指定在这个周期内,最多可以有多少时间用来跑这个容器,

这种配置是指定一个绝对值,容器对CPU资源的使用绝对不会超过配置的值。

方法一:
docker通--cpu-quota选项来限制CPU的使用速率。
[root@docker ~]# docker run --cpu-quota 20000 容器名  #CPU的使用率限定为20%  

方法二:
修改对应的配置文件,/sys/fs/cgroup/cpu/docker/容器编号/cpu.cfs_quota_us的值来实现,使用echo命令将设定值导入此文件就会立即生效。
[root@docker ~]# echo 20000 > /sys/fs/cgroup/cpu/docker/ 989c4313b4dde279cbb0cb2c5db4f8584260bc2f4238de380f8b4e97871f17b4/ cpu.cfs_quota_us
[root@docker ~]#

②、多任务按比例分享CPU

cgroups-优先级/权重限制

使用如下命令创建容器,命令中的–cpu-shares参数值不能保证可以获得1个vcpu或者多少GHz的

CPU资源,它仅是一个弹性的加权值。默认情况下,每个Docker容器的CPU份额都是1024。单独

一个容器的份额是没有意义的。只有在同时运行多个容器时,容器的CPU加权的效果才能体现出来

[root@docker stress]# docker run -itd --cpu-shares 100 centos:stress

        只在容器分配的资源紧缺时,即在需要对容器使用的资源进行限制时,才会生效。因此,无

法单纯根据某个容器的CPU份额来确定有多少CPU资源分配给它,资源分配结果取决于同时运行

的其他容器的CPU分配和容器中进程运行情况。

可以通过--cpu-share选项设置容器按比列共享CPU资源,这种方法还可以实现CPU使用率的动态

调整,如下启动了两个容器及运行查看CPU使用百分比。

docker run -tid --name cpu512 --cpu-shares 512 centos:stress stress -c 10		##容器产生10个子函数进程
docker run -tid --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10		##再开启一个容器做比较

docker exec -it 5590c57d27b0 bash  //进容器使用top对比两个容器的8CPU,比例是1:2
或者
docker stats 查看资源使用
或者
cadvisor工具  #将容器数据收集过来持续性查看

docker 自建registry v2_centos

③、CPU周期限制

Docker提供了**--cpu-period、--cpu-quota** 两个参数控制容器可以分配到的CPU时钟周期。cpu-period 和cpu-quota 参数一般联合使用。

--cpu-period 是用来指定容器对CPU的使用要在多长时间内做一次重新分配

--cpu-quota:容器获得资源的分配比例;

参数的单位:

cpu-period和cpu-quota 的单位为微秒(μs)。

cpu-period 的最小值为1000微秒,最大值为 1秒(10^6μs),默认值为0.1秒(100000 μs)

cpu-quota的值默认为-1,表示不做控制(不做任何限制)

例如

容器进程需要每1秒使用单个CPU的0.2秒时间,可以将cpu-period 设置为1000000 (即1秒),cpu-

quota 设置为200000 (0.2秒)。

当然,在多核情况下,如果允许容器进程完全占用两个CPU,则可以将cpu-period 设置为100000

(即0.1秒),cpu-quota设置为200000 (0.2秒)。

查询资源限制的方式有2种:

[root@docker docker]# docker run -itd --name test01 --cpu-period 100000 --cpu-quota 200000 centos:stress
860dba7cae05cdbaa113e5a86ec03e6d1e2ab4b25f1c743e17816000d0376c40
[root@docker docker]# docker exec -it test01 bash
[root@860dba7cae05 /]# cd /sys/fs/cgroup/cpu/ 
[root@860dba7cae05 cpu]# ls
cgroup.clone_children  cpu.cfs_period_us  cpu.rt_runtime_us  cpuacct.stat          notify_on_release
cgroup.event_control   cpu.cfs_quota_us   cpu.shares         cpuacct.usage         tasks
cgroup.procs           cpu.rt_period_us   cpu.stat           cpuacct.usage_percpu
[root@860dba7cae05 cpu]# cat cpu.cfs_period_us 
100000
[root@860dba7cae05 cpu]# cat cpu.cfs_quota_us  
200000
[root@860dba7cae05 cpu]#
#注:也可以使用docker inspect 容器id/容器名在详细信息中查看cpu资源的硬限制。
[root@docker docker]# docker inspect test01

docker 自建registry v2_centos_02

④、限制CPU内核使用

docker可以使用--cpuset-cpus选项来使某些程序独享cpu内核,以便提高其处理速度,对应的

cgroup配置文件为/sys/fs/cgroup/cpu/docker/容器编号/cpuset-cpus。该选项后直接跟0、1、2……

表示第1个内核、第2个内核、第3个内核

与/proc/cpuinfo中的CPU编号相同。

◆限制方法一:

#创建容器时直接使用参数指定资源限制
[root@docker docker]# docker run -itd --name cpu01 --cpuset-cpus 0-1 centos:stress
#执行以上命令需要宿主机为双核,表示创建的容器只能用0、1两个内核。最终生成的cgroup 的CPU内核配置如下:
[root@docker ~]# docker exec -it cpu01 /bin/bash -c "stress -c 10"  #模拟容器子任务
#接着,打开新会话连接,执行top进入视图,输入数字1查看各逻辑cpu使用情况

docker 自建registry v2_docker_03

#或者可以cat /sys/fs/cgroup/cpuset/docker/容器id/cpuset.cpus查看
[root@docker ~]# cd /sys/fs/cgroup/cpuset/docker/

[root@docker docker]# cd 5f5b2d07e6bbb8655db6cef030c816282b5c0e8df2c0cd466d3d86c644f9303a

[root@docker 5f5b2d07e6bbb8655db6cef030c816282b5c0e8df2c0cd466d3d86c644f9303a]# cat cpuset.cpus
0-1

◆限制方法二:

创建容器后,指定资源分配

修改宿主机对应容器资源控制的文件,位置:/sys/fs/cgroup/**目录下修改对应的文件参数,

echo “1-2” > /sys/fs/cgroup/cpuset/docker/容器id/cpuset.cpus

⑤、cpu配额控制参数的混合使用

通过cpuset-cpus 参数指定容器A使用CPU内核0,容器B只使用CPU内核1。

在主机上只有这两个容器使用对应CPU内核的情况,它们各自占用全部的内核资源,cpu-shares没

有明显效果。

cpuset-cpus、cpuset-mems 参数只在多核、多内存节点上的服务器上有效,并且必须与实际的物

理配置匹配,否则也无法达到资源控制的目的。

在系统具有多个CPU内核的情况下,需要通过cpuset-cpus 参数为设置容器CPU 内核才能方便地

进行测试。

#注意宿主虚拟机CPU核心为4核心
[root@docker stress]# docker run -itd --name cpu03 --cpuset-cpus 1 --cpu-shares 512 centos:stress stress -c 1dd8d3479977ea2eed4a7d337d122cbc973ba8ca002ef3ceef92c5acbe8324820
[root@docker stress]# docker ps -a
CONTAINER ID   IMAGE           COMMAND         CREATED          STATUS          PORTS     NAMES
dd8d3479977e   centos:stress   "stress -c 1"   11 seconds ago   Up 10 seconds             cpu03
[root@docker stress]# docker exec -it dd8d3479977e bash
[root@dd8d3479977e /]# top    #按1查看每个核心的占用cpu3的资源
top - 05:53:04 up 9 min,  0 users,  load average: 0.61, 0.18, 0.10
Tasks:   4 total,   2 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.0 us,  0.0 sy,  0.0 ni,100.0 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  :  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1863248 total,   683592 free,   571392 used,   608264 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used.  1124336 avail Mem 
……
  
[root@docker stress]# docker run -tid --name cpu04 --cpuset-cpus 3 --cpu-shares 1024 centos:stress stress -c 1
6deb05f32ddb64b041a1c5f480be65b052e1242bfdbcb22e8cdd8b83c5e41529
[root@docker stress]# docker ps -a
CONTAINER ID   IMAGE           COMMAND         CREATED         STATUS         PORTS     NAMES
6deb05f32ddb   centos:stress   "stress -c 1"   8 seconds ago   Up 7 seconds             cpu04
dd8d3479977e   centos:stress   "stress -c 1"   4 minutes ago   Up 4 minutes             cpu03
[root@docker stress]# docker exec -it 6deb05f32ddb bash
[root@6deb05f32ddb /]# top
top - 05:57:28 up 13 min,  0 users,  load average: 1.57, 0.83, 0.38
Tasks:   4 total,   2 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.0 us,  0.0 sy,  0.0 ni,100.0 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
KiB Mem :  1863248 total,   674008 free,   580556 used,   608684 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used.  1115092 avail Mem
……
[root@docker stress]# docker run -itd --name cpu05 --cpuset-cpus 3 --cpu-shares 512 centos:stress stress -c 1    #仍使用cpu3
6a4089e114f86e23e54604b2578c846953026c2c6769cae28f62cbed716c5ff1
[root@docker stress]# docker ps -a 
CONTAINER ID   IMAGE           COMMAND         CREATED          STATUS          PORTS     NAMES
6a4089e114f8   centos:stress   "stress -c 1"   7 seconds ago    Up 7 seconds              cpu05
dd560ca14aed   centos:stress   "stress -c 1"   26 seconds ago   Up 25 seconds             cpu04
[root@docker stress]# docker exec -it 6a4089e114f8 bash
[root@6a4089e114f8 /]# top
top - 06:07:30 up 23 min,  0 users,  load average: 0.93, 0.87, 0.72
Tasks:   4 total,   2 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.0 us,  0.0 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu1  :  0.0 us,  0.0 sy,  0.0 ni,100.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
KiB Mem :  1863248 total,   667660 free,   584476 used,   611112 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used.  1110904 avail Mem
……
[root@docker stress]# docker stats  #查看cpu04和cpu05的资源使用

CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT   MEM %     NET I/O     BLOCK I/O   PIDS
6a4089e114f8   cpu05     33.20%    128KiB / 1.777GiB   0.01%     656B / 0B   0B / 0B     2
dd560ca14aed   cpu04     66.99%    144KiB / 1.777GiB   0.01%     656B / 0B   0B / 0B     2

结论:

        上面的 centos:stress 镜像安装了 stress 工具,用来测试 CPU 和内存的负载。通过 在两个容

器上分别执行 stress -c 1 命令,将会给系统一个随机负载,产生 1 个进程。这个进程都反复不停

的计算由 rand() 产生随机数的平方根,直到资源耗尽。

观察到宿主机上的 CPU 使用率,第三个内核的使用率接近 100%, 并且一批进程的 CPU 使用率

明显存在 2:1 的使用比例的对比。

3、对内存使用的限制

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

参数来控制容器内存的使用量。默认情况下,容器可以使用主机上的所有空闲内存。与 CPU 的

cgroups 配置类似, Docker 会自动为容器在目录 /sys/fs/cgroup/memory/docker/<容器的完整长

ID>创建相应 cgroup 配置文件。

-m 或 --memory:设置内存的使用限额,例如 100M、1024M。 
--memory-swap:设置 内存+swap 的使用限额,即最大值

#执行如下命令允许该容器最多使用 200M 的内存和 300M 的 swap。
--vm 1:启动 1 个内存工作线程。 
--vm-bytes 280M:每个线程分配 280M 内存。
[root@docker stress]# docker run -it -m 200M --memory-swap=300M  progrium/stress  --vm 1 --vm-bytes 280M
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [7] forked
stress: dbug: [7] allocating 293601280 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 293601280 bytes
stress: dbug: [7] allocating 293601280 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
cstress: dbug: [7] freed 293601280 bytes
stress: dbug: [7] allocating 293601280 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
……
[root@docker stress]# docker run -it -m 200M --memory-swap=300M  progrium/stress  --vm 1 --vm-bytes 320M
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [8] forked
stress: dbug: [8] allocating 335544320 bytes ...
stress: dbug: [8] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) <-- worker 8 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 1s
[root@docker stress]#   #注意这里,让工作线程分配的内存超过 300M,分配的内存超过内存+swap和的使用限额,stress 线程报错,容器 退出。

4、Block IO 的限制

默认情况下,所有容器能平等地读写磁盘,可以通过设置--blkio-weight 参数来改变 容器 block IO

的优先级。

--blkio-weight 与 --cpu-shares 类似,设置的是相对权重值,默认为 500。

#容器 A 读写磁盘的带宽是容器 B 的两倍。
[root@docker stress]#  docker run -it --name container_A --blkio-weight 600 centos:stress
[root@c53b9a03b499 /]# cat /sys/fs/cgroup/blkio/blkio.weight
600
[root@c53b9a03b499 /]# exit
exit
[root@docker stress]# docker run -it --name container_B --blkio-weight 300 centos:stress
[root@84cf8998f1b4 /]# cat /sys/fs/cgroup/blkio/blkio.weight
300
[root@84cf8998f1b4 /]#
#也可以重新开启一个连接,在 /sys/fs/cgroup/blkio/docker/容器编号/ 目录下

 注:查看cat blkio.weight也可以查询。注意是在容器运行的时候查看。

5、bps 和 iops 的限制

控制磁盘的实际IO

bps 是 byte per second,每秒读写的数据量。 按每秒读取块设备的数据量设定上限

iops 是 io per second,每秒 IO 的次数。 按照每秒读操作次数设定.上限

可通过以下参数控制容器的 bps 和 iops:

--device-read-bps,限制读某个设备的 bps。

--device-write-bps,限制写某个设备的 bps。

--device-read-iops,限制读某个设备的 iops。

--device-write-iops,限制写某个设备的 iops。

        通过 dd 命令测试在容器中写磁盘的速度。因为容器的文件系统是在 host /dev/sda 上 的,在

容器中写文件相当于对 host /dev/sda 进行写操作。另外,oflag=direct 指定用 direct IO 方式写文

件,这样 --device-write-bps 才能生效。

[root@docker stress]# docker run -it --device-write-bps /dev/sda:5MB centos:stress  #限制容器写/dev/sda 的速率为5MB/s
[root@c585c84c32a9 /]#  dd if=/dev/zero of=test bs=1M count=100 oflag=direct  #可以按ctrl+c中断查看

^C45+0 records in
45+0 records out
47185920 bytes (47 MB) copied, 9.00077 s, 5.2 MB/s   #使用9.00077 s复制47 M,速度为5.2M/s
[root@c585c84c32a9 /]#
#以上结果表明限速 5MB/s 左右。作为对比测试,如果不限速,结果如下。
[root@docker stress]# docker run -it centos:stress
[root@a72bcdf887df /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.748743 s, 1.4 GB/s
[root@a72bcdf887df /]#

结论:我们不对容器写如磁盘的速度做限制,明显速度快很多。

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

以上都是通过命令行去创建,也可以通过构建镜像时指定。

参数

详解

–build-arg=[ ]

设置镜像创建时的变量

–cpu-shares

设置cpu使用权重

—cpu-period

限制CPU CFS周期

–cpu-quota

限制CPU CFS配额

–cpuset-cpus

指定使用的CPUid

–cpuset-mems

指定使用的内存id

–disable-content-trust

忽略校验,默认开启

#NAME?

指定要使用的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指令的网络模式

总结

1、资源限制的主要类型

①、CPU权重shares、quota、 cpuset (周期cpu-period )

②、磁盘BPS、TPS限制,指定使用哪个磁盘、磁盘分区

③、内存-m -swap内存、交换分区

大部分做的是上限的限制

2、资源限制的几种方式

①、build构建镜像时,可以指定该镜像的资源限制

②、run将镜像跑为容器的时候,可以指定容器的资源限制I

③、容器启动之后,可以在宿主机对应容器的目录下。修改资源限制,然后重载

/sys/fs/cgroup/* (cpu、blk、mem) /docker/ 容器ID/ --->修 改对应的资源限制文件参数就可以

3、资源限制的状态查询

①、docker inspect 镜像ID/容器ID

②、直接查看宿主机对应容器ID资源限制的文件