深入理解Docker Volume(一)
想要了解Docker Volume,首先我们需要知道Docker的文件系统是如何工作的.Docker镜像是由多个文件系统(只读层)叠加而成.当我们启动一个容器的时候,Docker会加载镜像层并在其上添加一个读写层.如果运行中的容器修改了现有的一个已存在的文件,那该文件将会从读写层下的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏.当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失.在Docker中,只读层以及在顶部的读写层的组合被称为Union FIle System(联合文件系统).
为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念.简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上.
我们可以通过两种方式来初始化Volume,这两种方式有些细小而又重要的差别.我们可以在运行时使用-v来声明Volume:
root@syx-VB:/home/syx# docker run -it --name container-test -h CONTAINER -v /data ubuntu /bin/bash
root@CONTAINER:/# ls /data/
root@CONTAINER:/#
上面的命令会将/data挂载到容器中,并绕过联合文件系统,我们可以在主机上直接操作该目录.任何在该镜像/data路径的文件的文件都会被复制到Volume.我们可以使用docker inspect命令找到Volume在主机上的存储位置:
$docker inspect container-test
"Mounts": [
{
"Name": "6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134",
"Source": "/var/lib/docker/volumes/6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true
}
],
这说明Docker把在/var/lib/docker下的某个目录挂载到了容器内的/data目录下.让我们从主机添加文件都此文件夹下:
root@syx-VB:~# touch /var/lib/docker/volumes/6407cbb6700a4076cdeeef60629f1748ff34310102480a3f702fd3fee9e69134/_data/test-file
进入容器
root@syx-VB:~# docker attach container-test
root@CONTAINER:/# ls /data/
test-file
只要将主机的目录挂载到容器的目录上,那改变就会立即生效.我们可以在Dockerfile中通过使用VOLUME指令来达到相同的目的:
- FROM ubunut VOLUME /data
但是还有另一件只有-v参数能够做到而Dockerfile是做不到的事情就是在容器上挂载指定的主机目录.例如:
root@syx-VB:~# docker run -v /home/syx/dockerfile:/data ubuntu ls /data
df_test1
该命令将挂载主机的/home/syx/dockerfile目录到容器内的/data目录上.任何在/home/syx/dockerfile目录下的文件都会出现在容器内.这对于在主机和容器之间共享文件是非常有用的,例如挂载需要编译的源代码.为了保证可移植性,挂载主机目录不需要从Dockerfile指定.当使用-v参数时,镜像目录下的任何文件都不会被复制到Volume中.
数据共享
如果要授权一个容器访问另一个容器的Volume,我们可以使用-volumes-from参数来执行docker run
root@syx-VB:~# docker run -it -h NEWCONTAINER --volumes-from container-test ubuntu /bin/bash
root@NEWCONTAINER:/# ls /data/
test-file
值得注意的是,就算你这个时候把container-test停止了,它仍然会起作用.只要有容器连接Volume,他就不会被删除,如果这个时候你执行:
root@syx-VB:~# docker rm container-test
Error response from daemon: Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f
Error: failed to remove containers: [container-test]
数据容器
常见的使用场景是使用纯数据容器来持久化数据库,配置文件或者数据文件等.例如:
- $docker run --name dbdate postgres echo “Data-Only container for postgres”
该命令将会创建一个已经包含在Dockerfile里定义过Volume的postgres镜像,运行echo命令然后退出.当我们运行docker ps命令时,echo可以帮助我们识别某镜像的用途.我们可以用-volume-from命令来识别其他容器的Volume:
- $docker run -d --volumes-from dadate --name db1 postgres
使用数据容器的两个注意点:
1.不要运行数据容器,这纯属是在两非自愿
2.不要为了数据容器而使用”最小的镜像”,如busybox或scratch,只使用数据库镜像本身就可以了.你已经拥有了该镜像,所以不需要占用额外的空间.
备份
如果你在用数据容器,那做备份是相当容易的.
- root@syx-VB:~# docker run --rm --volumes-from dbdate -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /var/lib/postgresql/data
该命令会将Volume里所有的东西压缩为一个tar包(官方的postgres Dockerfile在/var/lib/postgresql/data目录下定义了一个Volume).
- root@syx-VB:~# ls
- backup.tar
删除Volumes
这个功能太重要了,如果你已经使用docker run来删除你的容器,那可能会有很多孤立的Volume仍在占用着空间.
Voulume可以被删除的条件:
1.该容器可以用docker rm -v来删除且没有其他容器连接到该Volume(以及主机目录是也没被指定为Volume).注意,-v是必不可少的.
2.docker run中使用rm参数.
深入理解Docker Volume(一)的更多相关文章
- 用一个实际例子理解Docker volume工作原理
要了解Docker Volume,首先我们需要理解Docker文件系统的工作原理.Docker镜像是由多个文件系统的只读层叠加而成.当一个容器通过命令docker run启动时,Docker会加载只读 ...
- 深入理解Docker Volume(二)
一开始,认为Volume是用来持久化的,但是这实际上不对,因为认为Volume是用来持久化的同学一定是认为容器无法持久化,所以有了Volume来帮助容器持久化,事实上,容器会一直存在,除非你删除他 ...
- 理解OpenShift(5):从 Docker Volume 到 OpenShift Persistent Volume
理解OpenShift(1):网络之 Router 和 Route 理解OpenShift(2):网络之 DNS(域名服务) 理解OpenShift(3):网络之 SDN 理解OpenShift(4) ...
- docker挂载volume的用户权限问题,理解docker容器的uid
docker挂载volume的用户权限问题,理解docker容器的uid 在刚开始使用docker volume挂载数据卷的时候,经常出现没有权限的问题. 这里通过遇到的问题来理解docker容器用户 ...
- 理解Docker(8):Docker 存储之卷(Volume)
(1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 (4)Docker 容器的隔离性 - 使用 ...
- 什么是Docker Volume?
摘要:Docker Volume,通常翻译为数据卷,用于保存持久化数据.当我们将数据库例如MySQL运行在Docker容器中时,一般将数据通过Docker Volume保存在主机上,这样即使删除MyS ...
- 利用Docker volume修改Nginx Docker镜像里index.html
通过这个小例子我们可以进一步加深对Docker volume概念的理解和使用方法. 我们都知道运行基于Docker的Nginx镜像后,访问localhost能看到Nginx默认的首页,这个首页的位置是 ...
- 深刻理解Docker镜像大小
都说容器大法好,可是假设没有Docker镜像,Docker该是多无趣啊. 是否还记得第一个接触Docker的时候,你从Docker Hub下拉的那个镜像呢?在那个处女镜像的基础上.你执行了容器生涯的处 ...
- Docker - 命令 - docker volume
概述 docker volume 命令 背景 docker 容器的存储, 通常需要独立于镜像 docker volume 就是负责这块的命令 1. 写在 docker volume 之前 概述 doc ...
随机推荐
- jquery设置按钮disabled
通常我们设置disabled属性会用attr和removeAttr,但是今天我们不讨论这个方式 我们讨论是的prop jQuery的定义是:获取在匹配的元素集中的第一个元素的属性值. 随着一些内置属性 ...
- 表结构变更后出现的ERROR OGG-01161 Bad column index (88)
2014-07-31 09:38:31 ERROR OGG-01668 PROCESS ABENDING. 2014-07-31 09:38:31 ERROR OGG-01161 Bad column ...
- ArcMap概化之消除真曲线
在地理国情项目中,异常折线检查结果中,有报错为:几何类型为esriGeometryCircularArc不合法,而属性表中几何类型(Shape)内容为 "面",这是为何? 作为GI ...
- Wndows 主进程(Rundll32)已停止工作
打开电脑,出现"windows 主进程(Rundll32)已停止工作",百度了一下,是文件损坏了. 下载一个新的文件,替换即可,若遇到权限问题,使用魔方工具中的设置 ...
- berkelydb学习
http://www.oracle.com/technetwork/cn/java/seltzer-berkeleydb-sql-085418-zhs.html 官网中文学习网址
- Java从零开始学三十二(正则表达式)
一.为什么要有正则 正则表达式可以方便的对数据进行匹配,可以执行更加复杂的字符串验证.拆份.替换功能. 例如:现在要求判断一个字符串是否由数字组成,则可以有以下的两种做法: 不使用正则完成 使用正则完 ...
- java经典小程序
1,编写程序,判断给定的某个年份是否是闰年. 闰年的判断规则如下: (1)若某个年份能被4整除但不能被100整除,则是闰年. (2)若某个年份能被400整除,则也是闰年. import java.ut ...
- 22、集合(Collection)
一.集合(Collection) 1.简介 Collection是一个接口,其定义了集合的相关功能方法.Collection继承了Iterable接口,而Iterable接口有一个方法Iterator ...
- 转:一个多目录结构C程序的Makefile
来源: ChinaUnix博客 一个多目录结构的C程序Makefile,代码存在main init input output exit目录. CC = gcc RDIR = RelsMAIN_DIR ...
- 原创:【微信小程序】客服消息教程(后台以PHP示例)
1.不需要自己手动开发客服消息的,直接接入客服,不开启消息推送即可.这种模式不多讲. 2.公众号后台开启消息推送模式,配置服务器URL.TOKEN.随机串.数据模式.数据格式(XML或JSON),这个 ...