目录
一、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工具 #将容器数据收集过来持续性查看
③、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
④、限制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使用情况
#或者可以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资源限制的文件