引言

docker的镜像是由多个只读的文件系统叠加在一起形成的。当我们在我启动一个容器的时候,docker会加载这些只读层并在这些只读层的上面(栈顶)增加一个读写层。这时如果修改正在运行的容器中已有的文件,那么这个文件将会从只读层复制到读写层。该文件的只读版本还在,只是被上面读写层的该文件的副本隐藏。当删除docker,或者重新启动时,之前的更改将会消失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System联合文件系统)。

为了很好的实现数据保存和数据共享,Docker提出了Volume这个概念,简单的说就是绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。又被称作数据卷

Volume的作用

  • 通过数据卷可以在容器之间实现共享和重用
  • 对数据卷的修改会立马生效(非常适合作为开发环境)
  • 对数据卷的更新,不会影响镜像
  • 卷会一直存在,直到没有容器使用

初始化Volume

在使用docker run的时候我们可以通过 -v 来创建一个数据卷并挂载到容器上,在一次run中多次使用可以挂载多个容器。

如果使用Dockerfile方式进行初始化时可以使用 VOLUME 来添加一个或者多个新的卷到由该镜像创建的任意容器。

创建一个数据卷

docker run -p : -d --name shanlei-nginx -v /usr/share/nginx/html nginx

上面的命令的意思是,我们创建了一个名称为shanlei-nginx的容器,将本机的8080端口映射到容器中nginx服务器的默认web访问端口80下,创建一个数据卷,并挂载到容器的/usr/share/nginx/html目录下。

这时我们就可以绕过联合文件系统,直接在主机上操作该目录了,任何在该镜像/usr/share/nginx/html下的文件都会被复制到Volume。

我们可以通过docker inspect指令找到Volume在主机上的存储位置

docker inspect inspect shanlei-nginx

docker inspect指令后面的参数可以跟容器名称。通过这个命令我们可以获得容器所有的相关信息。我们需要看这一部分

...
... "Mounts": [
{
"Type": "volume",
"Name": "057f911105d4c77d2cfe16ee6acb7f5a43f2643d571708da40f5db55e27b1155",
"Source": "/var/lib/docker/volumes/057f911105d4c77d2cfe16ee6acb7f5a43f2643d571708da40f5db55e27b1155/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
...
...

这说明docker把本机的“Source”指向目录,也就是

/var/lib/docker/volumes/057f911105d4c77d2cfe16ee6acb7f5a43f2643d571708da40f5db55e27b1155/_data

挂载到了容器的“Destination”指向的目录。

在Linux中我们可以直接进入“Source”指向的路径(注意在访问该目录时可能会有权限问题)

只要将主机的目录挂载到容器的目录上,那改变就会立即生效。在Dockerfile中我们可以通过VOLUME达到相同的目的

FROM nginx
VOLUME /usr/share/nginx/html

目录作为数据卷

通过-v标识可以将主机的目录挂载到容器中去

sudo docker run -d -p : -v $PWD/html:/usr/share/nginx/html nginx

上面的命令将本机的$PWD/html目录挂载到容器的/usr/share/nginx/html目录。$PWD在是一个系统环境变量,指代当前目录环境。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,如果目录不存在 Docker 会自动为你创建它。

注意:Dockerfile中不支持这种语法.

docker挂载数据卷的默认权限是读写,当然我们可以通过指令:ro指定为只读。

sudo docker run -d -p : -v $PWD/html:/usr/share/nginx/html:ro nginx

在我的本机主机的$PWD/html中有一个index.html文件,内容如下:

this is old

我们运行上面的命令,并将本机8080端口映射到容器中nginx服务器的默认web端口80下,现在我们来访问localhost:8080

现在我们修改本机下的$PWD/html/index.html

this is new

访问localhost:8080

文件作为数据卷

我们也可以使用-v指令从主机挂载单个文件到容器中去

docker run -d -p : -v $PWD/html/index.html:/usr/share/nginx/html/index.html nginx

当修改本机$PWD/html/index.html时,容器中的/usr/share/nginx/html/index.html也会随之变化。效果和上面相同,在这里就不做赘述了。

注意:如果直接挂载一个文件,很多文件编辑工具,包括 vi 或者 sed --in-place ,可能会造成文件 inode的改变,从 Docker 1.1 .0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。

数据共享

如果想要实现容器间的数据共享,那么需要授权一个容器访问另一个容器的Volume。我们可以在使用docker run时使用-volumes-from参数来进行指定。

docker run -it -h NEWCONTAINER --volumes-from shanlei-nginx ubuntu /bin/bash

注意:值得注意的是不管shanlei-nginx是否运行,它都会起作用。只要有容器连接Volume,它就不会被删除。

数据卷容器

如果我们有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。常见的使用场景是使用纯数据容器来持久化数据库、配置文件或者数据文件等。

数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。

首先我们需要先创建一个数据卷容器

docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres

然后通过--volumes-from指令参数来挂载 dbdata 容器中的数据卷。

docker run -d --volumes-from dbdata --name db1 training/postgres

当然,我们也可以使用多个 --volumes-from 参数来从多个容器挂载多个数据卷。 也可以从其他已经挂载了数据卷的容器
来挂载数据卷。

docker run -d --name db3 --volumes-from db1 training/postgres

现在我们进入容器中查看数据卷容器是否挂载成功

docker exec -it db1 /bin/bash

说明数据卷容器挂载已经成功了。

注意:如果删除了挂载的容器(包括 dbdata、db1 和 db2等),数据卷并不会被自动删除。如果要删除一个数据卷,必
须在删除最后一个还挂载着它的容器时使用 docker rm -v 命令来指定同时删除关联的容器。

备份和恢复

我们可以利用数据卷对其中的数据进行进行备份、恢复和迁移。

首先使用 --volumes-from 标记来创建一个加载 dbdata 容器卷的容器,并从本地主机挂载当前到容器的 /backup 目录。命令如下:

docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

容器启动后,使用了 tar 命令来将 dbdata 卷备份为本地的 /backup/backup.tar 。

恢复

如果要恢复数据到一个容器,首先创建一个带有数据卷的容器 dbdata2。

docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

然后创建另一个容器,挂载 dbdata2 的容器,并使用 untar 解压备份文件到挂载的容器卷中。

docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar

以上

docker进阶篇(一) ---- Volume(数据卷)的更多相关文章

  1. Docker容器学习梳理 - Volume数据卷使用

    之前部署了Docker容器学习梳理--基础环境安装,接下来看看Docker Volume的使用. Docker volume使用 Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker ...

  2. Docker(六)容器数据卷

    容器数据卷 docker的理念回顾 将应用和环境打包成一个镜像 需求:数据可以持久化和同步 使用数据卷 指定路径挂载 docker run -it -v 主机目录:容器内目录 # 测试 [root@h ...

  3. Docker系列(20)- 数据卷容器

    数据卷容器 什么是数据卷容器? 容器和容器之间实现数据共享 一个容器先于宿主机创建挂载方式,宿主机就会有改卷的目录 第二个容器使用命令--volumes-from 第一个容器,共享使用了第一个容器与宿 ...

  4. docker挂载本地目录和数据卷容器

    1.docker挂载本地目录 docker可以支持把一个宿主机上的目录挂载到镜像里. 交互模式运行docker run -it -v /home/dock/Downloads:/usr/Downloa ...

  5. Docker——网络和存储(数据卷)

    iptables -t nat -vnL |grep docker 查看docker桥接网卡:brctl show 本地端口随机映射到docker容器的80端口上: docker run -d -P ...

  6. Docker系列(19)- 数据卷之Dockerfile

    初识Dockerfile Dockerfile就是用来构建docker镜像的构建文件!命令脚本! 通过这个脚本生成镜像,镜像是一层一层的,脚本与一个个的命令,每个命令都是一层! # 创建一个docke ...

  7. docker 数据卷之进阶篇

    笔者在<Docker 基础 : 数据管理>一文中介绍了 docker 数据卷(volume) 的基本用法.随着使用的深入,笔者对 docker 数据卷的理解与认识也在不断的增强.本文将在前 ...

  8. docker 数据卷 ---- 进阶篇

    笔者在<Docker 基础 : 数据管理>一文中介绍了 docker 数据卷(volume) 的基本用法.随着使用的深入,笔者对 docker 数据卷的理解与认识也在不断的增强.本文将在前 ...

  9. docker学习5--docker数据卷(volume)

    https://blog.csdn.net/dream_broken/article/details/52314993 1.什么是数据卷volume 为了了解什么是Docker Volume,首先我们 ...

随机推荐

  1. H5相关网址

    html5中国 http://www.html5cn.org/   HTML 5 教程 http://www.w3school.com.cn/html5/index.asp   http://www. ...

  2. I/O系统(一)

    输入输出系统的发展大致可以分为4个阶段1.早期阶段 特点:    1.1每个IO设备都得有一套独立的逻辑电路和CPU相连.    1.2输入输出过程需要通过CPU,穿插在程序运行的过程中,处理IO时候 ...

  3. 关于java中分割字符串

    例子:String path = "123.456.789"; 如果要使用“.”将path分割成String[], path.split("//."); or ...

  4. js的一些总结

    函数 函数是一等公民 函数可以有属性,并且能连接到它的构造方法 函数可以像一个变量一样存在内存中 函数可以当做参数传给其他函数 函数可以返回其他函数 加法操作表 Number + Number -&g ...

  5. 跑python用ThinkPad好还是MacBook好?

    跑Python,那肯定是服务器操作系统最好,找个方便安装Linux的本子. 我想题主的意图应该是做Python开发吧,如果是Python开发,还要看一下开发方向,如果是网络爬虫.服务器后端编程类的,那 ...

  6. SPS Programming Abrites AVDI or GM MDI

    Just information for you to make a wise purchase of GM scan tools for SPS programming: (here, I focu ...

  7. windows内核对象管理学习笔记

    目前正在阅读毛老师的<windows内核情景分析>一书对象管理章节,作此笔记. Win内核中是使用对象概念来描述管理内核中使用到的数据结构.此对象(Object)均是由对象头(Object ...

  8. Could not transfer artifact org.springframework

    无法从中心仓库获取该版本的信息, 从新下载: 1.配置eclipse中的maven  user setting路径为本地maven安装路径 配置阿里云镜像路径 <mirror> <i ...

  9. js--随机产生100个从0 ~ 1000之间不重复的整数(me)

    <style>       div{text-indent:40px;} </style> <script> window.onload=function(){ v ...

  10. 2019.02.12 bzoj3944: Sum(杜教筛)

    传送门 题意: 思路:直接上杜教筛. 知道怎么推导就很简单了,注意预处理的范围. 然后我因为预处理范围不对被zxyoi教育了(ldx你这个傻×两倍常数活该被卡TLE) 喜闻乐见 代码: #includ ...