美文网首页
06_Docker数据卷(Volume)

06_Docker数据卷(Volume)

作者: 单v纯微笑 | 来源:发表于2021-05-09 00:23 被阅读0次

    参考资料

    Docker容器默认把数据存储到容器内部,当容器删除的时候,容器内的数据会同步删除。

    很多情况下,我们是不希望数据被删除的,常规的有2种方式能达到目的:

    1. 在删除容器之前将数据拷贝到本地。
    2. 通过数据卷把宿主机文件夹映射到容器内部,这就是数据卷。

    Docker数据卷种类和特点

    Docker数据卷(Volume)有两种:

    • 数据卷
    • 数据卷容器

    数据卷是特殊设计的目录,独立在容器的生命周期外,可以绕过联合文件系统(UnionFS),可以为一个或多个容器提供服务。

    Docker数据卷的特点:

    • 可以在容器和宿主机之间或容器与容器之间共享和重用;
    • 在容器和宿主机之间双向同步;
    • 数据卷大小不会附加到容器上;
    • 数据卷的变化,不会影响镜像的更新;
    • 会一直存在,直到没有任何容器使用它,才能使用命令docker volume rm [volumes名字]删除。

    数据卷大小不会附加到容器上,这就类似软链接。可以启动两个Tomcat,并把其中一个Tomcat的logs目录挂载进去,分别通过docker export导出,发现挂载logs目录的导出文件中logs目录没文件,未挂载logs目录的,导出文件中有文件。

    Docker数据卷

    挂载

    Docker使用-v指令挂载数据卷,挂载多个时,使用多个-v指令。

    Docker数据卷挂载常规的有3种方式:

    • 指定目录挂载
    • 匿名挂载
    • 具名挂载

    指定目录挂载

    在挂载数据卷时,指定宿主机目录:容器目录。Docker不会自动在安装目录下创建数据卷。

    • 语法
    # -v 为挂载目录选项
    docker run -v 宿主机目录:容器目录 [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    • 示例
    # 启动tomcat,并给tomcat挂载日志目录
    # -d 后台运行
    # --name tomcat 指定别名
    # -P 随机指定端口,启动后可通过docker ps命令查看映射的端口
    # -v 宿主机目录:容器目录 挂载目录到容器
    docker run -d --name tomcat -P -v /home/docker/volumes/tomcat/logs:/usr/local/tomcat/logs tomcat:8.5.57-jdk8-openjdk
    

    注意:指定目录挂载,不能使用./相对路径,可以使用~/相对路径。

    • ./ 表示当前路径下的目录;
    • ~/ 表示用户主目录,也就是登录系统后直接进入的目录。
    • 分析

    Tomcat启动后,就可以在/home/docker/volumes/tomcat/logs目录中看到有日志文件生成。

    进入容器,也能看到日志文件,说明挂载成功。

    # 进入容器内部
    # -it 交互模型运行
    # /bin/bash 以/bin/bash交互
    docker exec -it tomcat /bin/bash
    

    此时在宿主机或容器中修改文件,另外一边都能看到,说明是双向同步的。

    使用docker inspect查看容器元数据,在Mounts节点下可以看到挂载的数据卷。

    # 查看容器元数据
    
    
    # 输出
    ...
    "Mounts": [
          {
               "Type": "bind",
               "Source": "/home/docker/volumes/tomcat/logs",
               "Destination": "/usr/local/tomcat/logs",
               "Mode": "",
               "RW": true,
               "Propagation": "rprivate"
          }
    ],
    ...
    

    使用docker volume ls命令查看Docker所有挂载的数据卷,发现并没有找到这个挂载的数据卷。说明指定目录挂载方式并不会把数据卷信息存储到Docker中,也就是并不能通过具名或匿名挂载方式复用该数据卷。

    # 查看所有挂载的数据卷
    docker volume ls
    
    # 输出
    DRIVER              VOLUME NAME
    local               0ea11ee5a377263e6a62a61afdd554f12f3f61e0e69fb603794363637668f270
    local               28ad647f7dc23b3a04c96f8ba8eeca08c0766a1b2669bc42162e43ddcd585164
    local               85a5ba99cf1ca1a52e745685bede94be81f6d79e44ef108192d2d27817460331
    

    要想多个Tomcat共用这个数据卷,那么就只能重新输入完整的宿主机文件路径来挂载。

    # 复用数据卷
    # -v 后面跟的是完整的宿主机文件路径:容器目录
    docker run -d --name tomcat1 -P -v /home/docker/volumes/tomcat/logs:/usr/local/tomcat/logs tomcat:8.5.57-jdk8-openjdk
    

    匿名挂载

    在挂载数据卷时,只指定容器内部的目录。Docker会自动将数据卷用一串很长的字符命名。

    • 语法
    docker run -v 容器目录 [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    • 示例
    # 启动tomcat,并给tomcat挂载日志目录
    # -v后只指定容器内部目录
    docker run -d --name tomcat -P -v /usr/local/tomcat/logs tomcat:8.5.57-jdk8-openjdk
    
    • 分析

    使用docker volume ls命令查看,发现多了一个数据卷,数据卷名称是一串很长的字符。

    # 查看所有数据卷
    docker volume ls
    
    # 输出
    DRIVER              VOLUME NAME
    local               0ea11ee5a377263e6a62a61afdd554f12f3f61e0e69fb603794363637668f270
    local               2afdddef007505f06bc4d83bc157c2b6250661c560c7650b9bd1b2f988bd43d4
    local               28ad647f7dc23b3a04c96f8ba8eeca08c0766a1b2669bc42162e43ddcd585164
    local               85a5ba99cf1ca1a52e745685bede94be81f6d79e44ef108192d2d27817460331
    

    使用docker volume inspect 数据卷ID命令查看数据卷详情,发现数据卷在Docker目录下。

    # 查看数据卷元数据
    docker volume inspect 2afdddef007505f06bc4d83bc157c2b6250661c560c7650b9bd1b2f988bd43d4
    
    # 输出
    [
        {
            "CreatedAt": "2020-08-07T12:05:52+08:00",
            "Driver": "local",
            "Labels": null,
            "Mountpoint": "/var/lib/docker/volumes/2afdddef007505f06bc4d83bc157c2b6250661c560c7650b9bd1b2f988bd43d4/_data",
            "Name": "2afdddef007505f06bc4d83bc157c2b6250661c560c7650b9bd1b2f988bd43d4",
            "Options": null,
            "Scope": "local"
        }
    ]
    

    使用ls命令查看目录内容,发现里面有Tomcat的日志文件,说明挂载成功了。

    # 查看目录内容
    ls /var/lib/docker/volumes/2afdddef007505f06bc4d83bc157c2b6250661c560c7650b9bd1b2f988bd43d4/_data
    
    # 输出
    catalina.2020-08-07.log  host-manager.2020-08-07.log  localhost.2020-08-07.log  localhost_access_log.2020-08-07.txt  manager.2020-08-07.log
    

    使用docker volume rm 数据卷ID 删除,发现删不掉。

    # 删除数据卷
    docker volume rm 2afdddef007505f06bc4d83bc157c2b6250661c560c7650b9bd1b2f988bd43d4
    

    停止并删除容器后,发现可以删除成功,说明,只要数据卷还在被使用(或引用)就不能删除

    具名挂载

    在挂载数据卷时,指定数据卷名称:容器内部的目录。Docker会按照指定的数据卷名称命名。

    语法

    docker run -v 数据卷名称:容器目录 [OPTIONS] IMAGE [COMMAND] [ARG...]
    # 或
    docker volume create 数据卷名称
    docker run -v 数据卷名称:容器目录 [OPTIONS] IMAGE [COMMAND] [ARG...]
    

    示例

    # 启动tomcat,并给tomcat挂载日志目录
    # -v后指定数据卷名称:容器内部目录
    docker run -d --name tomcat -P -v testvolume:/usr/local/tomcat/logs tomcat:8.5.57-jdk8-openjdk
    

    具名挂载和指定目录挂载对比

    • 具名挂载:

      • 数据卷命名规则:[a-zA-Z0-9][a-zA-Z0-9_.-],只能以字母或数据开头,不能包含/~/
      • 具名挂载会在Docker目录下生成自定义名称的数据卷,可以使用docker volume ls查看。
    • 指定目录挂载:

      • 数据卷是一个完整的路径,也就是以/~/开头的。
      • 指定目录挂载不会在Docker目录下生成数据卷。

    挂载方式对比

    挂载方式 生成数据卷 命名规则 默认名称
    指定目录挂载 × - -
    匿名挂载 - 随机字符串
    具名挂载 [a-zA-Z0-9][a-zA-Z0-9_.-] 指定的名称

    Docker数据卷容器

    如果一个非常复杂的容器,需要挂载很多个数据卷。如果这个容器要同时启动多个,一个个输入很长的挂载命令很容易出错。或者多个容器之间需要共享数据,此时就推荐使用数据卷容器了。

    数据卷容器

    数据卷容器就是挂载了数据卷的容器,数据卷容器可以被别的容器挂载。

    数据卷容器的出现是为了解决容器之间数据共享问题。

    数据卷容器的优势:

    • 可以被多个容器简单的复用;
    • 与数据卷容器是否启动无关。

    数据卷容器使用

    • 语法
    docker run --volumes-from 数据卷容器 [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    • 示例

    首先根据上面的示例,准备一个数据卷容器。

    # 创建一个tomcat容器,并挂载数据卷
    docker run -d --name tomcat -P -v testvolume:/usr/local/tomcat/logs tomcat:8.5.57-jdk8-openjdk
    

    使用--volumes-from 数据卷容器指令挂载这个数据卷容器。

    # 启动tomcat,并给tomcat挂载数据卷容器
    # 使用--volumes-from,挂载数据卷容器
    docker run -d --name tomcat_link -P --volumes-from tomcat tomcat:8.5.57-jdk8-openjdk
    

    挂载多个数据卷容器时,使用多个--volumes-from 数据卷容器指令挂载。

    然后停用tomcat容器,tomcat_link容器还是能正常使用数据卷,说明数据卷容器是否启动,对使用者来说不影响。

    命令集

    挂载

    指定目录挂载

    • 语法
    # -v 为挂载目录选项
    docker run -v 宿主机目录:容器目录 [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    • 示例
    # 启动tomcat,并给tomcat挂载日志目录
    # -d 后台运行
    # --name tomcat 指定别名
    # -P 随机指定端口,启动后可通过docker ps命令查看映射的端口
    # -v 宿主机目录:容器目录 挂载目录到容器
    docker run -d --name tomcat -P -v /home/docker/volumes/tomcat/logs:/usr/local/tomcat/logs tomcat:8.5.57-jdk8-openjdk
    

    匿名挂载

    • 语法
    docker run -v 容器目录 [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    • 示例
    # 启动tomcat,并给tomcat挂载日志目录
    # -v后只指定容器内部目录
    docker run -d --name tomcat -P -v /usr/local/tomcat/logs tomcat:8.5.57-jdk8-openjdk
    

    具名挂载

    • 语法
    docker run -v 数据卷名称:容器目录 [OPTIONS] IMAGE [COMMAND] [ARG...]
    # 或
    docker volume create 数据卷名称
    docker run -v 数据卷名称:容器目录 [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    • 示例
    # 启动tomcat,并给tomcat挂载日志目录
    # -v后指定数据卷名称:容器内部目录
    docker run -d --name tomcat -P -v testvolume:/usr/local/tomcat/logs tomcat:8.5.57-jdk8-openjdk
    

    数据卷容器挂载

    • 语法
    docker run --volumes-from 数据卷容器 [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    • 示例
    # 创建一个tomcat容器,并挂载数据卷
    docker run -d --name tomcat -P -v testvolume:/usr/local/tomcat/logs tomcat:8.5.57-jdk8-openjdk
    
    # 启动tomcat,并给tomcat挂载数据卷容器
    # 使用--volumes-from,挂载数据卷容器
    docker run -d --name tomcat_link -P --volumes-from tomcat tomcat:8.5.57-jdk8-openjdk
    

    说明:被挂载的Tomcat容器为正常的数据卷容器。

    数据卷操作

    创建数据卷:docker volume create

    • 语法
    docker volume create [OPTIONS] [VOLUME]
    
    • 示例
    # 创建一个匿名数据卷
    docker volume create
    
    # 创建一个testvolume数据卷
    docker volume create testvolume
    

    查看所有数据卷:docker volume ls

    • 语法
    docker volume ls [OPTIONS]
    
    • 示例
    # 查看所有数据卷
    docker volume ls
    

    查看指定数据卷元数据:docker volume inspect

    • 语法
    docker volume inspect [OPTIONS] VOLUME [VOLUME...]
    
    • 示例
    # 查看testvolume数据卷元数据
    docker volume inspect testvolume
    

    删除数据卷:docker volume rm/prune

    • 语法
    # 删除一个或多个数据卷
    docker volume rm [OPTIONS] VOLUME [VOLUME...]
    
    # 删除所有未使用的数据卷
    docker volume prune [OPTIONS]
    
    • 示例
    # 删除testvolume数据卷
    docker volume rm testvolume
    
    # 删除所有未使用的数据卷
    docker volume prune
    

    相关文章

      网友评论

          本文标题:06_Docker数据卷(Volume)

          本文链接:https://www.haomeiwen.com/subject/iopwrltx.html