使用 Docker 过程中,需要查看容器内应用产生的数据或者备份容器内数据,以及多个容器之间进行数据共享,这就会涉及到容器的数据管理(数据持久化):
将容器中的文件存储在宿主机的文件系统上,即使容器停止甚至销毁,文件仍会保留。如果在Linux上运行Docker,可以使用 tmpfs 挂载。
无论使用哪种类型,数据在容器内没有任何区别,依然被视为容器文件系统中的目录或文件。
Data Volume 是目录或文件,并非是没有格式化的磁盘(块设备);
容器可以读写 volume 中的数据;
volume 数据可以被永久的保存,即使使用它的容器已经销毁。
参数-v
docker run -v 容器目录
docker run -v 宿主机目录:容器目录
[root@johnnyg03 ~]# docker run -it -v /data/ busybox:latest /bin/sh
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # cd /data/
/data # ls //空的data目录
//添加三个文件
/data # touch 1.txt
/data # touch 2.txt
/data # touch 3.txt
/data # ls
1.txt 2.txt 3.txt
//退出容器
/data # exit
//在宿主机默认保存路径上查看“/var/lib/docker/volumes/”
[root@johnnyg03 ~]# ll /var/lib/docker/volumes/
total 28
drwx-----x 3 root root 4096 Aug 11 10:27 78d46bbc3aefb43bd5b31815e0ca22c644dec1221cca254ceba87349c9e275d6
brw------- 1 root root 253, 1 Aug 10 12:23 backingFsBlockDev
-rw------- 1 root root 32768 Aug 11 10:27 metadata.db
[root@johnnyg03 ~]# ll /var/lib/docker/volumes/78d46bbc3aefb43bd5b31815e0ca22c644dec1221cca254ceba87349c9e275d6/
total 4
drwxr-xr-x 2 root root 4096 Aug 11 10:28 _data
[root@johnnyg03 ~]# ll /var/lib/docker/volumes/78d46bbc3aefb43bd5b31815e0ca22c644dec1221cca254ceba87349c9e275d6/_data/
total 0
-rw-r--r-- 1 root root 0 Aug 11 10:27 1.txt
-rw-r--r-- 1 root root 0 Aug 11 10:27 2.txt
-rw-r--r-- 1 root root 0 Aug 11 10:28 3.txt
//可以看到在容器/data目录创建的三个文件实现数据持久化
[root@johnnyg03 ~]# mkdir /data/b1
[root@johnnyg03 ~]# docker run -it -v /data/b1/:/data --name b1 busybox:latest /bin/sh
/ # cd /data/
/data # ls //空的data目录
//添加三个文件
/data # touch b1-1.txt
/data # touch b1-2.txt
/data # touch b1-3.txt
/data # ls
b1-1.txt b1-2.txt b1-3.txt
//退出容器
/data # exit
//在宿主机查看所指定挂载目录“/data/b1”
[root@johnnyg03 ~]# ls /data/b1/
b1-1.txt b1-2.txt b1-3.txt
//可以看到在容器/data目录创建的三个文件实现数据持久化
如果用户需要在容器之间共享一些持续更新的数据,最简单的方法就是使用数据卷容器,其实数据卷容器就是一个普通的容器,只不过是专门提供其他容器挂载使用。
参数--volumes-from
docker run --volumes-from 数据卷容器名
docker run --volumes-from 其它挂载了数据卷容器的容器名
[root@johnnyg03 ~]# docker run -it --volumes-from dv_db --name b2 busybox:latest /bin/sh
/ # cd /data/
/data # touch b2_1.txt
/data # touch b2_2.txt
/data # touch b2_3.txt
/data # ls
b2_1.txt b2_2.txt b2_3.txt
/data # exit
[root@johnnyg03 ~]# ll /data/data-volumn-db/
total 0
-rw-r--r-- 1 root root 0 Aug 11 11:04 b2_1.txt
-rw-r--r-- 1 root root 0 Aug 11 11:04 b2_2.txt
-rw-r--r-- 1 root root 0 Aug 11 11:04 b2_3.txt
[root@johnnyg03 ~]# docker run -it --volumes-from b2 --name b3 busybox:latest /bin/sh
/ # cd /data/
/data # touch b3_1.txt
/data # touch b3_2.txt
/data # touch b3_3.txt
/data # ls
b2_1.txt b2_2.txt b2_3.txt b3_1.txt b3_2.txt b3_3.txt
/data # exit
[root@johnnyg03 ~]# ll /data/data-volumn-db/
total 0
-rw-r--r-- 1 root root 0 Aug 11 11:04 b2_1.txt
-rw-r--r-- 1 root root 0 Aug 11 11:04 b2_2.txt
-rw-r--r-- 1 root root 0 Aug 11 11:04 b2_3.txt
-rw-r--r-- 1 root root 0 Aug 11 11:11 b3_1.txt
-rw-r--r-- 1 root root 0 Aug 11 11:11 b3_2.txt
-rw-r--r-- 1 root root 0 Aug 11 11:11 b3_3.txt
首先先创建对应的数据卷容器,并在数据卷容器内放置一定测试文件(此步骤在上面已完成)
【数据卷容器名——dv_db】
【数据卷容器对应数据存放目录(宿主机)——/data/data-volumn-db/】
其次创建一个新的容器,此处容器名为dv_db_backup
,使用命令--volumes-from
将容器dv_db_backup
与容器dv_db
进行绑定,将当前容器dv_db_backup
的/backup
目录挂载到宿主机的当前目录pwd
【此处表示为宿主机的root家目录】,然后将数据卷容器dv_db
中的数据卷(即数据卷容器dv_db
的/data
目录下的数据内容)打包到当前容器dv_db_backup
的/backup
目录下并命名为backup.tar
。
此时,由于使用了命令--volumes-from
将容器dv_db_backup
与容器dv_db
绑定在一起,因此,会将容器dv_db
的/data
目录下的内容传送至容器dv_db_backup
的/data
目录下。然后在容器dv_db_backup
上执行命令tar cvf /backup/backup.tar /data
表示将当前容器的/data
目录下的数据内容包括/data
目录本身一起打包放到当前容器的/backup
目录下并将此打包文件命名为backup.tar
。
//创建容器`dv_db_backup`并实施上述操作(自行一一对应)
[root@johnnyg03 ~]# docker run --name dv_db_backup --volumes-from dv_db -v `pwd`:/backup busybox:latest tar cvf /backup/backup.tar /data
data/
data/b2_1.txt
data/b3_2.txt
data/b2_2.txt
data/b3_3.txt
data/b2_3.txt
data/b3_1.txt
tar: removing leading '/' from member names
//查看宿主机的当前目录(上述`pwd`命令执行结果为root家目录)
[root@johnnyg03 ~]# ll
total 2880
-rw-r--r-- 1 root root 4608 Aug 11 11:34 backup.tar
//可以清晰看到root家目录下已存在backup.tar打包文件(通过挂载实现数据持久化所得)
步骤二末尾可以看到数据已打包成功,此时可以实现恢复。此处通过创建一个新的容器,实现数据迁移测试。
先在03
设备将打包文件传送到02
设备的root家目录中
[root@johnnyg03 ~]# scp backup.tar 10.0.2.11:~
//查看家目录
[root@johnnyg02 ~]# ll
total 599792
-rw-r--r-- 1 root root 4608 Aug 11 13:57 backup.tar
接下来在02
设备上创建一个新的容器,此处容器名为b4
,将当前容器b4
的/data
目录挂载到宿主机本地目录/data/b4/
[root@johnnyg02 ~]# docker run -it --name b4 -v /data/b4/:/data busybox:latest /bin/sh
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # ls /data/
//可以看到,此时/data目录下为空,没有任何数据内容
紧接着在02
设备上再次创建一个新的容器,此处容器名为dv_db_backup_load
,通过--volumes-from
命令向容器b4
绑定,然后将当前容器dv_db_backup_load
的/backup
目录挂载到宿主机的当前目录pwd
【此处表示为宿主机的root家目录】,解包到当前容器dv_db_backup_load
的根目录下(tar
命令没有指定解包放置处会默认解包至当前目录,当前目录是容器dv_db_backup_load
的根目录,由于backup.tar
包中包含/data
目录本身,因此会覆盖根目录下原有的/data
目录,并将包内文件放置到此目录下)。
此时,由于使用了命令--volumes-from
将容器dv_db_backup_load
与容器b4
绑定在一起,因此,会将容器dv_db_backup_load
的/data
目录下的内容传送至容器b4
的/data
目录下。
[root@johnnyg03 ~]# docker run --name dv_db_backup_load --volumes-from b4 -v `pwd`:/backup busybox:latest tar xvf /backup/backup.tar
data/
data/b2_1.txt
data/b3_2.txt
data/b2_2.txt
data/b3_3.txt
data/b2_3.txt
data/b3_1.txt
此时再次查看容器b4
的/data
目录
/ # ls /data/
b2_1.txt b2_2.txt b2_3.txt b3_1.txt b3_2.txt b3_3.txt
//可以清晰看到数据已全部迁移成功且没有丢失
dv_db
[root@johnnyg03 ~]# docker run -it -v /data/data-volumn-db/:/data --name dv_db busybox:latest /bin/sh
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # ls data/
b2_1.txt b2_2.txt b2_3.txt b3_1.txt b3_2.txt b3_3.txt
dv_db_backup
[root@johnnyg03 ~]# docker run -it --name dv_db_backup --volumes-from dv_db -v `pwd`:/backup busybox:latest /bin/sh
/ # ls
backup bin data dev etc home proc root sys tmp usr var
/ # ls /backup/ //还没有打包,所以backup.tar文件
docker-busybox-test1.tar.gz docker-busybox-test2.tar.gz
/ # ls /data/ //绑定“dv_db”后传送过来的数据
b2_1.txt b2_2.txt b2_3.txt b3_1.txt b3_2.txt b3_3.txt
/ # tar cvf /backup/backup.tar /data/ //打包
tar: removing leading '/' from member names
data/
data/b2_1.txt
data/b3_2.txt
data/b2_2.txt
data/b3_3.txt
data/b2_3.txt
data/b3_1.txt
/ # ls /backup/ //再次查看此目录,backup.tar文件已存在
backup.tar docker-busybox-test1.tar.gz docker-busybox-test2.tar.gz
b4
[root@johnnyg02 ~]# docker run -it --name b4 -v /data/b4/:/data busybox:latest /bin/sh
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # ls /data/ //还没有进行后续操作,此时此目录为空
dv_db_backup_load
[root@johnnyg02 ~]# docker run -it --name dv_db_backup_load --volumes-from b4 -v `pwd`:/backup busybox:latest /bin/sh
/ # ls
backup bin data dev etc home proc root sys tmp usr var
/ # ls /backup/ //挂载了本地当前目录(宿主机root家目录)后传送过来的数据
backup.tar harbor-offline-installer-v2.4.1.tgz
docker-busybox-test2.tar.gz test
/ # ls /data/ //没有解包,此时此目录为空
/ # tar xvf /backup/backup.tar //解包到当前目录
data/
data/b2_1.txt
data/b3_2.txt
data/b2_2.txt
data/b3_3.txt
data/b2_3.txt
data/b3_1.txt
/ # ls /data/ //解包后,文件已存在
b2_1.txt b2_2.txt b2_3.txt b3_1.txt b3_2.txt b3_3.txt
b4
/ # ls /data/ //绑定“dv_db_backup_load”后传送过来的数据
b2_1.txt b2_2.txt b2_3.txt b3_1.txt b3_2.txt b3_3.txt