Docker数据卷

什么是数据卷(Data Volumes)?

  • 由于容器是朝生夕死的, 在生产环境中我们为了保证数据不丢失, 往往需要对数据进行持久化, 或在多个容器之间进行数据共享, 而数据卷就是解决这个需求的方案。

数据卷介绍

  • 默认位置: /var/lib/docker/volumes
  • 是容器可以访问, 但位置不在root文件系统中的一个目录。
  • 数据卷可以绕过Docker镜像的层叠机制, 从而让容器间可以共享数据。

数据卷相关操作

  1. 创建volume

    docker volume create ronnie-volume01
    
    • 执行完后就能在/var/lib/docker/volumes目录下看到新建的数据卷

      root@ronnie03:~# cd /var/lib/docker/volumes
      root@ronnie03:/var/lib/docker/volumes# ll
      total 36
      drwx------  3 root root  4096 10月 11 21:16 ./
      drwx--x--x 14 root root  4096 10月 11 19:55 ../
      -rw-------  1 root root 32768 10月 11 21:16 metadata.db
      drwxr-xr-x  3 root root  4096 10月 11 21:16 ronnie-volume01/
      
  2. 查看所有volume

    root@ronnie03:/var/lib/docker/volumes# docker volume ls
    DRIVER              VOLUME NAME
    local               ronnie-volume01
    local               ronnie-volume02
    
  3. 查看指定volume的详细信息

    root@ronnie03:/var/lib/docker/volumes# docker volume inspect ronnie-volume01
    [
        {
            "CreatedAt": "2020-10-11T21:16:12+08:00",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/ronnie-volume01/_data",
            "Name": "ronnie-volume01",
            "Options": {},
            "Scope": "local"
        }
    ]
    
    
  4. 删除volume

    root@ronnie03:/var/lib/docker/volumes# docker volume rm ronnie-volume02
    ronnie-volume02
    
  5. 启动一个挂载数据卷的容器

    • 我之前拉了一个mongo的镜像

      root@ronnie03:/var/lib/docker/volumes# docker images
      REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
      mongo               latest              ba0c2ff8d362        2 weeks ago         492MB
      
         docker run -d 
           -it 
           --name node01 
           --mount source=ronnie-volume01,target=/opt/ronnie mongo
    
    • 解释一下几个重要参数:
      • source: 要挂载的数据卷(若不存在, docker会自动创建)
      • target: 容器上目录(若不存在, docker会自动创建)
      • mongo前的: 命令还没有结束,继续等待用户进行输入,直到读到结束符。
    root@ronnie03:/var/lib/docker/volumes# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    535770cb13b7        mongo               "docker-entrypoint.s…"   28 seconds ago      Up 27 seconds       27017/tcp           node01
    
    • 我们检查一下数据卷的功能

      • 容器

      # 进入容器
      docker exec -it node01 /bin/bash
      
      # 查看目录
      root@535770cb13b7:/# cd /opt/ronnie/
      root@535770cb13b7:/opt/ronnie# ll
      total 8
      drwxr-xr-x 2 root root 4096 Oct 11 13:16 ./
      drwxr-xr-x 1 root root 4096 Oct 11 14:31 ../
      
      # 创建一个test.csv文件
      root@535770cb13b7:/opt/ronnie# touch test.csv
      root@535770cb13b7:/opt/ronnie# ll
      total 8
      drwxr-xr-x 2 root root 4096 Oct 11 14:43 ./
      drwxr-xr-x 1 root root 4096 Oct 11 14:31 ../
      -rw-r--r-- 1 root root    0 Oct 11 14:43 test.csv
      
      • 主机

        root@ronnie03:/var/lib/docker/volumes/ronnie-volume01/_data# cd /var/lib/docker/volumes/ronnie-volume01/_data
        root@ronnie03:/var/lib/docker/volumes/ronnie-volume01/_data# ll
        total 8
        drwxr-xr-x 2 root root 4096 10月 11 22:43 ./
        drwxr-xr-x 3 root root 4096 10月 11 21:16 ../
        -rw-r--r-- 1 root root    0 10月 11 22:43 test.csv
        
        • 这时候我们看到主机的数据卷目录下的_data目录中就有了一个test.csv文件
  6. 数据卷容器

    • 如果用户需要在多个容器之间共享一些持续更新的数据, 最简单的方式是使用数据卷容器。

    • 数据卷容器也是一个容器, 不过它的目的是专门提供数据卷给其他容器挂载

    • 相关操作:

      1. 创建数据卷容器

        # 删了之前的镜像及数据卷
        docker stop node01
        docker rm node01
        docker volume rm ronnie-volume01
        docker volume rm ronnie-volume02
        
        # 拉了个centos:7 镜像, 用它作为数据卷容器比较合适
        docker run -di --name db_data -v /opt/ronnie centos:7
        
      2. 用容器测试数据卷容器是否可用

        # 数据卷
        docker exec -it db_data /bin/bash
        cd /opt/ronnie
        
        # node01
        docker run -di --name node01 --volumes-from db_data mongo
        docker exec -it node01 /bin/bash
        cd /opt/ronnie
        
        # node02
        docker run -di --name node02 --volumes-from db_data mongo
        docker exec -it node02 /bin/bash
        cd /opt/ronnie
        
        • 这时候我们就可以看到三个容器了

          root@ronnie03:~# docker ps
          CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
          be237f236571        mongo               "docker-entrypoint.s…"   About a minute ago   Up About a minute   27017/tcp           node01
          a10ce2195d43        mongo               "docker-entrypoint.s…"   2 minutes ago        Up 2 minutes        27017/tcp           node02
          fecb361c3e8c        centos:7            "/bin/bash"              2 minutes ago        Up 2 minutes                            db_data
          
        • 我们在node01上touch一个test.csv文件, 然后就能发现在数据卷容器的/opt/ronnie目录及node02的/opt/ronnie下发现test.csv文件

          # node01
          root@be237f236571:/opt/ronnie# touch test.csv
          root@be237f236571:/opt/ronnie# ll
          total 8
          drwxr-xr-x 2 root root 4096 Oct 11 20:49 ./
          drwxr-xr-x 1 root root 4096 Oct 11 20:44 ../
          -rw-r--r-- 1 root root    0 Oct 11 20:49 test.csv
          
          # volume
          [root@fecb361c3e8c ronnie]# ll  
          total 0
          -rw-r--r-- 1 root root 0 Oct 11 20:49 test.csv
          
          # node02
          root@a10ce2195d43:/opt/ronnie# ll
          total 8
          drwxr-xr-x 2 root root 4096 Oct 11 20:49 ./
          drwxr-xr-x 1 root root 4096 Oct 11 20:43 ../
          -rw-r--r-- 1 root root    0 Oct 11 20:49 test.csv
          

--mount选项的三种数据卷

  • type = volume 即普通数据卷, 映射到主机/var/lib/docker/volumes目录下

    --mount type=volume,source=ronnie-volume01,target=/opt/ronnie
    
  • type = bind 即绑定数据卷, destination为要绑定的主机指定路径

    --mount type=bind,source=/opt/ronnie,destination=/opt/ronnie
    
  • type = tmpfs 即临时数据卷, 只存在于内存中

    docker run -d 
                  -it 
                  --name ronnie_tmp_volume 
                  --mount type=tmpfs,destination=/opt/ronnie 
                  mongo
    

一些注意点

  • 数据卷是被设计用来持久化数据的, 所以它的生命周期独立于容器, 而docker不会在容器被删除后自动删除数据卷, 并且也没有垃圾回收机制来处理没有任何容器引用的数据卷, 所以无主的数据卷可能占据很多空间, 需要及时删除
  • 挂载数据卷,最好是通过run而非create/start创建启动容器
  • create/start命令创建启动容器后,再挂载数据卷相当麻烦,要修改很多配置文件
原文地址:https://www.cnblogs.com/ronnieyuan/p/13800661.html