Docker存储卷(V18.X)
原文: Docker存储卷(V18.X)

简介

介绍

  Docker的存储卷称之为volume,本质上容器上的一个或者多个目录,而这些目录绕过了联合文件系统,与宿主机中的目录或者其他容器目录进行了绑定关系,这种绑定关系可以看作Linux的mount操作,当容器中的程序对这些目录写入数据时,其实写入到的是与之绑定的宿主机目录上,这样就实现了数据的存储功能。特别说明:本文章所使用的docker版本基于v18.X,对于较早版本的docker并不适合,例如tmpfs类型卷是v17.06新加入的存储卷。

作用

  默认情况下,容器不使用任何 volume时,容器的数据被保存在容器之内,它只在容器的生命周期内存在,会随着容器的删除而被删除,而想要持久化的存储这些数据,就得使用存储卷。特别的,保存容器中的数据也可以使用 docker commit 命令将容器提交为一个新的镜像,这个镜像中会保存容器运行时的所有数据(绑定的数据卷除外),但此种方法非常不推荐,因为这样的镜像通常会很大,镜像拉取以及运行容器都会变慢。当容器使用了存储卷,即使容器被删除了,但是与绑定的存储卷还在,对应目录的数据都会保存,如果想要恢复该容器,只要新建的容器绑定该存储卷,对应目录的数据也会随之恢复。

分类

  Docker存储卷可分为两类:

  • Volumes:数据卷,这类存储卷是被Docker Daemon管理,可使用docker volume create显示创建,被创建出来的卷位于/var/lib/docker/volumes/下,使用时候只需指定使用卷的名称以及对应的容器的一个目录,删除时候只需指定删除卷名即可,这类数据卷是存储数据最为推荐的方式。
  • Bind mounts :绑定挂载卷,从早版本docker提供,这类存储卷可以是宿主机的任意目录,也可以是来自其他容器的目录,不受docker Daemon管理,删除时候需要手动清理目录。
  • tmpfs mounts:临时挂载卷,该类存储卷数据存放在主机内存中,好处在于这类存储卷由于使用的tmpfs格式文件系统,读写性能好,但同时也增加了主机的内存开销,Docker早期版本不支持此类存储卷。

以下是其示意图:

存储卷使用

--volume&&--mount

  存储卷的使用是在docker run命令时候使用-v或者--volume来指明使用的存储卷,但是如果需要指明更多选项如卷类型、驱动等那就需要使用--mount来指明更多的选项。以下是两种选择的使用方法。

-v或--volume选项:[volume_name]:container_path:[options]

解释:

由三个字段组成,用冒号字符(:)分隔,字段必须按正确的顺序排列
volume_name:卷名,可省略,省略的时候默认会分配一个随机目录,在/var/lib/docker/volumes/随机目录/_data。还可以指定宿主机目录。
container_path:绑定的容器中的目录,必须。
options:其他选项,是逗号分隔的选项列表,例如读写模式(ro、rw),可省略。

示例:创建一个绑定挂载卷

--mount:该选项从V17.06加入,由多个键值对组成,用逗号分隔,每个键值由<key>=<value>组成。常用的key如下:

  • type:指明卷的类型,三种类型之一bind、volume、tmpfs
  • source:可简写为src,指定挂载来源通常是卷名称,匿名卷时忽略该选项
  • destination:可简写为dst或target,指定容器中的使用的目录
  • readonly:指定卷是否为只读
  • volume-opt:其他挂载选项可以多次使用,采用volume-opt=type=nfs

示例:将上述容器使用--mount启动(这里换一个名称为nginx-c2):

使用建议:两个命令能都实现数据卷的挂载,如果是老用户可以继续使用-v的方式来运行容器,如果是新用户推荐使用--mount,这样的语法比较简介明了,比如人性化的各种选项src、type、dest,但是如果需要使用tmpfs类型的数据卷时候必须使用--mount。

使用Volumes

  volume类型的数据卷是比较推荐方式,它是能被Docker 管理的卷, 使用流程是先创建卷,在使用-v或--mount进行挂载。如果在docker run时候不指定其宿主机目录,则默认也属于volumes类型,也受Docker管理。

创建卷

[root@app51 ~]# docker volume create data-vol
data-vol
[root@app51 ~]# docker volume inspect data-vol
[{"CreatedAt": "2019-02-28T17:39:36+08:00","Driver": "local","Labels": {},"Mountpoint": "/var/lib/docker/volumes/data-vol/_data","Name": "data-vol","Options": {},"Scope": "local"}
]
[root@app51 ~]# 

挂载卷并写入数据

[root@app51 ~]# docker run -it --name  bs1 -v data-vol:/data/tmp  busybox:latest /bin/sh
/ # ls /data/tmp/
/ # echo "hello world" > /data/tmp/index.html
/ # 

在宿主机上查看:

创建卷是还可以指定其他,列如指定大小、uid等其他选项,这些选项都是mount命令的选项,卷的管理中会介绍:

[root@app51 ~]# docker volume create --driver local  --opt type=tmpfs   --opt device=tmpfs  --opt o=size=100m,uid=1000 test-vol6
test-vol6
[root@app51 ~]# docker run -it --name  bs6 -v test-vol6:/data/tmp  busybox:latest /bin/sh
/ # ls /data
tmp

上面的挂载命令使用等价--mount:

[root@app51 ~]# docker run -it --name  bs7 --mount type=volume,src=test-vol6,dst=/data/tmp  busybox:latest /bin/sh
/ # 

容器内可以使用mount命令可以查看挂载点:

使用bind mounts

  绑定挂载卷使用,无非指定宿主机的具体某个目录,可以使用-v HOST_PATH:CONTAINER_PATH 也可以使用--mount type=bind,src=HOST_PATH,dst=CONTAINER_PATH。

示例:

[root@app51 ~]#  docker run -it --name bind-vol  -v "$(pwd)":/data busybox:latest /bin/sh
/ # ls /data
Dockerfile        a.txt             anaconda-ks.cfg   dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # 

等价于使用--mount:

[root@app51 ~]#  docker run -it --name bind-vol-1 --mount type=bind,src="$(pwd)",dst=/data busybox:latest /bin/sh
/ # ls /data
Dockerfile        a.txt             anaconda-ks.cfg   dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # 

以只读的方式挂载:

[root@app51 ~]#  docker run -it --name bind-vol-2 --mount type=bind,src="$(pwd)",dst=/data,readonly busybox:latest /bin/sh
/ # ls /data/
Dockerfile        a.txt             anaconda-ks.cfg   dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # cd /data/
/data # touch 1.txt
touch: 1.txt: Read-only file system
/data # 

查看卷(新开终端):

[root@app51 ~]# docker inspect bind-vol-2"Mounts": [{"Type": "bind","Source": "/root","Target": "/data","ReadOnly": true}],

使用tmpfs mounts

  tmpfs类型的卷只适用于Linux系统,命令行中除了使用--mount指定外还可以使用--tmpfs指定其类型。特别注意的,与volume卷和绑定挂载卷相反,tmpfs挂载是临时的,并且仅在主机内存中持久存在,当容器停止时,将删除tmpfs挂载,并且不会保留写在那里的文件。

示例 使用--mount:

[root@app51 ~]# docker run -it  --name tmpfs-c1  --mount type=tmpfs,dst=/app busybox:latest /bin/sh
/ #
/ # mount |grep /app
tmpfs on /app type tmpfs (rw,nosuid,nodev,noexec,relatime)

等价于使用--tmpfs:

[root@app51 ~]# docker run -it  --name tmpfs-c2   --tmpfs /app busybox:latest /bin/sh
/ # mount |grep /app
tmpfs on /app type tmpfs (rw,nosuid,nodev,noexec,relatime)
/ # 

查看挂载卷:

[root@app51 ~]# docker inspect tmpfs-c1 "Mounts": [{"Type": "tmpfs","Source": "","Destination": "/app","Mode": "","RW": true,"Propagation": ""}],

注意--mount选项还支持指定挂载目录的大小和权限,选项如下:

tmpfs-size 设置tmpfs类型卷的大小,默认无限制(即由宿主机内存决定)
tmpfs-mode 设置tmpfs类型卷挂载的目录权限,如1770。默认1777

指定一个大小为50m,目录选项为1770类似为tmpfs的存储卷:

[root@app51 ~]# docker run -it --name tmpfs-c3  --mount type=tmpfs,dst=/data/tmp,tmpfs-mode=1770,tmpfs-size=50m busybox:latest /bin/sh
/ #
/ #
/ # mo
modinfo     modprobe    more        mount       mountpoint
/ # mount |grep /data/tmp
tmpfs on /data/tmp type tmpfs (rw,nosuid,nodev,noexec,relatime,size=51200k,mode=1770)
/ # ls /data/ -l
total 0
drwxrwx--T    2 root     root            40 Mar  1 01:47 tmp

查看其存储卷信息:

[root@app51 ~]# docker inspect tmpfs-c3 "Mounts": [{"Type": "tmpfs","Source": "","Destination": "/data/tmp","Mode": "","RW": true,"Propagation": ""}],

使用容器数据卷

  除了以上数据卷外,还可以直接使用容器中已经挂载的数据卷,使用--volumes-from指定,此时两个容器的数据卷是共享的。从本质上来讲,这两数据卷共同挂载了宿主机上的同一个目录。

示例:创建一个容器share-c1挂载当前目录(确保不要退出)

[root@app51 ~]# docker run -it --name share-c1 -v $(pwd):/data busybox:latest /bin/sh
/ # ls /data/
Dockerfile        a.txt             anaconda-ks.cfg   backup.tar        dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # 

在运行一个容器挂载share-c1的卷:

[root@app51 ~]# docker run -it --name share-c2 --volumes-from share-c1 busybox:latest /bin/sh
/ # ls /data/
Dockerfile        a.txt             anaconda-ks.cfg   backup.tar        dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # 

存储卷管理

  docker存储卷管理通过docker volume命令组实现,v18.09的命令集合如下:

1.创建存储卷

docker volume create [OPTIONS] [VOLUME_NAME]

通常这样创建的卷会保存在宿主机目录/var/lib/docker/volumes/VOLUME_NAME/_data如果不指名 VOLUME则会创建匿名卷,方式等同于在docker run -v不指定宿主机目录。

常用选项:

-o, --opt :指定存储卷挂载选项。常用选项如下:

  • type: 挂载文件系统类型,可以是tmpfs、brtfs、甚至是nfs。
  • device:挂载的设备,
  • o:mount命令挂载选项,其选项可参考这里

示例一:创建一个普通的卷名称为test-vol-1。

[root@app51 test-vol-1]# docker volume create test-vol-1
test-vol-1
[root@app51 test-vol-1]# ls /var/
adm/      crash/    empty/    gopher/   lib/      lock/     mail/     opt/      run/      tmp/      yp/
cache/    db/       games/    kerberos/ local/    log/      nis/      preserve/ spool/    .updated
[root@app51 test-vol-1]# ls /var/lib/docker/volumes/test-vol-1/ -l
总用量 0
drwxr-xr-x 2 root root 6 3月   1 11:08 _data
[root@app51 test-vol-1]# 

示例二:创建一个tmpfs类型的存储卷,名称为test-vol-2

[root@app51 test-vol-1]# docker volume create --opt type=tmpfs  --opt device=tmpfs  --opt o=size=100m,uid=1000  test-vol-2
test-vol-2###挂载test-vol-2
[root@app51 test-vol-1]# docker run -it --name bs-c10 -v test-vol-2:/data busybox:latest /bin/sh
/ # mount |grep /data
tmpfs on /data type tmpfs (rw,relatime,size=102400k,uid=1000)
/ # 

示例三:创建一个nfs类型的存储卷,服务器地址为10.1.210.52,权限读写,目录为/data/tmp,名称为test-vol-3

[root@app51 test-vol-1]# docker volume create --opt type=nfs --opt o=addr=10.1.210.52,rw  --opt device=:/data/tmp test-vol-3
test-vol-3

需要注意的是:创建的卷即使创建成功了但是挂载的时候很可能出错,docker不会在创建卷时候检查挂载选项是否符合要求。

2.查看存储卷详情

docker volume inspect [OPTIONS] VOLUME [VOLUME...]

常用选项:

-f, --format :输出格式,基于go模版

示例:

[root@app51 ~]# docker inspect test-vol-1
[{"CreatedAt": "2019-03-01T11:08:00+08:00","Driver": "local","Labels": {},"Mountpoint": "/var/lib/docker/volumes/test-vol-1/_data","Name": "test-vol-1","Options": {},"Scope": "local"}
]

使用-f:.代表以根开头,Name是一级字段。

[root@app51 ~]# docker inspect test-vol-1 -f {{.Name}}
test-vol-1
[root@app51 ~]# 

3.查看所有存储卷

docker volume ls [OPTIONS]

常用选项:

-f, --filter 过滤具体存储卷

示例:

[root@app51 ~]# docker volume ls
DRIVER              VOLUME NAME
local               test-vol-1
local               test-vol-2
local               test-vol-3
[root@app51 ~]# 

过滤某个卷:

[root@app51 ~]# docker volume ls -f name=test-vol-1
DRIVER              VOLUME NAME
local               test-vol-1

4.删除一个或多个卷

  docker volume rm [OPTIONS] VOLUME [VOLUME...]

常用选项:

-f, --force 强制删除存储卷,即使它还在被使用

[root@app51 ~]# docker volume ls
DRIVER              VOLUME NAME
local               test-vol-1
local               test-vol-2
local               test-vol-3
[root@app51 ~]# docker volume rm test-vol-3
test-vol-3
[root@app51 ~]# docker volume ls
DRIVER              VOLUME NAME
local               test-vol-1
local               test-vol-2
[root@app51 ~]# 

5.移除本地未使用的卷

docker volume prune [OPTIONS]

[root@app51 ~]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
test-vol-1Total reclaimed space: 0B
[root@app51 ~]# 

数据卷的备份与恢复

数据备份

  容器中的数据卷备份有两种方式,一是你可以直接备份与之对应的宿主机目录,二则运行一个容器挂载有数据的容器将其备份到与之对应的宿主机目录。这里演示下第二种数据备份方法。

方法:

1.创建备份容器并挂载需要备份的目录,同时挂载宿主机目录进行备份任务。

2.运行备份指令并将备份数据放到挂载的宿主机目录,以下示例为/backup,将数据备份在来/backup就等于备份在了宿主机的$(pwd)目录下,也就是当前目录。

新建一个数据容器并写入数据:

[root@app51 ~]# docker run -it --name data-c1 -v /data busybox:latest /bin/sh
/ # cd /data/
/data # touch 1.txt
/data # echo "hello world" > index.html
/data # ls -l
total 4
-rw-r--r--    1 root     root             0 Mar  1 07:40 1.txt
-rw-r--r--    1 root     root            12 Mar  1 07:40 index.html
/data # 

创建备份容器同时挂载两个目录进行数据备份:

[root@app51 ~]#  docker run --rm --volumes-from data-c1 -v $(pwd):/backup centos tar cvf /backup/backup.tar /data
/data/
/data/1.txt
/data/index.html
tar: Removing leading `/' from member names

查看备份数据:

[root@app51 ~]# ls -l
总用量 220332
-rw-------. 1 root root      1258 1月  16 00:15 anaconda-ks.cfg
-rw-r--r--  1 root root         7 2月  27 10:25 a.txt
-rw-r--r--  1 root root     10240 3月   1 15:42 backup.tar
-rw-r--r--  1 root root        76 2月  27 19:14 Dockerfile
-rw-r--r--  1 root root       578 1月  16 10:41 dr.sh
-rw-r--r--  1 root root       559 1月  16 14:53 nat.sh
-rw-------  1 root root 114356736 2月  24 10:56 nginx-bus.tar.gz
-rw-------  1 root root 111224320 2月  23 19:18 nginx.tar
[root@app51 ~]# tar tvf backup.tar
drwxr-xr-x root/root         0 2019-03-01 15:40 data/
-rw-r--r-- root/root         0 2019-03-01 15:40 data/1.txt
-rw-r--r-- root/root        12 2019-03-01 15:40 data/index.html

数据恢复

  恢复数据的原理与备份类似,也是启动一个容器共享需要备份的目录,同时挂载宿主机的备份目录,最后解压数据到备份目录中。为了演示数据恢复,我将上述容器 data-c1中的data目录中文件全部删除:

[root@app51 ~]# docker run -it --name data-c1 -v /data busybox:latest /bin/sh
/ # cd /data/
/data # rm -rf *
/data # 

创建一个恢复容器:

[root@app51 ~]# docker run --rm --volumes-from data-c1 -v $(pwd):/backup centos bash -c "cd / && tar xvf /backup/backup.tar"
data/
data/1.txt
data/index.html
[root@app51 ~]# 

再次查看data-c1容器数据:

/data # rm -rf data
/data #
/data #
/data #
/data #
/data # ls -l
total 4
-rw-r--r--    1 root     root             0 Mar  1 07:40 1.txt
-rw-r--r--    1 root     root            12 Mar  1 07:40 index.html
/data # 

  

posted on 2019-03-01 17:35 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10457783.html

Docker存储卷(V18.X)相关推荐

  1. Docker存储卷volume(V18.X)

    文章目录 1. 简介 1.1 介绍 1.2 作用 1.3 分类 2. 存储卷使用 2.1 设置卷的命令 2.1.1 -v或`--volume`选项指定卷 2.1.2 `--mount`指定卷 2.1. ...

  2. Docker存储卷简述和测试

    Docker存储卷 文章目录 Docker存储卷 COW机制 什么是存储卷 使用存储卷的好处 为什么要用存储卷 存储卷管理方式 存储卷的分类 容器数据管理 COW机制 Docker镜像由多个只读层叠加 ...

  3. Docker 学习6 Docker存储卷

    一.什么是存储卷 二.为什么要用到数据卷 三.数据卷是怎么被管理的 四.存储卷种类 五.在容器中使用存储卷 1.只声明容器路径 [root@localhost docker]# docker run ...

  4. docker存储卷篇

    在之前的文章中,我们说过,容器的服务如果需要提供给外部访问,需要把端口映射出来.docker的数据存储卷也是一样的道理,我们在使用docker的时候,有些应用是需要保存数据的,这些需要保存数据的应用就 ...

  5. Docker存储卷基本操作

    简介 Docker镜像是由多个只读层添加而成,启动容器时,Docker加载值读镜像层并在镜像栈顶部添加一个读写层. 如果运行中的容器修改了现有的一个已经存在的文件,那么该文件将会在读写层下面的只读层复 ...

  6. Docker 存储卷

    docker在运行时是基于分层镜像得联合挂载机制来实现的,而在这种分层构建镜像联合挂载并在最上层实现读写层的时候会发现一个特点,所有的有容器中的进程所生成的数据都是被最上面的可写层所保存而这个可写层本 ...

  7. docker存储卷的使用

    COW技术原理(Copy On Write,写时复制) Ø 直接映射原始盘的数据内容 Ø 当原始盘的旧数据有修改时,在修改之前自动将旧数据存入前端盘 Ø 对前端盘的修改不回写到原始盘 Docker镜像 ...

  8. Docker存储卷(Volume)

    简介 想要了解Docker Volume,首先我们需要知道Docker的文件系统是如何工作的.Docker镜像是由多个文件系统(只读层)叠加而成.当我们启动一个容器的时候,Docker会加载只读镜像层 ...

  9. docker修改镜像的存储位置_云原生存储详解:容器存储与 K8s 存储卷(内含赠书福利)...

    作者 | 阚俊宝  阿里巴巴技术专家 参与文末留言互动,即有机会获得赠书福利! 导读:云原生存储详解系列文章将从云原生存储服务的概念.特点.需求.原理.使用及案例等方面,和大家一起探讨云原生存储技术新 ...

最新文章

  1. 关于tomcat中文乱码的问题解决
  2. Oracle怎样创建共享文件夹,Oracle vm要如何使用共享文件夹的解决方法
  3. 链表c的经典实现(一)
  4. Gitlab-ci 替代 webhook 触发Jenkins job
  5. android 微信登录点击没翻译,[android] 微信登录,没有唤起微信,直接返回ERR_AUTH_DENIED...
  6. 【Qt】DOM创建和操作XML文档
  7. node 调用腾讯大数据接口
  8. 如何在并发中给 HttpClient 设置不同的超时时间?
  9. 斐波纳契回调线_斐波那契回调线(黄金分割线)神级操作-经典
  10. html 弹出一个邮件连接,mailto scheme 高级用法, 显示带html样式的邮件文本
  11. java executor 异步_Java并发编程11-异步执行框架Executor
  12. 非现场执法管理计算机(工业级),浅析非现场执法中存在问题的方法及对策
  13. mysql中 for update 使用
  14. python 获取表格中的空数据_在python beautifulsoup中获取表格单元格值为空时的文本输出...
  15. 创建虚拟文件系统设备文件节点_使用proc_create实例分析
  16. 31省“5G应用”主攻方向+责任单位一览!
  17. python扇贝每日一句api,英语每日一句API封装
  18. Qt for Android获取手机序列号
  19. “PaaS+云管”双剑合璧,BoCloud博云的进阶之路
  20. 函数function的使用方法

热门文章

  1. java基于ssm的在线家电维修系统网站
  2. 英文会议和期刊中引言的研究现状和相关工作中的研究现状有何区别?
  3. 解决文件或文件夹属性选项中只有“常规“、“以前的版本”,没有“安全”、“共享”、“位置”的方法
  4. UNIX操作系统族谱 —— 发展脉络一览
  5. Feedthrough
  6. 阿里云asp主机 后台登录一直提示验证码错误_温馨提示:欠谁钱,也别欠阿里云的钱!!!...
  7. 两个Android端基于蓝牙通讯的demo
  8. 学python能干web前端吗_【29岁,想转行,是学web前端还是python?】-看准网
  9. 浅谈C++结构体初始化
  10. 数据分析项目实战之淘宝女装店铺销售分析(一)数据获取篇