volumes是Docker数据持久化机制。bind mounts依赖主机目录结构,volumes完全由Docker管理。Volumes有以下优点:


  • Volumes更容易备份和移植。
  • 可以通过Docker CLI或API进行管理
  • Volumes可以无区别的工作中Windows和Linux下。
  • 多个容器共享Volumes更安全。
  • Volume驱动可以允许你把数据存储到远程主机或者云端,并且加密数据内容,以及添加额外功能。
  • 一个新的数据内容可以由容器预填充。

而且,volumes不会增加容器的大小,生命周期独立与容器。



docker vim 容器里 没有 docker volume ls_docker



如果你的容器产生不需要持久化数据,请使用tmpfs mount方式,可以避免容器的写入层数据写入。



Volumes use  
 rprivate 
  bind propagation, and bind propagation is not configurable for volumes.(不理解什么意思)



选择使用 -v还是—mount



swarm services。然而,从 Docker 17.06开始,也可是使用 --mount用于独立容器。—mount命令更精准详细。-v将选项进行了合并。使用—mount。



如果你需要制定volume驱动选项,你必须使用 —mount。


  • -v或者--volume:由3部分参数组成,使用“:”间隔。顺序不能颠倒。
  • 第一个部分是volumes名字,在宿主机上具有唯一性。匿名卷名字系统给出。
  • 第二部分是挂载到容器里的文件或文件夹路径。
  • 第三部分是可选项列表分隔符,例如“or”,这些可选项在下面会讨论。
  •     —mount:由多个键值对组成,<key>=<value>。—mount要比-v或者--volume命令更长,但是更容易理解。
  • type,可以是bind,volume或者tmpfs。这篇文章主要讨论volumes,所以type一直使用volume.
  • source,volumes的名字,匿名volume可以省略。source可缩写为src.
  • destination,挂载到容器中的文件或目录路径。可也缩写为dst或者使用target。
  • readonly,指定挂载在容器中为只读。
  • volume-opt,可选属性,可以多次使用。

下面是—mount和-v的例子。



-v和—mount的不同行为


与bind mounts不同,对于—mount和-v所有的选项都可以使用。


当使用volumes服务时,只支持—mount.



创建和管理volumes


不像bind mount,你可以在容器外创建和管理volumes。



创建一个volume:



$  
 docker volume create my-vol



显示所有volumes



$  
 docker volume  
 ls
 
 
 
 
local                
 my-vol



查看volumes



$  
 docker volume inspect my-vol
 
[
 
  
 {
 
  
 "Driver" 
 :  
 "local" 
 ,
 
         
 "Labels" 
 :  
 {} 
 ,
 
         
 "Mountpoint" 
 :  
 "/var/lib/docker/volumes/my-vol/_data" 
 ,
 
         
 "Name" 
 :  
 "my-vol" 
 ,
 
         
 "Options" 
 :  
 {} 
 ,
 
         
 "Scope" 
 :  
 "local"
 
  
 }
 
]



删除一个volume:


$  
 docker volume rm my-vol



启动一个带volume的容器



如果你启动一个带有volume容器,volume还没有创建,Docker会为你创建。下面的例子挂载myvol2到容器中的/app/下。



下面的例子-v和—mount结果是一样的。



—mount: 

 
$  
 docker run  
 -d 
   
 \
 
  
 --name 
  devtest  
 \
 
  
 --mount 
   
 source 
 = 
 myvol2,target 
 = 
 /app  
 \
 
  nginx:latest
 
 
 
 

  -v: 

 
 
$  
 docker run  
 -d 
   
 \
 
  
 --name 
  devtest  
 \
 
  
 -v 
  myvol2:/app  
 \
 
  nginx:latest


使用inspect查看挂载是否正确,查看Mounts部分:


"Mounts" 
 : 
   
 [
 
  
 {
 
  
 "Type" 
 : 
   
 "volume" 
 ,
 
  
 "Name" 
 : 
   
 "myvol2" 
 ,
 
  
 "Source" 
 : 
   
 "/var/lib/docker/volumes/myvol2/_data" 
 ,
 
  
 "Destination" 
 : 
   
 "/app" 
 ,
 
  
 "Driver" 
 : 
   
 "local" 
 ,
 
  
 "Mode" 
 : 
   
 "" 
 ,
 
  
 "RW" 
 : 
   
 true 
 ,
 
  
 "Propagation" 
 : 
   
 ""
 
  
 }
 
],



可以看出挂载正确,并且是可读写的。



停止容器然后删除volume


$  
 docker container stop devtest
 
 
 
 
$  
 docker container rm devtest
 
 
 
 
$  
 docker volume rm myvol2



启动一个带有volumes服务



Docker for AWS and Docker for Azure使用 Cloudstor插件 都支持持久化存储。



下面的例子启动4份nginx服务,每个使用一个本地存储myvol2。


$  
 docker service create  
 -d 
   
 \
 
  
 --replicas 
 = 
 4  
 \
 
  
 --name 
  devtest-service  
 \
 
  
 --mount 
   
 source 
 = 
 myvol2,target 
 = 
 /app  
 \
 
  nginx:latest



使用 docker service ps devtest-service  查看服务是否运行:


$  
  docker service ps devtest-service
 
 
 
  
 
 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
 
 
4d7oz1j85wwn        devtest-service.1   nginx:latest        moby                Running             Running 14 seconds ago


删除服务


$  
 docker service rm devtest-service



服务标识的不同



docker service create 
  命令不支持-v或者—volume。必须使用—mount。



使用容器加载一个volume



和上面一样,如果你启动一个容器创建一个新的volume,在容器被挂载的目录(/app/)中有文件或者文件夹,这个目录中的内容会被拷贝到volume中。然后容器挂载使用volume,其他容器使用这个volume也可以访问预加载内容。



为了说明这个,这个例子启动一个nginx容器并且加载一个新volume nginx-vol,里面包括容器中 /usr/share/nginx/html  目录中的内容,里面存储的是nginx默认的HTML内容。



—mount and -v具有相同结果
 
 
 
 
—mount:
 
$  
 docker run  
 -d 
   
 \
 
  
 --name 
 = 
 nginxtest  
 \
 
  
 --mount 
   
 source 
 = 
 nginx-vol,destination 
 = 
 /usr/share/nginx/html  
 \
 
  nginx:latest
 
 
 
 
-v
 
$  
 docker run  
 -d 
   
 \
 
  
 --name 
 = 
 nginxtest  
 \
 
  
 -v 
  nginx-vol:/usr/share/nginx/html  
 \
 
  nginx:latest



以下是运行后清理命令


$  
 docker container stop nginxtest
 
 
 
 
$  
 docker container rm nginxtest
 
 
 
 
$  
 docker volume rm nginx-vol



使用只读volume



对于一些开发应用,容器需要回写数据到Docker主机。但有时容器只需要读数据。请记住多个容器可以挂载相同volume,一个挂载读写容器,也可以挂载只读容器,还可以两种同时挂载。



这个例子修改上面的例子,但是挂载的是只读容器,使用’or’分隔符处理选项列表,



—mount and -v具有相同结果
 
 
 
 
—mount
 
$  
 docker run  
 -d 
   
 \
 
  
 --name 
 = 
 nginxtest  
 \
 
  
 --mount 
   
 source 
 = 
 nginx-vol,destination 
 = 
 /usr/share/nginx/html,readonly  
 \
 
  nginx:latest
 
 
 
 

  -v 

 
$  
 docker run  
 -d 
   
 \
 
  
 --name 
 = 
 nginxtest  
 \
 
  
 -v 
  nginx-vol:/usr/share/nginx/html:ro  
 \
 
  nginx:latest
 
 
 
 
docker inspect nginxtest
 
"Mounts" 
 : 
   
 [
 
  
 {
 
  
 "Type" 
 : 
   
 "volume" 
 ,
 
  
 "Name" 
 : 
   
 "nginx-vol" 
 ,
 
  
 "Source" 
 : 
   
 "/var/lib/docker/volumes/nginx-vol/_data" 
 ,
 
  
 "Destination" 
 : 
   
 "/usr/share/nginx/html" 
 ,
 
  
 "Driver" 
 : 
   
 "local" 
 ,
 
  
 "Mode" 
 : 
   
 "" 
 ,
 
  
 "RW" 
 : 
   
 false 
 ,
 
  
 "Propagation" 
 : 
   
 ""
 
  
 }
 
],



清理命令


$  
 docker container stop nginxtest
 
 
 
 
$  
 docker container rm nginxtest
 
 
 
 
$  
 docker volume rm nginx-vol



机器间共享数据



当构建高可用应用程序,你需要配置多个相同的服务访问相同文件。



docker vim 容器里 没有 docker volume ls_docker_02


Amazon S3。另一种是使用支持外服存储驱动(NFS,  Amazon S3 )的volume。



Volume驱动允许你在应用中抽象下层的存储系统。例如,如果你的服务使用NFS驱动volume,你可以使用不同的驱动更新服务,就像存储在云中的数据,不需要修改应用逻辑。



使用volume驱动



vieux/sshfs volume驱动



初始化设置



这个例子假设你有两个节点,第一个是Docker主机而且可以连接到第二个的ssh.



在Docker主机中安装vieux/sshfs插件:


$  
 docker plugin install  
 --grant-all-permissions 
  vieux/sshfs



使用volume驱动创建volume



这个样例指定一个SSH密码,但是如果两个主机共享keys配置,你可以省略密码。每个volume驱动可以没有或者更多配置选项,可以使用-o标识。



$  
 docker volume create  
 --driver 
  vieux/sshfs  
 \
 
  
 -o 
   
 sshcmd 
 = 
 test 
 @node2:/home/test  
 \
 
  
 -o 
   
 password 
 = 
 testpassword  
 \
 
  sshvolume



test @node2:/home/test 为远程主机挂载点



启动一个带有使用volume驱动创建volume的容器



这个样例指定一个SSH密码,但是如果两个主机共享keys配置,你可以省略密码。每个volume驱动可以没有或者更多配置选项。如果volume驱动要穿可选参数,你必须使用—mount。



$  
 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






参考: https://docs.docker.com/storage/volumes/