一、数据卷(Data Volumes)
   为了很好的实现数据保存和数据共享,Docker提出了Volume这个概念,简单的说就是绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。又被称作数据卷。 
 
 
  
 
   数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS(联合文件系统), 
  可以提供很多有用的特性: 
 
 
 -  
   数据卷可以在容器之间共享和重用
-  
   对数据卷的修改会立马生效
-  
   对数据卷的更新,不会影响镜像
-  
   数据卷 默认会一直存在,即使容器被删除
   volume的容量取决于docker host文件系统当前未使用的空间, 
  目前无法设置volume的容量。 
  。 
 
 
  
 
   有关数据挂载的指令: 
 
 
  
 
  
 
 二、Docker数据持久化的三种方式
Docker提供了三种不同的方式将数据从宿主机挂载到容器中:volume、bind mounts、tmpfs mounts
-  
    volume:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)
-  
    bind mounts:可以存储在宿主机系统的任意位置
-  
    tmpfs mounts:挂载存储在宿主机的内存中,不会写入宿主机的文件系统
2.1、volume(普通数据卷)
   Docker管理宿主机 
  文件系统的一部分(/var/lib/docker/volumes) 
 
 
  
   # 创建volume数据卷,注意:创建数据卷后,会在本机的/var/lib/docker/volumes目录下创建相应的文件夹 
  
 
   
   docker volume create for_nginx 
  
 
   
 
   
   # 查看创建的volume 
  
 
   
   docker volume ls 
  
 
   
   
   # 运行容器并挂载(nginx为例) 
  
 
   
   docker run --name nginx -d -p 8070:80 --mount type=volume,source=for_nginx,target=/usr/share/nginx/html nginx 
  
 
   
   注意:运行完容器后,会在本机相应的目录中会将容器内相关目录中的文件挂载出来。如下图,宿主机上出现了两个html文件,是创建nginx容器时生成的文件: 
  
 
   
 
   
 
   
   # 进入容器内部 
  
 
   
   docker exec -it 84608669dfc0 /bin/bash 
  
 
   
   # cd到具体目录 
  
 
   
   cd /usr/share/nginx/html/ 
  
 
   
   # 创建一个test.html文件 
  
 
   
   echo "container write info" > test.html 
  
 
   
 
  2.2、bind mounts(绑定数据卷,挂载主机目录)
   可以存储在宿主机 
  系统的任意位置。 
 
 
 
   bind mount 
  默认权限是读写 rw ,可以在挂载时指定只读 ro 
 
 
  
   bind mount是将host上已存在的目录或文件mount到容器。 
  
 
   
   
   #  在宿主机上创建相应目录 
  
 
   
   mkdir -p /home/docker/volumes/nginx 
  
 
   
   
   #  运行容器并挂载 
  
 
   
   # 运行容器并设置挂载(正常方式)  
  
 
   
   docker run --name nginx1 -d -p 8090:80 --mount type=bind,source=/home/docker/volumes/nginx,target=/usr/share/nginx/html nginx 
  
 
   
   # 运行容器并设置挂载(-v方式)简写 
  
 
   
   docker run --name mynginx1 -d -p 8090:80 -v /home/docker/volumes/nginx:/usr/share/nginx/html:rw nginx 
  
 
  -  
    -v <host path>:<container path> 若container path已经存在,原有的数据会被隐藏,取而代之的是host path中的数据
 
 
   
   进入到相应目录后会发现,没有任何文件。 
  
 
   
   
   注意:如果你使用bind mounts挂载宿主机目录到一个容器中的非空目录,那么此容器中非空目录中的文件会被清空,容器中访问的这个目录直接就是宿主机上的相应挂载目录。 
  
 
 2.3、tmpfs mounts(临时数据卷)
   挂载存储在宿主机的内存中, 
  不会写入宿主机的文件系统. 
 
 
  
  注意:删除容器重新创建容器后发现数据丢失,临时卷无法持久化数据 
 
 
  
   # 挂载方式运行容器 
  
 
   
   docker run --name nginx -d -p 8070:80 --mount type=tmpfs,target=/usr/share/nginx/html nginx 
  
 
   
   # 进入容器 
  
 
   
   docker exec -it 969cb895b621 /bin/bash 
  
 
   
   # cd到具体目录 
  
 
   
   cd /usr/share/nginx/html/ 
  
 
   
 
   
   # 创建test.html文件 
  
 
   
   echo "container write info" > test.html 
  
 
   
 
  2.4、数据卷容器
 
   专门用来管理数据卷的容器,该容器主要供其他容器引用和使用。 
  
 
   
   
   # 创建数据卷容器 
  
 
   
   docker run -itd -v /usr/share/nginx/html/:/usr/share/nginx/html/ --name mydata ubuntu 
  
 
   
   
   # 容器引用创建的数据卷容器mydata 
  
 
   
   docker run -itd --volumes-from mydata -p 80:80 --name nginx1 nginx 
  
 
   
   docker run -itd --volumes-from mydata -p 81:80 --name nginx2 nginx 
  
 
   
   nginx1与nginx2都挂载了同一个数据卷到/usr/share/nginx/html/目录下,三个容器,任意一个修改该目录下的文件,其他两个都能看到变化 
  
 
  
  数据卷其他操作 
 
 
  
   1、Dockerfile里设置数据卷: 
  
 
   
   VOLUME /usr/share/nginx/html/ 
  
 
   
   2、查看所有数据卷 
  
 
   
   docker volume ls 
  
 
   
   3、查看数据卷详情 
  
 
   
   docker volume inspect volume_id 
  
 
   
   4、删除数据卷(需先将相关容器停止移除,才能删除卷) 
  
 
   
   docker volume rm 数据卷名称 
  
 
 三、总结
 
  volumes: 
 
 
 -  
   需要创建docker volume,docker volume的 存储是在docker安装目录内, 卸载docker会丢失。
-  
   创建容器时 会将容器内文件映射到docker volume的相应目录上 ,并且不管宿主机还是容器内操作挂载目录中的文件都是互通的。
-  
   多个运行容器间共享数据,备份、恢复、或将数据从一个Docker主机迁移到另一个Docker主机时。
 
  bind mount: 
 
 
 -  
   需要手动在宿主机上创建挂载的目录(或者利用现有的), 数据直接存在了宿主机硬盘上 ,删除容器或者卸载docker,数据并不会消失。
-  
   创建容器时 ,会将宿主机上目录上的文件覆盖容器内的相应目录 ,所以此方法挂载需要预先将容器内相应被挂载目录的文件复制出来.
-  
   主机与容器共享配置文件(Docker默认情况下通过这种方式为容器提供DNS解析,通过将/etc/resolv.conf挂载到容器中)
-  
   命令有简写的 -v 方式.
 
  tmpfs mount: 
 
 
 -  
   既不想将数据存于主机,又不想存于容器中时(这可以是出于安全的考虑,或当应用需要写大量非持久性的状态数据时为了保护容器的性能)。
四、特殊文件名(1199:683b)挂载导致的docker启动容器失败
挂载的文件名1199:683b比较特殊,-v以:分隔,会把:后的当成mode,举例如下:
docker run -it --rm -v /home/abc:dd:/home/abc ubuntu:18.04 /bin/bash

使用bind mounts的正常方式指令:
docker run -it --rm --mount type=bind,source=/home/abc:dd,target=/home/aa.py ubuntu:18.04 /bin/bash

之前的:

修改后的:



















