docker系列-05数据挂载
seefly
seefly
发布于 2020-04-03 / 3 阅读 / 0 评论 / 0 点赞

docker系列-05数据挂载

    • Docker中的数据挂载

      一、概念

      引用

      • Docker 镜像时由多个文件系统(只读层)叠加而成。当我们启动一个容器的时候,Docker会加载只读镜像层并在其上添加一个读写曾。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在并未改变(这可能就是Docker说的copy on wirte),只是被读写层中的副本隐藏掉了,当删除容器,再通过同一个镜像再次启动的时候,之前的修改就丢失了,在Docker中,只读层及在顶部的读写层的组合被成为UnionFile System(UFS联合文件系统)
      • Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume)。数据卷可以用来存储Docker应用的数据,亦可以用来在Docker容器间共享数据。数据呈现给Docker容器的形式就是一个目录,支持多个容器间共享,修改也不会影响镜像。使用DOcker数据卷,类似在系统中使用mount挂载一个文件系统。
      • 为了能够保存数据或者容器间共享数据,Docker提出了Volume概念,简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。

      二、创建数据卷

      • 方式一:使用命令创建
      # 事先创建一个名为myVolume的数据卷,该数据卷会保存在宿主机/var/lib/docker/volumes目录下
      docker volume create myVolume
      
      # 在创建容器的时候可以指定使用该数据卷,并绑定到容器中指定的目录
      docker run -it -v myVolume:/ab -p 9898:80 --name mynginx nginx:latest /bin/bash
      
      # 或者直接在启动容器的时候创建数据卷,不用事先准备,也不会报错
      docker run -it -v hisVolume:/ab -p 9898:80 --name mynginx nginx:latest /bin/bash
      
      • 方式二:使用默认数据卷 上面的方式是先创建,再使用,我们可以不实现准备好,使用默认的。
      # 直接 -v /ab 就是,容器中的/ab目录挂载到宿主机的匿名数据卷中
      [ech@centos-10 _data]$ docker run -it -v /ab -p 9898:80 --name mynginx nginx:latest /bin/bash
      # 进入该目录
      root@98c7ed71827c:/# cd /ab
      # 添加一个文件
      root@98c7ed71827c:/ab# echo "hello volume!" > hello.txt
      # 退出
      root@98c7ed71827c:/ab# exit
      exit
      # 查看该容器对应默认数据卷在哪
      [ech@centos-10 _data]$ docker inspect mynginx | grep /var/lib/docker/volumes/
                      "Source": "/var/lib/docker/volumes/2c6723ead7638ff16ca6b2625871480f57ad7815c84b086c46dd0c132dcb23b9/_data",
      # 进入该目录
      [ech@centos-10 _data]$ cd /var/lib/docker/volumes/2c6723ead7638ff16ca6b2625871480f57ad7815c84b086c46dd0c132dcb23b9/_data
      # 在容器中创建的文件在宿主机中找到了
      [ech@centos-10 _data]$ ls
      hello.txt
      [ech@centos-10 _data]$ cat hello.txt 
      hello volume!
      
      

      三、挂载宿主机文件(夹)到容器

      这就相当于是一个文件映射,将宿主机的文件映射到容器中,可以在docker run 的时候通过-v命令来指定

      # 将本机opt目录映射到容器中的opt目录,这样以来,在容器中对opt目录下的操作都会反映到宿主机上
      docker run -it -v /opt:/opt --name nginx:latest mynginx /bin/bash
      # 给文件设置权限,ro = readonly
      docker run -it -v /opt:/opt:ro --name nginx:latest mynginx /bin/bash
      # 可以通过多个-v来同时挂载多个文件
      docker run -it -v /opt:/opt:ro -v /a:/a:ro --name nginx:latest mynginx /bin/bash
      

      注意:如果指定的宿主机目录不存在或者容器中的路径不存在都会被docker直接创建

      四、在Dockerfile中配置挂载

      由于Dockerfile可能运行在各种系统中,如果像docker run中使用-v指令那样配置volume,可能会出问题,例如linux和windows的路径就不一样。所以在Dockerfile只能声明匿名挂载卷,并在Dockerfile中声明的挂载卷会被应用在使用该Dockerfile的各个容器上,注意,虽然用的是一个Dockerfile但是各个容器实例在宿主机上的挂载卷可不一样!!

      FROM ubuntu
      # 这就相当于是 docker run -v /data1 -v /data2,创建匿名数据卷
      VOLUME ["/data1","/data2"]
      

评论