GVKun编程网logo

Docker 实战 10 之初识 volume(docker --volumes-from)

22

想了解Docker实战10之初识volume的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于docker--volumes-from的相关问题,此外,我们还将为您介绍关于Docker-命令-

想了解Docker 实战 10 之初识 volume的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于docker --volumes-from的相关问题,此外,我们还将为您介绍关于Docker - 命令 - docker volume、Docker - 命令 - volume 相关、docker -v 和Dockerfile 中VOLUME 区别、Docker 0x06: Docker Volume卷的新知识。

本文目录一览:

Docker 实战 10 之初识 volume(docker --volumes-from)

Docker 实战 10 之初识 volume(docker --volumes-from)

Volume
提供独立于容器之外的持久化存储


第一种方式

运行时加入 -v 指定保存目录
运行后保存容器中的某个目录下的文件到本地服务器

运行
docker run -d -p 8080:80 -v /usr/share/nginx/html hub.c.163.com/library/nginx


docker ps
CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS                    NAMES
b1de38756a14        hub.c.163.com/library/nginx          "nginx -g ''daemon of…"   7 minutes ago       Up 7 minutes        0.0.0.0:8080->80/tcp     inspiring_snyder
c71cf6554cc0        hub.c.163.com/library/mysql:latest   "docker-entrypoint.s…"   6 hours ago         Up 6 hours          0.0.0.0:3306->3306/tcp   kind_stallman


检查镜像
docker inspect b1de38756a14
[
    {
        "Id": "b1de38756a14112876e741be54f748b3574ea28e313e8804b6c37e4a2e66d7f7",
        "Created": "2018-06-10T16:40:29.32542017Z",
        "Path": "nginx",
        "Args": [
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 72359,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2018-06-10T16:40:29.767102986Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:46102226f2fd547f5bbabfcd3dac62cd0d3b7cc33a37a40dae38e088fbb70a38",
        "ResolvConfPath": "/var/lib/docker/containers/b1de38756a14112876e741be54f748b3574ea28e313e8804b6c37e4a2e66d7f7/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/b1de38756a14112876e741be54f748b3574ea28e313e8804b6c37e4a2e66d7f7/hostname",
        "HostsPath": "/var/lib/docker/containers/b1de38756a14112876e741be54f748b3574ea28e313e8804b6c37e4a2e66d7f7/hosts",
        "LogPath": "/var/lib/docker/containers/b1de38756a14112876e741be54f748b3574ea28e313e8804b6c37e4a2e66d7f7/b1de38756a14112876e741be54f748b3574ea28e313e8804b6c37e4a2e66d7f7-json.log",
        "Name": "/inspiring_snyder",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {
                "80/tcp": [
                    {
                        "HostIp": "",
                        "HostPort": "8080"
                    }
                ]
            },
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "shareable",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DiskQuota": 0,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": 0,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/286c66161a6c3a177443531f6b2498dfc758a0cdf968fc80e9b55ee4dd2ae805-init/diff:/var/lib/docker/overlay2/7ccd9884a6415246657126945aaafe0ca5dc7f441008621063bcb864a1103a4a/diff:/var/lib/docker/overlay2/514740a8bee43934b08595850a04e851081511e29784cc15864fc8a895720126/diff:/var/lib/docker/overlay2/099aee435090164e3800975f5e898741bd2d4a9fb612bf0d161c36ccce71ffdc/diff",
                "MergedDir": "/var/lib/docker/overlay2/286c66161a6c3a177443531f6b2498dfc758a0cdf968fc80e9b55ee4dd2ae805/merged",
                "UpperDir": "/var/lib/docker/overlay2/286c66161a6c3a177443531f6b2498dfc758a0cdf968fc80e9b55ee4dd2ae805/diff",
                "WorkDir": "/var/lib/docker/overlay2/286c66161a6c3a177443531f6b2498dfc758a0cdf968fc80e9b55ee4dd2ae805/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "volume",
                "Name": "bfaea3344c46ea20f456ba21404c3a61495729b0ca882d2a46932f3be0127bcc",
                "Source": "/var/lib/docker/volumes/bfaea3344c46ea20f456ba21404c3a61495729b0ca882d2a46932f3be0127bcc/_data",
                "Destination": "/usr/share/nginx/html",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "b1de38756a14",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.13.0-1~stretch",
                "NJS_VERSION=1.13.0.0.1.10-1~stretch"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "ArgsEscaped": true,
            "Image": "hub.c.163.com/library/nginx",
            "Volumes": {
                "/usr/share/nginx/html": {}
            },
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {},
            "StopSignal": "SIGQUIT"
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "e7a83bae8e08e242c713691975d0357d8ce730c6ed5316cf9b9da34d8b663608",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "8080"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/e7a83bae8e08",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "dc8e990f9d404aeacd60296996effc54dc5c823f4b680901af18d7c6dff8da5d",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "e8e4805fcf95e9463bcb3a5adad4de6f9f462f564578873537ce8dfedc419759",
                    "EndpointID": "dc8e990f9d404aeacd60296996effc54dc5c823f4b680901af18d7c6dff8da5d",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

cd /var/lib/docker/volumes/bfaea3344c46ea20f456ba21404c3a61495729b0ca882d2a46932f3be0127bcc/_data
vim index.html

修改后的内容,不拉不拉・・・

进入镜像内部目录
docker exec -it b1de38756a14 /bin/bash

cd /usr/share/nginx/html
ls
50x.html  index.html

cat index.html
与服务器中的 index.html 是一致的
即这里的文件对应的就是 /var/lib/docker/volumes/bfaea3344c46ea20f456ba21404c3a61495729b0ca882d2a46932f3be0127bcc/_data 目录下的文件

 


第二种方式

本地目录挂载到镜像中
docker run -d -p 80:80 -v $PWD/html:/var/www/html nginx

说明:$PWD 指向当前目录


第三种方式

docker run --volumes-from ...

Docker - 命令 - docker volume

Docker - 命令 - docker volume

  1. 概述

    1. docker volume 命令
  2. 背景

    1. docker 容器的存储,通常需要独立于镜像
    2. docker volume 就是负责这块的命令

1. 写在 docker volume 之前

  1. 概述

    1. docker run 与 volume 相关的介绍
  2. 背景

    1. 其实在使用 docker [container] run 的时候,我们已经在使用 volume 了
  3. volume

    1. 概述

      1. 类似
        1. linux 里的 卷
        2. windows 里的 盘
    2. 作用

      1. 对接其他设备
      2. 拓展存储空间
      3. 隔离存储区域
      4. 对数据的迁移,复用,也有支持

1. 首先,这个不是 volume

  1. 概述

    1. docker run -v 中,本地目录 与 容器路径 对接,不是 volume
  2. 命令

    > docker run --name some-nginx1 -v $(pwd)/html:/usr/share/nginx/html -d nginx
    
  3. 结果

    1. 容器成功启动
    2. 容器的 ''/usr/share/nginx/html'' 目录,与 宿主机 的 ''$(pwd)/html'' 目录,成功关联
    3. 但是
      1. 并没有创建 volume
  4. 验证

    1. docker container inspect

      1. HostConfig 下
        1. Volumes 字段,值为 null
    2. docker volume ls

      1. 无法查到 新的 volume
  5. 特性

    1. 触发

      1. 填写路径时,需要用以下方式触发
        1. /
        2. ~/
    2. 路径

      1. host 上如果不存在,主动创建
      2. container 上如果不存在,主动创建
    3. 覆盖

      1. 如果冲突,则以 host 为准

2. 然后,我们开始使用 volume

  1. 概述

    1. 在 docker run 中使用 volume
  2. 位置

    1. 路径

      # 默认位置
      /var/lib/docker/volumes
      # 具体位置, 可以通过 docker container inspect 查看
      
  3. 命令

    > docker run --name some-nginx2 -v html:/usr/share/nginx/html -d nginx
    
  4. 结果

    1. 容器启动成功
    2. 在 volume 的默认路径下,创建了一个 volume
      1. 名为 html
    3. html 与 容器的路径 绑定成功
  5. 验证

    1. docker volume ls
      1. 可以查看到新的 volume
  6. 其他

    1. volume 名称
      1. 如果不指定,会随机生成

        > docker run --name some-nginx2 -v /usr/share/nginx/html -d nginx
        
    2. volume 权限
      1. 权限

        1. 只读
        2. 读写
      2. 指定

        # 默认为 rw
        -v html:/usr/share/nginx/html[:ro|:rw]
        

3. volumes-from

  1. 概述

    1. 创建新容器时,使用和另一个容器相同的挂载策略
  2. 场景

    1. 容器 d1
      1. 有自己的卷
    2. 容器 d2
      1. 继承 d1 的卷
  3. 命令

    1. d1

    2. d2

      > docker container run --name d2 --volumes-from d1 -d nginx
      
  4. 埋个坑

    1. 参考里创建 d1 的时候,没有带 -v

      1. 创建 d2 也没问题
      2. docker container inspect 查看时,也能正确查看到
      3. 但是这个继承,到底有没有意义
        1. 还是说,容器起来的时候,临时读写层,也被视为了 volume?
    2. volume 的生命周期

      1. 例子里说了这么个情况
        1. d1 创建,有了 volume v1
        2. d2 volumes-from 了 d1, 使用了 同样的 v1
        3. d1 关闭了,volume 不受影响
        4. d2 关闭,没有容器使用 v1,
        5. 然后 v1 的生命周期结束了
      2. 疑问
        1. 什么是 volume 的生命周期
        2. 我试过所有容器都结束,甚至删掉的情况
          1. -v 创建的卷,依然存在
          2. 那结束,又是怎么个回事

2. docker volume

1. 概述

  1. docker volume 命令
    1. 有了上面的认识,后续的理解,会方便很多

2. 命令们

  1. ls

    1. 概述

      1. 查看卷列表
    2. 命令

      # 返回 driver 信息 和 volume 的名称
      > docker volume ls
      
  2. inspect

    1. 概述

      1. 查看卷详情
    2. 命令

      # 稍微详细的信息, 不细说了
      > docker volume inspect <volumeName>
      
  3. create

    1. 概述

      1. 创建卷
    2. 命令

      # 在默认位置, 创建一个名为 volumeName 的卷
      # 卷 不能重名
      # 创建完之后, 可以用 volumeName 在 创建容器时挂载
      > docker volume crreate <volumeName>
      
  4. rm

    1. 概述

      1. 删除卷
    2. 命令

      # 删除卷
      > docker volume rm <volumeName> 
      
  5. prune

    1. 概述

      1. 删除 闲置卷
    2. 命令

      # 删除没有挂载的卷
      > docker volume prune
      

ps

  1. ref

    1. docker 容器与容器云
      1. 问题
        1. 这本书没把 bind 和 volume 区分得很开
    2. Docker 学习笔记(6)——Docker Volume
      1. advantage
        1. 区分了 bind mount 和 volume
      2. disadvantage
        1. 没有 ref 作为支持
    3. docker 入门 —— docker 容器数据卷 volumes-from
  2. 问题 1: 是否有 mount 之类的命令

    1. 条件
      1. 运行之中
  3. 问题 2: 上面提到的一些问题

    1. 概述
      1. 需要验证
  4. 问题 3: 卷能独立于文件系统

    1. 概述

      1. 在书上看到有书这么说,但是我想不明白
      2. 我所创建的卷,都是在本地,文件系统,是由 /var 那个盘决定的
      3. 如果要触发,需要什么条件
        1. 将 /var 挂载为其他目录
        2. 指定 卷存放的位置,到其他的文件系统
    2. 感觉是个坑,以后得填上

Docker - 命令 - volume 相关

Docker - 命令 - volume 相关

  1. 概述
    1. docker volume 命令
  2. 背景
    1. docker 容器的存储, 通常需要独立于镜像
    2. docker volume 就是负责这块的命令

1. 写在 docker volume 之前

  1. 概述
    1. docker run 与 volume 相关的介绍
  2. 背景
    1. 其实在使用 docker [container] run 的时候, 我们已经在使用 volume 了
  3. volume
    1. 概述
      1. 类似
        1. linux 里的 卷
        2. windows 里的 盘
    2. 作用
      1. 对接其他设备
      2. 拓展存储空间
      3. 隔离存储区域
      4. 对数据的迁移, 复用, 也有支持

1. 首先, 这个不是 volume

  1. 概述
    1. docker run -v 中, 本地目录 与 容器路径 对接, 不是 volume
  2. 命令

    > docker run --name some-Nginx1 -v $(pwd)/html:/usr/share/Nginx/html -d Nginx
  3. 结果
    1. 容器成功启动
    2. 容器的 '/usr/share/Nginx/html' 目录, 与 宿主机 的 '$(pwd)/html' 目录, 成功关联
    3. 但是
      1. 并没有创建 volume
  4. 验证
    1. docker container inspect
      1. HostConfig 下
        1. Volumes 字段, 值为 null
    2. docker volume ls
      1. 无法查到 新的 volume
  5. 特性
    1. 触发
      1. 填写路径时, 需要用以下方式触发
        1. /
        2. ~/
    2. 路径
      1. host 上如果不存在, 主动创建
      2. container 上如果不存在, 主动创建
    3. 覆盖
      1. 如果冲突, 则以 host 为准

2. 然后, 我们开始使用 volume

  1. 概述
    1. 在 docker run 中使用 volume
  2. 位置
    1. 路径

      # 默认位置
      /var/lib/docker/volumes
      # 具体位置, 可以通过 docker container inspect 查看
  3. 命令

    > docker run --name some-Nginx2 -v html:/usr/share/Nginx/html -d Nginx
  4. 结果
    1. 容器启动成功
    2. 在 volume 的默认路径下, 创建了一个 volume
      1. 名为 html
    3. html 与 容器的路径 绑定成功
  5. 验证
    1. docker volume ls
      1. 可以查看到新的 volume
  6. 其他
    1. volume 名称
      1. 如果不指定, 会随机生成

        > docker run --name some-Nginx2 -v /usr/share/Nginx/html -d Nginx
    2. volume 权限
      1. 权限
        1. 只读
        2. 读写
      2. 指定

        # 默认为 rw
        -v html:/usr/share/Nginx/html[:ro|:rw]

3. volumes-from

  1. 概述
    1. 创建新容器时, 使用和另一个容器相同的挂载策略
  2. 场景
    1. 容器 d1
      1. 有自己的卷
    2. 容器 d2
      1. 继承 d1 的卷
  3. 命令
    1. d1
    2. d2

      > docker container run --name d2 --volumes-from d1 -d Nginx
  4. 埋个坑
    1. 参考里创建 d1 的时候, 没有带 -v
      1. 创建 d2 也没问题
      2. docker container inspect 查看时, 也能正确查看到
      3. 但是这个继承, 到底有没有意义
        1. 还是说, 容器起来的时候, 临时读写层, 也被视为了 volume?
    2. volume 的生命周期
      1. 例子里说了这么个情况
        1. d1 创建, 有了 volume v1
        2. d2 volumes-from 了 d1, 使用了 同样的 v1
        3. d1 关闭了, volume 不受影响
        4. d2 关闭, 没有容器使用 v1,
        5. 然后 v1 的生命周期结束了
      2. 疑问
        1. 什么是 volume 的生命周期
        2. 我试过所有容器都结束, 甚至删掉的情况
          1. -v 创建的卷, 依然存在
          2. 那结束, 又是怎么个回事

2. docker volume

1. 概述

  1. docker volume 命令
    1. 有了上面的认识, 后续的理解, 会方便很多

2. 命令们

  1. ls
    1. 概述
      1. 查看卷列表
    2. 命令

      # 返回 driver 信息 和 volume 的名称
      > docker volume ls
  2. inspect
    1. 概述
      1. 查看卷详情
    2. 命令

      # 稍微详细的信息, 不细说了
      > docker volume inspect <volumeName>
  3. create
    1. 概述
      1. 创建卷
    2. 命令

      # 在默认位置, 创建一个名为 volumeName 的卷
      # 卷 不能重名
      # 创建完之后, 可以用 volumeName 在 创建容器时挂载
      > docker volume crreate <volumeName>
  4. rm
    1. 概述
      1. 删除卷
    2. 命令

      # 删除卷
      > docker volume rm <volumeName> 
  5. prune
    1. 概述
      1. 删除 闲置卷
    2. 命令

      # 删除没有挂载的卷
      > docker volume prune

ps

  1. ref
    1. docker 容器与容器云
      1. 问题
        1. 这本书没把 bind 和 volume 区分得很开
    2. Docker学习笔记(6)——Docker Volume
      1. advantage
        1. 区分了 bind mount 和 volume
      2. disadvantage
        1. 没有 ref 作为支持
    3. docker 入门 —— docker容器数据卷volumes-from
  2. 问题1: 是否有 mount 之类的命令
    1. 条件
      1. 运行之中
  3. 问题2: 上面提到的一些问题
    1. 概述
      1. 需要验证

docker -v 和Dockerfile 中VOLUME 区别

docker -v 和Dockerfile 中VOLUME 区别

在学习Dockerfile的过程中有个VOLUME命令,很多教程或书中说的是用来定义匿名卷的,其作用如下:
  容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。

这令我们想起docker的run命令中的 "-v"参数的作用

# docker run --help | grep volume
  -v, --volume list                    Bind mount a volume
      --volume-driver string           Optional volume driver for the container
      --volumes-from list              Mount volumes from the specified

那么Dockerfile中的VOLUME指令实际使用中是不是就是跟docker run中的-v参数一样是将宿主机的一个目录绑定到容器中的目录以达到共享目录的作用呢?
并不然,其实VOLUME指令只是起到了声明了容器中的目录作为匿名卷,但是并没有将匿名卷绑定到宿主机指定目录的功能。
但是当我们生成镜像的Dockerfile中以Volume声明了匿名卷,并且我们以这个镜像run了一个容器的时候,docker会在安装目录下的指定目录下面生成一个目录来绑定容器的匿名卷(这个指定目录不同版本的docker会有所不同)。如我使用的版本如下:

# docker --version
Docker version 18.09.0, build 4d60db4    //docker版本
# pwd
/var/lib/docker/volumes          //默认绑定容器的匿名卷的目录
# ll
total 32
drwxr-xr-x. 3 root root  4096 Nov 25 20:18 593fda6d7b8296bfca22894b326727c734133eebb11c9bc2c25a73b892157a37  //其中一个容器的共享目录文件夹
drwxr-xr-x. 3 root root  4096 Nov 25 20:14 78d890eeb15ac6295484d5e84e97928e981b01501fa40bac40b965fc9e54899a  //其中一个容器的共享目录文件夹
-rw-------. 1 root root 32768 Nov 25 20:18 Metadata.db

就是说当Dockerfile中声明了匿名卷,但是run的时候没有使用-v绑定匿名卷的话,那么docker就会在/var/lib/docker/volumes这个目录下创建一个目录来绑定匿名卷。
所以真正使用的时候我们在Dockerfile构建镜像的时候如:

FROM centos:latest
RUN groupadd -r redis && useradd  -r -g redis redis
RUN yum -y update &&  yum -y install epel-release && yum -y install redis && yum -y install net-tools
RUN mkdir -p /config && chown -R redis:redis /config
VOLUME /share/data      #声明容器中/share/data为匿名卷
EXPOSE 6379

那么使用该Dockerfile构建镜像的为

# docker build -t image-redis    //构建镜像image-redis
......
#docker run -d -it -name redis1 -v /data:/share/data image-redis    //运行一个容器并且将当前机器的/data目录绑定到容器的匿名卷中
.....
#docker run -d -it  -name redis2 image-redis   //运行一个容器但是不绑定目录到容器的匿名卷,这时候再/var/lib/docker/volumes(不同版本目录不一样)中就会创建一个目录绑定匿名卷

Docker 0x06: Docker Volume卷

Docker 0x06: Docker Volume卷

Docker Volume卷

[toc]

在容器技术介绍篇,我们提到过容器的难点在构建网络和文件存储。容器的文件系统虽然可以保存数据,但是容器中的,容器本身是不可迁移的,只能导出其中的文件系统,但是导出文件系统不是迁移容器的最佳实践,最佳实践是镜像。但是镜像是静态数据。改变容器文件系统的东西是不会影响到镜像的。所以就有了挂在volume实践。在build应用镜像的时候,就通过VOLUME给容器创建挂载点,可以挂在宿主机的卷或者其它容器的卷。至此,我们知道了为什么要有volume,因为要持久化容器产生的数据。那本文将说明docker volume是什么,怎么使用挂载,容器间共享同步,迁移备份还原数据。

一句话什么是docker volume?

docker volume是docker容器对应使用的外界存储。

docker volume特性

  1. 如果镜像的挂载点有数据,那么会通过COPY ON WRITE技术写道数据卷里。也就是被挂在后数据将显示被挂载的卷的数据,取消挂在后,原挂载点的数据会出现。
  2. 容器读取volume中的数据和宿主机操作数据是同步的,立马生效。
  3. 数据券是可以共享和重用的,多个容器可以使用同一个数据券。类似多主机间NFS共享。
  4. 从以上可以得到另一个特性,容器,数据券,镜像能相互独立存在。
  5. 容器删除,对应的挂在券数据不会丢失。
  6. 容器操作数据券的IO性能,就是具体数据券所在硬件设备的IO性能。

docker 挂载卷

  1. 数据券是外界的,一般就是宿主机文件系统中的一个目录。
  2. 可以在docker 层面创建一个券引用名,通过该引用名可以挂在到容器的挂在点上。当然也可以直接使用文件系统存在目录作为数据券来挂载。
  3. 挂在点也是可以预先在dockerfile中通过VOLUME创建。在启动时会自动在/var/lib/docker/volumes/下随机创建一个券目录,作为挂载点对应的数据券。
  4. 当然,也可以docker volume create v_name 或者dockerfile中 VOLUME 挂载点都没有操作。直接在docker run -v 券:挂载点 ,在从镜像启动容器时,直接设置容器外和容器内目录的挂载。

docker 多容器间共享数据券

要实现这个,不是通过每个容器都挂载相同的物理数据券来实现,而是通过第一个容器挂载数据券后。后面的容器在docker run时,指定一个--volumes-from 第一个dockerid,这样新建的容器就会同第一个容器一样,有相同挂载点对应数据卷。我们通常称第一个容器是“数据卷容器”

删除,查看数据卷

  1. 常看:docker volume ls 列出所有通过docker volume create的卷;docker volume inspect vol_id 常看券详情。
  2. 删除:docker volume rm vol_id

备份还原数据卷

应用产生的数据是非常重要的,数据持久化到数据卷后,持久化数据的备份和迁移还原也是数据卷使用的重要操作。

  1. 备份volume 备份一个容器的volume,通过启动一个新容器,共享要备份的目标容器,在新容器新挂在备份的目录在新容器的另一个挂载点;由于新容器同时共享了目标容器的volume,所以在新容器中执行tar 共享挂载点数据 放到新挂载点,同时启动新容器时指定--rm,这样就可以在新容器的新挂载点对应的数据卷中找到备份的数据了。 命令如下:已经知道存在docker容器docker1 其有一个数据卷要备份时/data docker run -it --volumes-from docker1 -v /tmp/backup/:/backup --name docker_bk --rm ubuntu tar cvf /backup/docker1.tar /data 执行成功的话,会炸/tmp/backup/下看到docker1.tar 这种方式是最专业和正确的操作。

  2. 还原volume 恢复基本原理一样,也是将新容器启动后,作为数据卷容器,然后再启动第二个容器,挂载备份数目录,并--volumes-from 第一个容器,执行tar xvf 数据到第一个容器的卷中。

docker run -it --name docker_recover -v test_vol:/data ubuntu /bin/bash docker run --rm --volumes-from docker_recover -v /tmp/backup/:/backup ubuntu tar xvf /backup/docker1.tar -C /data

小结

  1. 数据卷的挂载
  2. 容器间共享数据卷和数据卷容器
  3. 利用数据卷容器思想,备份和恢复目标容器的目标数据卷

我们今天的关于Docker 实战 10 之初识 volumedocker --volumes-from的分享就到这里,谢谢您的阅读,如果想了解更多关于Docker - 命令 - docker volume、Docker - 命令 - volume 相关、docker -v 和Dockerfile 中VOLUME 区别、Docker 0x06: Docker Volume卷的相关信息,可以在本站进行搜索。

本文标签: