用户在使用Docker的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份,甚至多个容器之间进行数据共享,这必然涉及到Docker的数据管理。
容器中管理数据主要有两种方式:
- 数据卷(Data Volumes)
- 数据卷容器(Data Volumes Dontainers)
1. 挂载本地的目录到容器里
docker run -itd -v /data/:/data/ 镜像名/IMAGE_ID bash
-d 选项表示后台运行
-v 选项用来指定挂载(创建映射关系)的目录
/data/:/data/ 宿主机目录:容器目录,: 前面的/data/为本地目录 : 后面的/data/为容器里的目录,名字不一定要相同 只要自己指定好对应的目录就可以 宿主机要手动去创建这个目录 容器会自动生成这个目录
镜像名/IMAGE_ID 为 #docker images 显示的 REPOSITORY 列的 镜像名 或者 IMAGE_ID 列的 id
实例:
[root@localhost configs]# docker run -itd -v /data/:/data1/ centos bash 246eeac7493f7701f65b5d13f76c0eb8f1c3dae0159e766f7253e0e238e549b0 [root@localhost configs]# touch /data/1.txt [root@localhost configs]# echo "hhh" > /data/1.txt [root@localhost configs]# docker exec -it 246eea bash [root@246eeac7493f /]# cat /data1/1.txt hhh
2. 挂载数据卷
其实我们挂载目录的时候,可以指定容器name,如果不指定就随机定义了。比如下面我们没有指定,它就生成了一个名字为desperate_babbage
docker run -itd --volumes-from llonely_archimedes centos bash
--volumes-from 镜像名/IMAGE_ID 指定数据卷容器来源 ,这样,我们使用centos镜像创建了新的容器,并且使用了 desperate_babbage 容器的数据卷
实例:
[root@localhost configs]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 246eeac7493f centos "bash" 3 hours ago Up 3 hours desperate_babbage [root@localhost configs]# docker run -itd --volumes-from desperate_babbage centos bash 0ce506d56e681fc9989bc8bba523f93f5d814b54381e43308661eb035cf38d47 [root@localhost configs]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0ce506d56e68 centos "bash" 5 seconds ago Up 5 seconds sleepy_noyce 246eeac7493f centos "bash" 3 hours ago Up 3 hours desperate_babbage [root@localhost configs]# docker exec -it 0ce bash [root@0ce506d56e68 /]# cat /data1/1.txt hhh
自定义容器name:
docker run -itd -v /data/:/data1 --name datavol centos bash
删除Volumes
如果你已经使用docker rm来删除你的容器,那可能有很多的孤立的Volume仍在占用着空间。 Volume只有在下列情况下才能被删除:该容器是用docker rm -v命令来删除的(-v是必不可少的)。
docker run中使用了--rm参数
即使用以上两种命令也只能删除没有容器连接的Volume。连接到用户指定主机目录的Volume永远不会被docker删除。
除非你已经很小心的,总是像这样来运行容器,否则你将会在/var/lib/docker/vfs/dir目录下得到一些僵尸文件和目录,并且还不容易说出它们到底代表什么。
3. 定义数据卷容器
有时候,我们需要多个容器之间相互共享数据,类似于linux里面的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷首先建立数据卷容器
docker run -itd -v /data/ --name testvol centos bash //注意这里的/data/是容器的/data目录,并非本地的/data/目录
实例:
[root@localhost volumes]# docker run -itd -v /data/ --name testvol centos bash 3428b89eb59f9f8912909170b554ee069b4f747c600a889ede62bc09cb87f30f [root@localhost volumes]# docker exec -it 342 bash [root@3428b89eb59f /]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/docker-253:0-132997-3428b89eb59f9f8912909170b554ee069b4f747c600a889ede62bc09cb87f30f 9.8G 226M 9.0G 3% / tmpfs 499M 0 499M 0% /dev shm 64M 0 64M 0% /dev/shm /dev/mapper/VolGroup-LogVol00 29G 7.1G 20G 27% /data [root@3428b89eb59f /]ls /data/ //容器内data内容为空 [root@3428b89eb59f /]# echo 11111 > /data/1.txt [root@3428b89eb59f /]# exit exit [root@localhost volumes]# docker run -itd --volumes-from testvol centos bash //其他容器挂在该卷 5ec4dc4f7bf1d362ab125e9e43021b66f64ebb2d4df3b8b86c1af6b07d7bc369 [root@localhost volumes]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5ec4dc4f7bf1 centos "bash" 13 seconds ago Up 12 seconds loving_darwin 3428b89eb59f centos "bash" 3 minutes ago Up 3 minutes testvol 29fd96303e7f centos "bash" 55 minutes ago Up 55 minutes datavol [root@localhost volumes]# docker exec -it 5ec bash [root@5ec4dc4f7bf1 /]# cat /data/1.txt //共享成功 11111 [root@5ec4dc4f7bf1 /]# exit exit [root@localhost volumes]# docker run -itd --volumes-from testvol --name web3 centos bash //然后让其他容器挂载该数据卷,加上--name web3,指定name d54365aafdfb742062d452a2bc35c7ab3c28e5e8ac9b170aeb99ba1f098c5180 [root@localhost volumes]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d54365aafdfb centos "bash" 5 seconds ago Up 4 seconds web3 5ec4dc4f7bf1 centos "bash" 13 minutes ago Up 13 minutes loving_darwin 3428b89eb59f centos "bash" 16 minutes ago Up 16 minutes testvol 29fd96303e7f centos "bash" About an hour ago Up About an hour datavol [root@localhost volumes]#
如何配置自定义的数据卷容器(容器NFS:/data1)与本地/data/同步?并且容器之间的/data1目录相互同步,思路如下:
# docker run -tid -v /data/:/data1/ --name vol-nfs centos bash
# docker run -itd --volumes-from vol-nfs --name web4 centos bashl
[root@localhost volumes]# docker run -tid -v /data/:/data1/ --name vol-nfs centos bash 15722aba5ef735cebdab7b37f0c5ca7f05ebea8abf8744890a1ba4984c6f2731 [root@localhost volumes]# ls /data/ 1.txt [root@localhost volumes]# docker exec -it 157 bash [root@15722aba5ef7 /]# ls /data1/ 1.txt [root@15722aba5ef7 /]# echo 222 > /data1/2.txt [root@15722aba5ef7 /]# exit[root@localhost volumes]# [root@localhost volumes]# docker run -itd --volumes-from vol-nfs --name web4 centos bash 91b99aebf615cfcea2a87f22a23e3dd95564407d74dc4f7be53ca5e0ae22005c [root@localhost volumes]# docker exec -it 91b bash [root@91b99aebf615 /]# ls /data1/ 1.txt 2.txt [root@91b99aebf615 /]#
4. 数据卷的备份与恢复
(1)备份
说明:首先我们需要使用testvol数据卷新开一个容器,同时我们还需要把本地的/vol_data_backup/目录挂载到该容器的/backup下,这样在容器中/backup目录里面新建的文件,我们就可以直接在/vol_data_backup/目录中看到了。 然后再把/data/目录下面的文件打包到成data.tar文件放到/backup目录下面。
[root@localhost volumes]# mkdir /vol_data_backup [root@localhost volumes]# docker run -itd --volumes-from testvol -v /vol_data_backup/:/backup centos bash 6836fd692b26bef205ddc59c39605babc054bf6cd3b0010c1442212d04c1e24f [root@localhost volumes]# docker exec -it 683 bash [root@6836fd692b26 /]# ls /data/ 1.txt [root@6836fd692b26 /]# ls /backup/ [root@6836fd692b26 /]# tar cvf /backup/data.tar /data/ tar: Removing leading `/' from member names /data/ /data/1.txt [root@6836fd692b26 /]# exit[root@localhost volumes]# [root@localhost volumes]# ls /vol_data_backup/ data.tar [root@localhost volumes]#
(2)恢复(假设共享的数据卷容器已经删除)
思路:先新建一个数据卷容器,再建一个新的容器并挂载该数据卷容器,然后再把tar包解包,与上图类似,把宿主机/vol_data_backup/下的data.tar解压为data
新建数据卷容器:docker run -itd -v /data/ --name testvol3 centos bash
挂载数据卷新建容器,并解包:docker run --volumes-from testvol3 -v /vol_data_backup/:/backup centos tar xvf /backup/data.tar
[root@localhost volumes]# docker run -itd -v /data --name testvol3 centos bash 5d9796232df8ce2c7f7455b1fda127dd242d580f6745305f7eadd9d5913d6a97 [root@localhost volumes]# docker run --volumes-from testvol3 -v /vol_data_backup/:/backup centos tar xvf /backup/data.tar data/ data/1.txt [root@localhost volumes]# docker exec -it 5d9 bash [root@5d9796232df8 /]# ls /data/ 1.txt [root@5d9796232df8 /]# cat /data/1.txt 11111