1. 问题
随着项目开发进度的推移,容器挂载到宿主机中的volume大小可能会增加,甚至占满本地文件系统。我们应采取何种方式控制docker volume数据卷容量大小呢?
2. 解决
2.1 几个概念:docker文件系统、镜像与容器、UFS与volume
Docker镜像是由多个文件系统(只读层)叠加而成。当我们启动一个容器的时候,Docker会加载镜像层并在其上添加一个读写层。如果运行中的容器修改了现有的一个已存在的文件,那么该文件将会从读写层下的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失。
在Docker镜像中,只读层以及在顶部的读写层组合,被称为Union FIle System(联合文件系统)。
为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念。简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,以正常的文件或者目录形式存在于宿主机上。
2.2 清理
- 发现大文件
在当前文件夹中,查找100M以上的文件,并升序输出
# find . -type f -size +100M -print0 | xargs -0 du -h | sort -nr
- 清空大文件内容
从上述输出中,找出大文件,内容置0
# cat /dev/null > /path/to/file_name
注意,只是把文件内容置0,而非删除文件。
通过大文件查找,我们可以获取大文件的目标路径,但是清理过后,volume中的测试数据可能还会涨满。如何限制volume的大小呢?
2.3 指定Volume大小的两种方式
- 创建docker volume,指定大小,再指定容器挂载卷。
# docker volume create -d local -o type=tmpfs -o device=tmpfs -o o=size=2m,uid=1000 --name my_test_volume_01
# docker volume inspect my_test_volume_01
[
{
"Name": "my_test_volume_01", # 这个才是你在-v里的参数
"Driver": "local",
"Mountpoint": "/opt/docker/graph/volumes/my_test_volume_01/_data", # 这个是实际数据存储,你可以在宿主机里直接读取容器里volume的数据,但不是在你-v里的参数
"Labels": {},
"Scope": "local"
}
]
# docker run -it --rm --name test01 --hostname test01 -v my_test_volume_01:/mytest centos:7.3.1611 bash
// 在容器命令行,尝试向volume里面填充数据,但最后只能写入2M
$# cd /mytest
$# dd if=/dev/zero of=/mytest/my01.img bs=1M count=10
同理,也可以在docker-compose.yml、dockerfile中指定已经创建的volume。
- 映射本地文件系统
# mkdir /run/my_test_volume_01 // 宿主机挂载目录
# mount tmpfs /run/my_test_volume_01 -t tmpfs -o rw,size=2m,uid=1000
// 使用-v选项,把这个文件系统挂载给容器
# docker run -it --rm --name test01 --hostname test01 -v /run/my_test_volume_01:/mytest centos:7.3.1611 bash
同理,也可以在docker-compose.yml、dockerfile中指定已经创建的volume。