docker——数据卷(volume)概念及使用案例
docker数据卷
Docker的镜像是有?系列的只读层组合?来,当启动?个容器时,Docker加载镜像的所有只读层,并在最上层加??个读写层。这个设计使得Docker可以提?镜像构建、存储和分发的效率,节省了时间和存储空间,然?也存在?些问题:
- 容器中的?件在宿主机上存在形式复杂,不能在宿主机上很?便地对容器中的?件进?访问。
- 多个容器之间的数据?法共享
- 当删除容器时,容器产?的数据将丢失。
所以引入的数据卷的概念。Volume 是存在于?个或多个容器中的特定?件或?件夹,这个?录以独?于联合?件系统的形式在宿主机中存在,并为数据的共享和持久化提供便利。
- volume 在容器创建时就会初始化,在容器运?时就可以使?其中的?件。
- volume 能在不同的容器之间共享和重?
- 对volume中数据的操作会?上?效
- 对volume中数据的操作不会影响镜像本身
- volume的?存周期独?于容器的?命周期,即使删除容器,volume仍然会存在,没有任何容器使?的volume也不会被Docker删除。
数据卷使用
大概命令
//Create a volume
docker volume create
//Display detailed information on one or more volumes
docker volume inspect
//List volumes
docker volume ls
//Remove all unused local volumes
docker volume prune
//Remove one or more volumes
docker volume rm
创建数据卷
#创建?个名为 vol_simple的存储卷
docker volume create --name vol_simple
Docker run 和 docker create 通过指定-v参数 可以为容器挂载?个数据卷。这样挂载的对应宿主机是一个匿名数据卷
#没有指定volume卷,只指定了容器中的挂载点/data
docker run -d -it -v /data ubuntu /bin/bash
#查看随机创建的volume位置,查看mounts的内容
docker inspect {ID}
#创建?个指定名字的volume ,并挂载到容器中的/data?录
docker run -d -v vol_simple:/data ubuntu
#查看数据卷的信息
docker volume inspect vol_simple
挂载数据卷
使?docker run 或者 docker create 创建新容器是,可以使?-v标签为容器添加volume。可以将??创建或者有Docker创建的volume挂载到容器中,也可以将宿主机上的?录或者?件作为volume挂载到容器中。
将宿主机中指定?录作为volume挂载到容器中的/data?录下,?件夹必须使?绝对路径,如果宿主机中不存在指定的?录,则会创建?个空?件夹;如果宿主机?件夹已经存在,容器可以通过访问挂载点/data 从?访问宿主机?件夹中的所有内容。如果容器下原本已经存在/data?件夹,且不为空,那么容器中?件夹下原有的内容将被隐藏,来保持与宿主机中的?件夹?致
挂载案例
#1.挂载方式
#创建名为vol_simple的数据卷,并挂载到容器中的/data?录下
docker volume create --name vol_simple
docker run -d -v vol_simple:/data ubuntu /bin/bash
#创建?个随机的ID的volume,并将其挂载到容器中的/data?录下
docker run -d -v /data ubuntu /bin/bash
#将宿主机中指定?录作为volume挂载到容器中的/data?录下,?件夹必须使?绝对路径
#如果宿主机中不存在指定的?录,则会创建?个空?件夹;
#如果宿主机?件夹已经存才,容器可以通过访问挂载点/data 从?访问宿主机?件夹中的所有内容
#如果容器下原本已经存在/data?件夹,且不为空,那么容器中?件夹下原有的内容将被隐藏,来保持与宿主机中的?件夹?致
docker run -d -v $HOME/data:/data ubuntu /bin/bash
#2.只读挂载
# ro表示只读,rw表示读写,默认为rw
docker run -it -v $HOME/data:/data:ro ubuntu /bin/bash
# 通过修改?件验证
echo 123456abcdefg >> /data/test
#3.挂载多个数据卷
docker run -it -v $HOME/data:/data:ro -v /data1 -v /data2 ubuntu /bin/bash
docker run -v /path/to/host/volume1:/container/path1 -v /path/to/host/volume2:/container/path2 <image>
# 如果宿主机多个路径挂载到容器内同一个路径,只有最后一个挂载会生效
#4.通过dockerfile指定数据卷挂载
VOLUME /data
#指定多个数据卷的挂载点
VOLUME ["/data1","/data2"]
使?dockerfile VOLUME 指令,与docker run -v 不同的是,dockerfile指令不能挂载主机中指定的?件夹。这时为了保证Dockerfile的可移植性,因为不能保证所有的宿主机都有对应的?件夹。如果镜像中存在/data?件夹,这个?件夹中的内容将全部被复制到宿主机上对应?件夹中,并且根据容器中的?件设置合适的权限和所有者。
注意:在Dockerfile中使?VOLUME指令后的代码,如果尝试对这个volume进?修改,这些修改都不会?效。因为:volume 是独?于rootfs的存储,镜像构建过程,每?层类似docker commit 提交临时镜像为镜像层,docker commit不会对挂载的volume进?保存。
dockerfile挂载案例
案例一
FROM ubuntu
RUN useradd foo
VOLUME /data
# 后面对存储卷的修改都不会生效
RUN touch /data/file
RUN chown -R foo:foo /data
docker build -t test1:v1 -f Dockerfile .
docker run -d -it test1:v1 /bin/bash
//查看挂载点信息
docker inspect 容器ID
//查看宿主机存储卷?录
sudo ls 宿主机存储卷?录
案例二
由于挂载volume时,/data?录已经存在,所以/data中的?件以及它们的权限和所有者设置都会被复制到volume中。
FROM ubuntu
RUN useradd foo
RUN mkdir /data && touch /data/file
RUN chown -R foo:foo /data
VOLUME /data
docker build -t test1:v2 -f Dockerfile1 .
docker run -d -it test1:v2 /bin/bash
//查看挂载点信息
docker inspect 容器ID
//查看宿主机存储卷?录
sudo ls 宿主机存储卷?录
案例三
通过CMD和ENTRYPOINT指令,在容器启动时执?挂载点下?件的初始化
FROM ubuntu
RUN useradd foo
VOLUME /data
CMD touch /data/file && chown -R foo:foo /data
共享数据卷
在使?docker run 或docker create创建新容器时,可以使?–volumes-from 标签使得容器与已有容器共享volume。可以使?多个–volumes-from标签,使得容器与多个已有容器共享volume。
?个容器挂载了?个volume,即使这个容器停?运?,该volume?仍然存在,其他容器也可以使?–volume-from与这个容器共享volume。
[root@localhost example_vol]# echo $HOME
/root
[root@localhost example_vol]# mkdir $HOME/data
[root@localhost example_vol]# mkdir $HOME/readOnly_data
[root@localhost example_vol]# docker volume create vol_simple1
vol_simple1
[root@localhost example_vol]# docker volume create vol_simple2
vol_simple2
# 运行容器,挂载宿主机目录和创建的数据卷
[root@localhost example_vol]# docker run -d -it -v vol_simple1:/vol_simple1 -v $HOME/data:/data -v $HOME/readOnly_data:/readOnly_data:ro --name share_data ubuntu /bin/bash
[root@localhost example_vol]# docker run -d -it -v vol_simple2:/vol_simple2 --name share_data2 ubuntu /bin/bash
# 通过--volumes-from 共享容器share_data和share_data2的数据卷
[root@localhost example_vol]# docker run -d -it --volumes-from share_data --volumes-from share_data2 --name volume_from1 ubuntu /bin/bash
97b43a8a0851450e08737c5c108742e51dc1902a04c798cd5e1fe5a022f894fc
[root@localhost example_vol]# docker run -d -it --volumes-from share_data --volumes-from share_data2 --name volume_from2 ubuntu /bin/bash
472a7e7fd1de6d19fb05c8d87d7f3bc5da6090160e2d4efb00c65ca8acb701da
#docker inspect查看一下。可以看到都挂载了哪些数据卷或者绑定目录
[root@localhost example_vol]# docker inspect 472a7e7fd1de
...
"Mounts": [
{
"Type": "bind",
"Source": "/root/readOnly_data",
"Destination": "/readOnly_data",
"Mode": "",
"RW": false,
"Propagation": "rprivate"
},
{
"Type": "volume",
"Name": "vol_simple2",
"Source": "/var/lib/docker/volumes/vol_simple2/_data",
"Destination": "/vol_simple2",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "vol_simple1",
"Source": "/var/lib/docker/volumes/vol_simple1/_data",
"Destination": "/vol_simple1",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "bind",
"Source": "/root/data",
"Destination": "/data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
...
删除数据卷
如果创建容器时从容器中挂载了volume,在/var/lib/docker/volumes下会?产与volume对应的?录(可使?docker inspect 命令查看容器信息找到对应的信息)。
使?docker rm 删除容器并不会删除与volume对应的?录,这些?录会占据不必要的存储空间。
删除volume的方式
- 使?docker volume rm <volume_name> 删除数据卷
- 使?docker rm -v <container_name> 删除容器时?并删除它挂载的数据卷
- 在运?容器时使?docker run --rm 标签会在容器停?运?时删除容器以及容器所挂载的volume
注意:
-
在使?第?种docker volume rm 删除时,只有当没有任何容器使?该volume的时候,才能被删除成功
-
另外两种删除?式,只会对挂载在该容器上的未指定名称(匿名的)的volume进?删除,?会对?户指定名称的(具名的)volume进?保留
-
如果volume 是在创建容器时从宿主机中挂载的,?论对容器进?任何操作都不会导致其在宿主机中被删除,如果不需要这些?件,只能?动删除。(从宿主机中挂载是指 docker run -v dir:dir 这种模式
备份和迁移数据卷
volume 作为数据的载体,在很多情况下需要对其中的数据进?备份、迁移,或是从已有数据恢复。我们最容易想到?个备份还原的?式,那就是通过inspect 命令查看容器信息,找到对应的数据卷,?动打包数据;同样的还原那就是把打包好的数据解压到对应的数据卷。
同时可以采用–volumes-from实现备份和还原
备份
启动另外?个临时容器,共享挂载数据容器share_data,同时挂载当前?录到容器的/backup。启动容器时执?打包命令,将/data挂载点下的数据打包到/backup/data.tar ?件中。–rm 表示该容器停?后会删除该容器和该容器的数据卷
docker run --rm --volumes-from share_data -v $(pwd):/backup ubuntu tar cvf /backup/data.tar /data
恢复
# 创建需要迁移的目标容器
docker run -d -it --name vol_bck -v /data ubuntu /bin/bash
创建临时容器,通过共享存储的?式与?标容器共享存储,同时挂载当前?录到容器的/backup。启动容器时从backup挂载点下的data.tar 解压?件到容器的根?录。
docker run --rm --volumes-from vol_bck -v $(pwd):/backup ubuntu tar xvf /backup/data.tar -C /
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!