用一个实际例子理解Docker volume工作原理

摘要:
要了解DockerVolume,首先我们需要了解Docker文件系统的工作原理。Docker图像由多个文件系统的只读层叠加。当使用dockerrun命令启动容器时,Docker将加载一个只读图像层,并在图像堆栈的顶部添加一个读写层。当Docker容器被删除并通过镜像重新启动时,读/写层中先前的更改将丢失。在Docker中,只读层和顶层读写层的组合称为UnionFileSystem,简称UnionFS。它使用一种重要的资源管理技术,称为写时复制。Docker基于UnionFS创建容器。

要了解Docker Volume,首先我们需要理解Docker文件系统的工作原理。Docker镜像是由多个文件系统的只读层叠加而成。当一个容器通过命令docker run启动时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,但是该文件的只读版本依然存在,只不过已经被读写层中该文件的副本所隐藏。

当删除Docker容器,并通过该镜像重新启动时,之前在读写层的更改将会丢失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统),简称UnionFS,它用到了一个重要的资源管理技术,叫写时复制。写时复制(copy-on-write),也叫隐式共享,是一种对可修改资源实现高效复制的资源管理技术。对于一个重复资源,若不修改,则无需立刻创建一个新的资源,该资源可以被共享使用。当发生修改的时候,才会创建新资源。这会大大减少对于未修改资源复制的消耗。其实COW这个概念对编程人员来说一点也不陌生,广泛用在各种领域,比如ABAP里对于内表(Internal table)的拷贝动作,Java字符串的拷贝实现等等。Docker基于UnionFS去创建containers。

我们下面看一个实际例子。

使用命令行docker run --help查看这个命令的帮助文档。 -h 的作用是指定容器的主机名。
用一个实际例子理解Docker volume工作原理第1张

使用命令行创建一个新的容器:

docker run -it --name jerry-container-test -h CONTAINER -v /data busybox /bin/sh
名称为jerry-container-test, 用-v创建了一个volume /data
用一个实际例子理解Docker volume工作原理第2张

创建完毕之后,在容器里执行cd /data进入这个目录,这个时候还是空的。
用一个实际例子理解Docker volume工作原理第3张

docker ps查看容器状态:
用一个实际例子理解Docker volume工作原理第4张

现在我想知道主机上为了实现这个volume,使用了哪个internal目录。

用命令docker inspect jerry-container-test查看关键字"volumes":
用一个实际例子理解Docker volume工作原理第5张

得到了容器里/data在主机上实现的目录:

/var/lib/docker/volumes/96aa969033ee7e6d7ff607a0a47de5a5866613a422518ed3f86fee6240bae8cc/_data

现在我在主机上使用touch命令在这个目录下直接创建一个文件:

sudo touch /var/lib/docker/volumes/96aa969033ee7e6d7ff607a0a47de5a5866613a422518ed3f86fee6240bae8cc/_data/test.s
用一个实际例子理解Docker volume工作原理第6张

现在切换到容器里,用ls也能看到直接在主机上用touch命令在internal folder里创建的文件了。
用一个实际例子理解Docker volume工作原理第7张

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

用一个实际例子理解Docker volume工作原理第8张

免责声明:文章转载自《用一个实际例子理解Docker volume工作原理》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C# Task 源代码阅读(2)[StringUtil ] isEmpty VS isBlank下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

docker打开api remote接口设置

前言 本文记录docker怎么打开api remote接口设置,docker的版本更新太快了,不同的版本之间,设置可能不同,本文是针对docker13.1 1、 查看配置文件位于哪里systemctl show --property=FragmentPath docker 2、编辑配置文件内容,接收所有ip请求vim /lib/systemd/sys...

FastAPI 学习之路(四十九)WebSockets(五)修复接口测试中的问题

其实代码没有问题,但是我们忽略了一点,就是我们在正常的开发中,肯定是遇到这样的情况,我们频繁的有客户端链接,断开链接,我们需要统一的管理起来,那么我们应该如何去管理呢,其实这个时候,我们要去声明一个类去管理我们的这些链接。我们应该如何优化呢。 定义一个链接管理类,处理我们所有的链接。 classConnectionManager: def __in...

记一次docker容器中运行springboot程序日志打印的中文变成问号

问题现象: 在虚拟机中 java -jar app.jar 程序正常启动,中文日志显示无误,在docker容器内中文全部显示为问号,但在容器内echo可以正常输出中文,遂排除字体因素。 百度说改/etc/locale.conf 和 ~/.bashrc,都没用。 解决方案: 做 docker 容器的时候加上一句ENV LANG C.UTF-8,问题搞定。 参...

docker pull报x509问题及docker启动失败问题解决

docker pull 报x509 最近通过docker pull拉取私有仓库镜像出错,具体报错(证书问题): docker pull 私有仓库ip/资源路径 x509: certificate has expired or is not yet valid 要注意。如果报509问题通常两方面原因: 1.系统时间不同步 2.证书问题,daemon.js...

数组中的filter函数,递归以及一些应用。

当我们用一个东西时候我们必须知道的是?why---where----how---when。一个东西我们为什么用?在哪用?怎么用?何时用?而不是被动的去接受一些东西。用在js里边我觉得也会试用。一直追求源生js,虽然也都背过好多东西,但是随着时间的流逝,工作的繁忙都忘了,有时甚至一点印象都没有,这让我开始思考我的学习方法了已经思维方式了。我们要记得不是简单的...

出现 "System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本" 错误的解决办法

出现 "System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本" 错误的解决办法 1.问题: 在Windows SP2 + VS2005 + Oracle 9i +IIS5.1环境中运行ASP.NET网页的时候出现如下错误: System.Data.OracleClient 需要 Oracle 客户端软...