06_Docker数据卷(Volume)

参考资料

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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容