docker 的资源控制,数据管理,容器互联
一: docker 的资源控制
1.1 CPU资源控制
cgroups ,是一个非常强大的 Linux 内核工具,他不仅可以限制被 namespace 隔离起来的资源,还可以为资源设置权重,计算使用量,操控进程启停等等。
所有cgroups (Control groups) 实现了对资源的配额和度量。
cgroups 有四大功能
- 资源限制: 可以对任务使用的资源总额进行限制
- 优先级分配:通过分配的 cpu 时间片数据以及磁盘IO 带宽大小,实际上相当于控制了任务运行优先级
- 资源统计:可以统计系统的资源使用量,如cpu 时长,内存使用等
- 任务控制: cgroup 可以对任务执行挂起,恢复等操作
1.1.1 设置cpu 使用率上限
Linux 通过CFS(Complete Fair Scheduler,完全公平调度器) 来调度各个进程对cpu的使用。CFS默认的调度器周期100ms,我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少CPU时间.
使用 --cpu-period 即可设置调度周期,使用--cpu-quota 即可设置在每个周期内容器能使用的cpu 时间。两者可以配合使用。而容器的CPU 配额必须不小于 1ms ,即 --cpu-quota 的额度必须 >=1000.
[root@host103 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed597b354adf centos:7 "bash" 21 seconds ago Up 19 seconds test1
[root@host103 ~]# cd \
/sys/fs/cgroup/cpu/docker/ed597b354adf3d4cfd1b572cedb5d106077bcf62a31df44bc8aac3aa3deb5d1b/
[root@host103 ed597.....]# cat cpu.cfs_quota_us
-1
[root@host103 ed597.....]# cat cpu.cfs_period_us
100000
cpu.cfs_quota_us: 表示 cgroups 限制占用时间(微秒)默认为 -1 ,表示不限制
cpu.cfs_period_us: cpu 分配的周期(微秒,所以文件中用 us 表示),默认为 100000
如果设置为 50000 ,表示占用 50000/100000= 50% cpu
1.1.2 进行CPU 压力测试
[root@host103 ~]# docker exec -it test1 /bin/bash
[root@ed597b354adf /]# vi cpu.sh
#!/bin/bash
i=0
while true
do
let i++
done
[root@ed597b354adf /]# chmod +x /cpu.sh
[root@ed597b354adf /]# ./cpu.sh
1.1.3 设置cpu 使用时间上限
[root@host103 ~]# cd /sys/fs/cgroup/cpu/docker/ed59...../
[root@host103 ed59.....]# echo 50000 > cpu.cfs_quota_us
[root@host103 ed59.....]# top
1.1.4 设置cpu 资源占比(多个容器时才有效)
docker 通过 --cpu-shares 指定CPU 份额,默认值为1024 ,值为1024 的倍数。
#先停止和删除之前容器
[root@host103 ~]# docker kill $(docker ps -aq)
[root@host103 ~]# docker rm $(docker ps -aq)
#创建两个容器为c1 ,c2 若只有这两个容器,设置容器的权重,使得c1和c2的cpu资源占比为 1/3和2/3
[root@host103 ~]# docker run -itd --name c1 --cpu-shares 1024 centos:7
47fa6089f568e616cba8cf05bf22279bd7ff0602cf31d4d685e3a37d4bd27d85
[root@host103 ~]#
[root@host103 ~]# docker run -itd --name c2 --cpu-shares 2048 centos:7
25d0d2229f4ea05b5a290fd0a96f364b071826700826378b596e5cdf38f5e72c
#分别进入容器,进行压力测试
[root@host103 ~]# docker exec -it c1 bash
[root@47fa6089f568 /]# yum -y install epel-release
[root@47fa6089f568 /]# yum -y install stress
#产生4个进程,每个进程都反复不听的精算随机数的平方根
[root@47fa6089f568 /]# stress -c 4
[root@host103 ~]# docker exec -it c2 bash
[root@25d0d2229f4e /]# yum -y install epel-release
[root@25d0d2229f4e /]# yum -y install stress
#产生4个进程,每个进程都反复不听的精算随机数的平方根
[root@25d0d2229f4e /]# stress -c 4
#查看容器运行状态(动态更新)
[root@host103 ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
25d0d2229f4e c2 260.34% 137.2MiB / 1.938GiB 6.92% 27.8MB / 484kB 25.3MB / 25.3MB 7
47fa6089f568 c1 140.19% 111.8MiB / 1.938GiB 5.63% 27.5MB / 416kB 58.1MB / 25.3MB 7
1.1.5 指定容器绑定cpu
#配置容器使用编号为 1,3 的CPU(cpu编号从0开始)
[root@host103 ~]# docker run -itd --name test3 --cpuset-cpus 1,3 centos:7 bash
90666bf2833d3b93bbcc043c66b5dff3f76ca43057aaacd3867d3d47f7e2d640
#进入容器,进行压力测试
[root@host103 ~]# docker exec -it test3 bash
[root@90666bf2833d /]# yum -y install epel-release
[root@90666bf2833d /]# yum -y install stress
[root@90666bf2833d /]# stress -c 4
#先使用top 命令,在按下1 ,查看CPU的使用情况
[root@host103 ~]# top
1.2 对内存使用的限制
-m (--memory=) 选项用于限制容器可以使用的最大内存
--memory-swap 和 --memory 一起使用可以限制swap 的大小。
正常情况下,--memory-swap 的值包含容器的可用内存和可用swap。
所以,-m 300m --memory-swap=1g 的含义为: 容器可以使用300M的物理内存,并且可以使用 700M(1G-300M)的swap
- 如果 --memory-swap 设置为0或者 不设置,则容器可以使用swap 大小为 -m 值的两倍
- 如果 --memory-swap 的值和 -m 值相同,则容器不能使用 swap
- 如果 --memory-swap 的值为 -1 ,它表示容器程序使用的内存受限,而可以使用的swap空间不受限制(宿主机有多少swap,容器就可以使用多少)
1.3 对磁盘IO 配置控制的限制
--device-read-bps: 限制某个设备上的读速度 bps(数据量),单位可以是kb,mb(M)或者gb。
eg: docker run -itd --name test --device-read-bps /dev/sda:1M centos:7 /bin/bash
--device-write-bps: 限制某个设备上的写速度(数据量),单位可以是kb,mb(M)或者gb。
eg: docker run -itd --name test --device-write-bps /dev/sda:1M centos:7 /bin/bash
--device-read-iops : 限制读某个设备的iops(次数)
--device-write-iops: 限制写入某个设备iops(次数)
#创建容器,并限制写速度
[root@host103 ~]# docker run -it --name test4 --device-write-bps /dev/sda:1mb centos:7 bash
#通过dd来验证写速度
[root@98dbd982b24c /]# dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 10.0035 s, 1.0 MB/s
二: 数据管理
管理Docker 容器中数据主要有两种方式:数据卷(Data Volumes) 和数据卷容器(DataVolumes Containers)。
2.1 数据卷
数据卷是一个供容器使用的特殊目录,位于容器中,可将书主机的目录挂载到数据卷上,对数据卷的修改操作立即可见 ,并且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移。数据卷使用类似于Linux下对目录进行的mount操作。
#当前宿主机没有/var/www目录
[root@host103 ~]# ls /var/www
ls: 无法访问/var/www: 没有那个文件或目录
#宿主机目录/var/www 挂载到容器中/data1.
#注意:宿主机本地目录的路径必须是使用绝对路径。如果路径不存在,Docker 会自动创建相应的路径.
#-v 选项可以在容器内创建数据卷
[root@host103 ~]# docker run -v /var/www:/data1 --name web1 -it centos:7 bash
#docker 容器里有了 data1目录
[root@d66def26bb22 /]# ls
anaconda-post.log data1 etc lib media opt root sbin sys usr
bin dev home lib64 mnt proc run srv tmp var
[root@d66def26bb22 /]# echo "this is web 1" >> /data1/web1.txt
[root@d66def26bb22 /]# exit
exit
#宿主机有了/var/www,并且该目录下有了web1.txt,且有内容
[root@host103 ~]# cat /var/www/web1.txt
this is web 1
2.2 数据卷容器
如果需要在容器之间共享一些数据,最简单的方法就是使用数据卷容器。数据卷容器是一个普通的容器,专门提供数据卷给其他容器挂载使用
#创建一个容器作为数据卷容器
[root@host103 ~]# docker run --name web2 -v /data1 -v /data2 -it centos:7 bash
[root@63ec486d5683 /]# ls
anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@63ec486d5683 /]# echo "this is web2 data1" > /data1/abc.txt
[root@63ec486d5683 /]#
[root@63ec486d5683 /]# echo "this is web2 data2" > /data2/ABC.txt
[root@63ec486d5683 /]#
[root@63ec486d5683 /]# cat /data1/abc.txt
this is web2 data1
[root@63ec486d5683 /]# cat /data2/ABC.txt
this is web2 data2
#使用 --volumes-from 挂载web2 容器中的数据卷到新容器
[root@host103 ~]# docker run -it --volumes-from web2 --name web3 centos:7 bash
[root@bdbbd457daea /]# ls
anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@bdbbd457daea /]# ls data1 data2
data1:
abc.txt
data2:
ABC.txt
[root@bdbbd457daea /]# cat data1/abc.txt
this is web2 data1
[root@bdbbd457daea /]# cat data2/ABC.txt
this is web2 data
2.3 容器互联(使用centos 镜像)
容器互联是通过容器的名称在容器间建立一条专门的网络通信隧道。简单点说,就是会在源容器和接收器之间建立一条隧道,接收容器可以看到源容器指定的信息
#创建并运行容器,取名为web4
[root@host103 ~]# docker run -itd -P --name web4 centos:7 bash
bc1caf5b2f441c834e70eb3307dab72bdb597568e1af6070f2b45f1cf8d9196e
[root@host103 ~]#
#创建并运行容器,取名为web5. --link 容器名:连接的别名
[root@host103 ~]# docker run -itd --name web5 --link web4:WEB4 centos:7 bash
107f5c583c1db9c456c47952081a084efd66de762a905f471776dd65949bb892
[root@host103 ~]#
#进入容器,ping 容器名,ping 别名,都可以ping通
[root@host103 ~]# docker exec -it web5 bash
[root@107f5c583c1d /]# ping web4
[root@107f5c583c1d /]# ping WEB4