容器中的数据可以存储在容器层。但是将数据存放在容器层存在以下问题:
Docker 提供了3种持久化数据的方式:
如果没有显式创建,一个卷会在最开始挂载时被创建。当容器停止时,卷仍然存在。多个容器可以通过read-write或read-only的方式使用同一个卷。
只有在显式删除时,卷才会被删除。如果将一个空卷挂载到容器中一个存有文件或目录的目录中,这些文件或目录会被拷贝到空卷中;如果将一个非空卷挂载到容器中一个存有文件或目录的目录中,这些文件或目录会被隐藏。
docker volume create
docker volume rm 卷名
docker volume prune
docker volume ls
docker volume inspect 卷名
-v
或--volume
。如果是Docker17.06或更高:推荐使用--mount
。(同 bind mount)第一个域:对于命名卷,为卷名;匿名卷,则忽略,此时会创建匿名卷
第二个域:容器中的挂载点
第三个域:可选参数,由','
隔开,如ro
-v或—volume:由3个域组成,’:’分隔
—mount:由多个’,’隔开的键值对
=组成:
当使用docker service create 启动Docker服务时,只支持--mount,不支持-v和--volume。并且每个服务容器使用它们各自的本地卷,因此如果使用本地(local)卷驱动,容器无法通过卷共享数据,但是一些卷驱动支持共享存储。Docker for AWS和Doocker for Azure都使用Cloundstor plugin支持持久存储
主机中的文件或目录通过全路径被引用。在使用绑定挂载时,这些目录或文件不一定要已经存在。
如果使用这种方式将一个目录挂载到容器中一个存有文件或目录的目录中,这些文件或目录会被隐藏;如果主机中的文件或目录不存在,当使用--mount
挂载时,Docker会报错,当使用-v
或--volume
时,会在主机上创建目录
挂载到容器:-v或—volume。如果是Docker17.06或更高:推荐使用—mount。(同 volumes)
-v
或--volume
:由3个域组成,':'
分隔','
隔开,如ro
--mount
:由多个','
隔开的键值对<key>=<value>
组成:--mount
不支持z和Z(这个不同于-v和—volume)大体上来说,只要可能,最好使用volumes
对于bind mount和volumes,默认都是rprivate。只有在使用bind mount时可配置,且必须在linux下。bind propagation是个超前主题,对于大多数用户来说,并不需要配置
对于一个挂载点/mnt
,假设它同时也被挂载到/tmp
。bind propagation控制 whether a mount on /tmp/a would also be available on /mnt/a
在设置bind propagation之前,主机文件系统需要支持bind propagation
下面的例子将主机中的target/
挂载到容器中2次:
docker run -d -it --name devtest --mount type=bind,source="$(pwd)"/target,target=/app --mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave nginx:latest
此时如果创建/app/foo/
,/app2/foo
也会存在
你能添加z
或Z
选项来修改挂载到容器中的主机文件或目录的selinux label:
z
选项指明bind mount的内容在多个容器间是共享的Z
选项指明bind mount的内容是私有不共享的要特别小心的使用这两个选项。”Bind-mounting a system directory such as /home
or /usr
with the Z
option renders your host machine inoperable and you may need to relabel the host machine files by hand”
只在linux中支持
相对于volumes和bind mount,tmpfs mount是临时的,只在主机内存中持久化。当容器停止,tmpfs mount会被移除。对于临时存放敏感文件很有用
不同于volumes和bind mount,多个容器无法共享tmpfs mount
=组成:
机器间共享数据
当构建错误容忍应用时,可能需要配置同一个服务的多个副本来访问相同的文件:
有多种方法来实现这个目的:
volume drivers可以将底层存储系统从应用逻辑中抽象出来。比如,如果你的服务使用一个具有NFS driver的卷,你能更新你的服务使用不同的driver,作为在云中存储数据的示例,而不更改应用程序逻辑
在使用docker volume create
或驱动容器创建匿名卷时,可以指定一个volume drivers。下面的例子使用vieux/sshfs作为volume drivers
假设有2个节点,第一个节点是Docker主机,它能SSH到第二个节点
1、在Docker主机中,安装vieux/sshfs插件
docker plugin install --grant-all-permissions vieux/sshfs
2、使用卷驱动创建卷
1)创建命名卷
docker volume create --driver vieux/sshfs -o sshcmd=test@node2:/home/test -o password=testpassword sshvolume
2)启动容器时使用卷驱动创建匿名卷
docker run -d --name sshfs-container --volume-driver vieux/sshfs --mount src=sshvolume,target=/app,volume-opt=sshcmd=test@node2:/home/test,volume-opt=password=testpassword nginx:latest
3、备份、恢复、迁移数据卷
1)备份一个容器
docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
2)用备份恢复容器
使用刚刚创建的备份来恢复容器:
docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
然后,在新创建的容器的卷中使用tar
解包备份的数据:
docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
领取专属 10元无门槛券
私享最新 技术干货