Docker 学习 | 第四篇:数据卷管理
前言
本文主要介绍Docker Volume的原理以及使用方式。参考了以下文章:
Docker文件系统
想要了解Docker Volume,需要知道Docker的文件系统是如何工作的。Docker的镜像是由多个文件系统(只读)叠加而成,当我们启动一个容器的时候,Docker会加载只读镜像层并在其上添加一层’读写层’.如果运行中的容器需要了一个文件,那么并不会修改只读层的文件,只会把该文件复制到’读写层’然后对他修改,只读层的文件就被隐藏了,当删除了Docker容器之后,或者重启容器之后,之前对文件的更改会丢失,镜像的只读层以及容器运行时的’读写层’被称为Union File System
(联合文件系统)
为了能够保存数据的持久化以及共享容器之间的数据,提出了Volume的概念。简单来说Volume就是一个文件或者目录。它可以绕过联合文件系统,以正常的文件或者目录的形式保存在主机上。可以通过两种方式来初始化Volume,这两种方式有一些细微区别。
运行时创建
我们可以在运行容器时使用-v
来声明Volume:
[root@VM_0_14_centos ~]# docker run -it --name centOs -v /data centos /bin/bash
[root@5c84840232ed /]#
上述命令会创建一个CentOs的容器并且把容器内部的/data目录作为数据卷挂载,并且进入了容器。
我们输入exit
命令退出容器之后。可以通过以下命令来查看挂载的情况:
[root@VM_0_14_centos ~]# docker inspect -f {{.Mounts}} centOs
[{volume fb87aef5e4ec1fc42ce8618f958a281882e32234290ecea09d9f0719477b7399 /var/lib/docker/volumes/fb87aef5e4ec1fc42ce8618f958a281882e32234290ecea09d9f0719477b7399/_data /data local true }]
可以看到容器已经把/var/lob/docker/volumes/xxx/_data
目录挂载到容器的/data
目录了。
下面我们尝试在这个目录创建一个文件,然后在进入容器查看文件。
[root@VM_0_14_centos ~]# touch /var/lib/docker/volumes/fb87aef5e4ec1fc42ce8618f958a281882e32234290ecea09d9f0719477b7399/_data/test-file
[root@VM_0_14_centos ~]# docker exec -it centOs /bin/bash
[root@5c84840232ed /]# ls /data
test-file
[root@5c84840232ed /]#
可以看到只要将主机的目录挂载到容器上,那改变就会立即生效。
除此之外,我们还可以指定挂载主机的具体目录,如下命令:
docker run -it --name centOs -v /home/wangjianfeng/data:/data centos
该命令是将主机的/home/wangjianfeng/data
目录挂载到容器的/data
目录。另外值得注意的是,挂载目录不会将镜像的文件复制到Volume中,只会把主机中不存在的文件夹创建出来。笔者就尝试过挂载nginx的配置文件目录,但是挂载的主机目录中没有nginx配置文件,所以导致容器启动失败的情况。
使用Dockfile创建数据卷
创建数据卷的另一种方式是通过Dockerfile中使用VOLUME指令,这种指定数据卷的情况只能指定挂载到本机的/var/lib/docker/xxx/
这样的目录中,并不支持指定主机的特定目录。
由于这里没有介绍过Dockerfile,所以这方面内容这里不详细介绍,后面的Dockfile文章中会再次介绍。
数据共享
如果要授权一个容器访问另一个容器的Volume,可以使用-volumes-from
参数来执行docker run
命令:
[root@VM_0_14_centos ~]# docker run -it --name centOs1 --volumes-from centOs centos
[root@53b9b9c08f5a /]# ls /data
test-file
[root@53b9b9c08f5a /]#
不管容器是否正在运行,Volume都不会被删除。
数据卷容器
还有一种方式使用数据卷,就是专门生成一个容器来挂载某个目录,该容器并不需要运行,其他容器可以使用–volumes-from命令来挂着它。可以多次使用--volumes-from
从多个容器挂载多个数据卷,还可以从其他挂载了数据卷容器的容器来挂载数据卷。
可以把上述中的centOs容器停止(数据卷容器运行纯粹就是浪费资源)后看做一个数据卷容器
数据备份与恢复
如果使用数据卷容器,想做备份和恢复就非常容易了。假设有较多的镜像从centOs中挂载了数据卷,那么备份与恢复只需针对centOs这个容器即可。
备份
执行如下命令
docker run --volumes-from centOs -v $(pwd):/backup --name worker centos tar cvf /backup/backup.tar /data
这个命令的意思是 将当前目录挂载到容器的/backup 目录,然后容器的工作就是压缩 /data的内容到 /back/backup.tar文件中。执行完之后就会看见在当前目录中生成了backup.tar文件
恢复
执行如下命令:
docker run --volumes-from centOs -v $(pwd):/backup centos tar xvf /backup/backup.tar -C /data
原理和备份是一样的。
删除数据卷
这个功能有时也挺重要的,如果使用docker rm命令来移除容器,有可能会产生很多无用的数据卷,它们会占用空间。
Volume可以使用两种方式删除数据卷:
- 使用
docker rm -v
命令,这个命令移除容器的同时也会移除数据卷 - 使用
docker run --rm
这个命令会在容器退出时清除数据
注意!以上两种方式只能删除没有容器挂载的Volume。如果有容器正在挂载的数据卷永远不会被删除。
下面还有一些关于数据卷比较有用的命令:
docker volume ls
列出所有数据卷docker volume prune
删除无用的数据卷