一 引入问题
除了控制容器的磁盘的容量之外,还应该对容器的磁盘性能进行限制,防止影响到其他容器。
在介绍示例之前,先来复习一个知识
衡量磁盘性能的两个常见的指标
- IOPS :英文全称 Input/Output Operations Per Second ,翻译过来就是每秒钟磁盘读写的次数,这个数值越大,当然也就表示性能越好。
-
BPS(Throughput吞吐量,有时候也被称为带宽Bandwidth,简称 BW):是指每秒钟磁盘中数据的读取量,一般以 MB/s 为单位。这个读取量可以叫作吞吐量
IOPS与吞吐量直接的关系,可以简单的大概理解为:吞吐量 = 数据块大小 *IOPS
从上面的简略公式中可以看出来,如果IOPS固定,那么数据库越大,吞吐量自然越大
示例:下面示例中用 fio 测试的结果中就包含了带宽BW
# 1、制作镜像
[root@test04 ttt]# cat Dockerfile
FROM centos:7
RUN yum install fio -y
CMD tail -f /dev/null
[root@test04 ttt]# docker build -t fiotest:v1.0 ./
# 2、容器文件系统并不适合频繁的写,对于频繁的写入操作,应该为其关联一个volume,volume可以是一个本次磁盘,也可以是一个网络磁盘
[root@test04 ~]# mkdir /tmp/test1
[root@test04 ~]# mkdir /tmp/test2
[root@test04 ~]# mkdir /tmp/test3
[root@test04 ~]# docker container run -d --name test1 -v /tmp/test1:/tmp/test1 fiotest:v1.0 tail -f /dev/null
[root@test04 ~]# docker container run -d --name test2 -v /tmp/test2:/tmp/test2 fiotest:v1.0 tail -f /dev/null
[root@test04 ~]# docker container run -d --name test3 -v /tmp/test3:/tmp/test3 fiotest:v1.0 tail -f /dev/null
# 3、先测试,只有一个容器在写的时候的带宽情况
[root@test04 ttt]# docker exec -ti test1 sh
sh-4.2# fio -name=mytest1 -direct=1 -rw=write -bs=4k -size=2G -ioengine=libaio -iodepth=64 -thread -numjob=1 -filename=/tmp/test1/test1.txt
输出:write: IOPS=21.5k, BW=83.8MiB/s (87.9MB/s)(2048MiB/24431msec)
代表此IOS为21.5k,带宽(BW)是83.8MiB/s左右
# 4、然后测试,3个容器同时在写的时候各自的带宽情况
强调,如果你要同时测试,请保证内存剩余充足,否则同时测试fio的过程中,可能会出现总有一个被killed的情况
强调,如果你要同时测试,请保证内存剩余充足,否则同时测试fio的过程中,可能会出现总有一个被killed的情况
强调,如果你要同时测试,请保证内存剩余充足,否则同时测试fio的过程中,可能会出现总有一个被killed的情况
强调,如果你要同时测试,请保证内存剩余充足,否则同时测试fio的过程中,可能会出现总有一个被killed的情况
强调,如果你要同时测试,请保证内存剩余充足,否则同时测试fio的过程中,可能会出现总有一个被killed的情况
下面3个fio测试要同时执行
[root@test04 ttt]# docker exec -ti test1 sh
sh-4.2# fio -name=mytest1 -direct=1 -rw=write -bs=4k -size=2G -ioengine=libaio -iodepth=64 -thread -numjob=1 -filename=/tmp/test1/1.txt
输出:write: IOPS=10.3k, BW=40.4MiB/s (42.4MB/s)(2048MiB/50693msec)
[root@test04 ttt]# docker exec -ti test2 sh
sh-4.2# fio -name=mytest2 -direct=1 -rw=write -bs=4k -size=2G -ioengine=libaio -iodepth=64 -thread -numjob=1 -filename=/tmp/test2/2.txt
输出:write: IOPS=9763, BW=38.1MiB/s (39.0MB/s)(2048MiB/53700msec)
[root@test04 ttt]# docker exec -ti test3 sh
sh-4.2# fio -name=mytest3 -direct=1 -rw=write -bs=4k -size=2G -ioengine=libaio -iodepth=64 -thread -numjob=1 -filename=/tmp/test3/3.txt
输出:write: IOPS=11.5k, BW=44.7MiB/s (46.9MB/s)(2048MiB/45774msec)
可以看到,当多个容器同时进行写操作时,IOS与BW带宽都会下降
补充
在linux内核4.15之后,为了OverlayFS添加了自己的read/write接口,从而不再直接调用OverlayFS后端文件系统如XFS或Ext4的读写接口,但也只实现了同步I/O(sync I/O),没有实现异步I/O,如果我们用fio工具去测试文件系统性能,若采用异步io模式,在linux5.4内核上就无法测试OverlayFS的最高性能指标。
OverlayFS 在 Linux 内核中还在不断的完善中,linux5.6内核通过打补丁的方式修复了上述问题
二 基于Cgroup v1限制容器磁盘IO
我们可以用Cgroups机制限制容器的cpu、内存资源使用,同样可以用它来限制容器的磁盘性能
具体如何限制,需要分cgroup v1与cgroup v2两个版本来看
Cgroup v1 中有 blkio 子系统,它可以来限制磁盘的 I/O,blkio cgroup的虚拟机文件系统挂载点通常在"/sys/fs/cgroup/blkio/",有四个重要参数