Docker原理之UnionFS

一、UnionFS

Linux 的命名空间和控制组分别解决了不同资源隔离的问题,前者解决了进程、网络以及文件系统的隔离,后者实现了 CPU、内存等资源的隔离,但是在 Docker 中还有另一个非常重要的问题需要解决 - 也就是镜像。

镜像到底是什么,它又是如何组成和组织的是作者使用 Docker 以来的一段时间内一直比较让作者感到困惑的问题,我们可以使用 docker run 非常轻松地从远程下载 Docker 的镜像并在本地运行。

Docker 镜像其实本质就是一个压缩包,我们可以使用下面的命令将一个 Docker 镜像中的文件导出:

$ docker export $(docker create busybox) | tar -C rootfs -xvf -
$ ls
bin  dev  etc  home proc root sys  tmp  usr  var

你可以看到这个 busybox 镜像中的目录结构与 Linux 操作系统的根目录中的内容并没有太多的区别,可以说 Docker 镜像就是一个文件。

二、存储驱动

Docker 使用了一系列不同的存储驱动管理镜像内的文件系统并运行容器,这些存储驱动与 Docker 卷(volume)有些不同,存储引擎管理着能够在多个容器之间共享的存储。

想要理解 Docker 使用的存储驱动,我们首先需要理解 Docker 是如何构建并且存储镜像的,也需要明白 Docker 的镜像是如何被每一个容器所使用的;Docker 中的每一个镜像都是由一系列只读的层组成的,Dockerfile 中的每一个命令都会在已有的只读层上创建一个新的层:

FROM ubuntu:15.04
COPY . /app
RUN make /app
CMD python /app/app.py

容器中的每一层都只对当前容器进行了非常小的修改,上述的 Dockerfile 文件会构建一个拥有四层 layer 的镜像:

16.png

当镜像被 docker run 命令创建时就会在镜像的最上层添加g zhi一个可写的层,也就是容器层,所有对于运行时容器的修改其实都是对这个容器读写层的修改。

容器和镜像的区别就在于,所有的镜像都是只读的,而每一个容器其实等于镜像加上一个可读写的层,也就是同一个镜像可以对应多个容器。

17.png

三、AUFS

UnionFS 其实是一种为 Linux 操作系统设计的用于把多个文件系统『联合』到同一个挂载点的文件系统服务。而 AUFS 即 Advanced UnionFS 其实就是 UnionFS 的升级版,它能够提供更优秀的性能和效率。

AUFS 作为联合文件系统,它能够将不同文件夹中的层联合(Union)到了同一个文件夹中,这些文件夹在 AUFS 中称作分支,整个『联合』的过程被称为联合挂载(Union Mount):

18.png

每一个镜像层或者容器层都是 /var/lib/docker/ 目录下的一个子文件夹;在 Docker 中,所有镜像层和容器层的内容都存储在 /var/lib/docker/aufs/diff/ 目录中:

$ ls /var/lib/docker/aufs/diff/00adcccc1a55a36a610a6ebb3e07cc35577f2f5a3b671be3dbc0e74db9ca691c       93604f232a831b22aeb372d5b11af8c8779feb96590a6dc36a80140e38e764d8
00adcccc1a55a36a610a6ebb3e07cc35577f2f5a3b671be3dbc0e74db9ca691c-init  93604f232a831b22aeb372d5b11af8c8779feb96590a6dc36a80140e38e764d8-init
019a8283e2ff6fca8d0a07884c78b41662979f848190f0658813bb6a9a464a90       93b06191602b7934fafc984fbacae02911b579769d0debd89cf2a032e7f35cfa
...

而 /var/lib/docker/aufs/layers/ 中存储着镜像层的元数据,每一个文件都保存着镜像层的元数据,最后的 /var/lib/docker/aufs/mnt/ 包含镜像或者容器层的挂载点,最终会被 Docker 通过联合的方式进行组装。

19.png

上面的这张图片非常好的展示了组装的过程,每一个镜像层都是建立在另一个镜像层之上的,同时所有的镜像层都是只读的,只有每个容器最顶层的容器层才可以被用户直接读写,所有的容器都建立在一些底层服务(Kernel)上,包括命名空间、控制组、rootfs 等等,这种容器的组装方式提供了非常大的灵活性,只读的镜像层通过共享也能够减少磁盘的占用。

四、其他存储驱动

AUFS 只是 Docker 使用的存储驱动的一种,除了 AUFS 之外,Docker 还支持了不同的存储驱动,包括 aufs、devicemapper、overlay2、zfs 和 vfs 等等,在最新的 Docker 中,overlay2 取代了 aufs 成为了推荐的存储驱动,但是在没有 overlay2 驱动的机器上仍然会使用 aufs 作为 Docker 的默认驱动。

20.png

不同的存储驱动在存储镜像和容器文件时也有着完全不同的实现,有兴趣的读者可以在 Docker 的官方文档 Select a storage driver 中找到相应的内容。

想要查看当前系统的 Docker 上使用了哪种存储驱动只需要使用以下的命令就能得到相对应的信息:

$ docker info | grep Storage
Storage Driver: aufs

作者的这台 Ubuntu 上由于没有 overlay2 存储驱动,所以使用 aufs 作为 Docker 的默认存储驱动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/535716.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

教你精确编写高质量高性能的MySQL语法

在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的编写,刚开始不会体会出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的…

Docker使用-Hello World

1、docker pull hello-world 拉去docker远程仓库中的Hello World的镜像 [rootCarlota2 ~]# docker pull hello-world Using default tag: latest latest: Pulling from library/hello-world 0e03bdcc26d7: Pull complete Digest: sha256:7f0a9f93b4aa3022c3a4c147a449bf11e09…

Mysql数据库引擎快速指南

如果你是个赛车手并且按一下按钮就能够立即更换引擎而不需要把车开到车库里去换,那会是怎么感觉呢? MySQL 数据库为开发人员所做的就好像是按按钮换引擎;它让你选择数据库引擎,并给你一条简单的途径来切换它。 MySQL的自带引擎肯…

Docker使用-构建MySQL

拉取官方镜像(我们这里选择5.7,如果不写后面的版本号则会自动拉取最新版) docker pull mysql:5.7 # 拉取 mysql 5.7 docker pull mysql # 拉取最新版mysql镜像MySQL文档地址 检查是否拉取成功 $ sudo docker images一般来说数据库容…

Java集合:什么是Java集合?

一、集合的由来 通常,我们的Java程序需要根据程序运行时才知道创建了多少个对象。但若非程序运行,程序开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的准确类型。为了满足这些常规的编程需要,我们要…

Mysql截取中英数混合的字符串

在 mysql中截取字符串我们用 LEFT函数 LEFT(str,len) 返回从字符串str 开始的len 最左字符。 mysql> SELECT LEFT(foobarbar, 5); -> fooba 手册上只介绍了截取英文字符串的方法,中文或者中英文的怎么办呢?以下是截取中英混合的字符串(中国人…

Java集合:Collection接口

Collection是一个接口,继承自Iterable。我们先看一下Iterable接口的源码 一、Iterable package java.lang;import java.util.Iterator; import java.util.Objects; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Cons…

Java集合:List集合

List集合 List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。 List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。 JDK API中List接口的实现类常用的有:ArrayList、LinkList和…

MySQL为什么要set names

大家都知道SET NAMES x相当于SET character_set_client x;SET character_set_results x;SET character_set_connection x; 以下从MySQL5.0官方文档上摘录了相关内容,并翻译,说明了相关系统变量的用处: What character set is the statem…

MySql日期处理系列-常用的日期推算处理

以下都是我平时用的一些日期推算处理方法,方法并不一定是最有效率的.全部均通过测试!转载请注明来自[phpchina.com] #title: 常用的日期推算处理#auther: 小强(占卜师) #date: 2007-12-25 #取得当前日期set dtCURDATE();select dt; #当前日期这个月的第一天selec…

Java集合:Set集合

一、Set接口的特点 一个不包含重复元素的collection。更确切地讲,Set不包含满足e1.equals(e2)的元素对 e1和e2,并且最多包含一个null元素。 Set集合由Set接口和Set接口的实现类组成,Set接口继承了Collection接口,因此包含了Coll…

谈谈我对MYSQL乱码的解决办法

经常更换虚拟主机,而各个服务商的MYSQL版本不同,当导入数据后,总会出现乱码等无法正常显示的问题,查了好多资料,总结出自己的一点技巧: WINDOWS 下导入应该这样使用MYSQL的命令在DOS命令下进入mysql的bin目录下,输入mysql -uroot -p密码 数据库名称<要恢复的数据库, 例如我们…

Java集合:Map集合

一、简述 public interface Map<K,V>将键映射到值的对象。一个映射不能包含重复的键&#xff1b;每个键最多只能映射到一个值。 注意&#xff1a;Map中的集合不能包含重复的键&#xff0c;值可以重复。每个键只能对应一个值。 Map集合是键值对形式存储值的&#xff0c…

用离线编辑器Zoundry写zblog日志

Zoundry是免费的离线网志发布工具&#xff0c;由于家里的网络很差&#xff0c;写了一半的日志经常因为掉线而丢失&#xff0c;这样一款软件的确是很必要的。今天下载试用了一下&#xff0c;感觉的确不错。使用起来也很简单&#xff1a; 1.下载并安装zoundry软件&#xff1a;现…

MySQL:基本命令

一、数据库操作 1、查询数据库&#xff0c;命令如下: SHOW DATABASES;2、我们可以在登陆 MySQL 服务后&#xff0c;使用 create 命令创建数据库&#xff0c;命令格式: CREATE DATABASE 数据库名;3、使用 drop 命令删除数据库&#xff0c;命令格式&#xff1a; drop databas…

CentOS 5打造全功能Web服务器

转&#xff1a;主要做为历史记录&#xff0c;以后用。另外很少见这么好的编译的文章&#xff0c;其实我不推荐用编译安装。但这个文章不错.V3.0 2007年11月11日 将搭建教程划分阶段以适应不同需要。加入程序优化&#xff0c;程序安全&#xff0c;加入memcache&#xff0c;squid…

MySQL:查询条件

查询条件 1、使用 WHERE 子句从数据表中读取数据的通用语法&#xff1a; SELECT field1, field2,...fieldN FROM table_name1, table_name2... [WHERE condition1 [AND [OR]] condition2.....查询语句中你可以使用一个或者多个表&#xff0c;表之间使用逗号**,** 分割&#x…

linux下的ImageMagick安装

检查系统有无安装ImageMagick官方网址是&#xff1a; www.imagemagick.org 从官方不好下载&#xff0c;提供 sourceforge的下载地址&#xff1a; imagemagick.sourceforge.net shell> rpm -qa | grep ImageMagick 没有就开始安装ImageMagickshell> rpm -Uvh ImageMagi…

MySQL:进阶应用

一、进阶应用 1、可以在 SELECT, UPDATE 和 DELETE 语句中使用 Mysql 的 JOIN 来联合多表查询。 JOIN 按照功能大致分为如下三类&#xff1a; INNER JOIN&#xff08;内连接,或等值连接&#xff09;&#xff1a;获取两个表中字段匹配关系的记录。**LEFT JOIN&#xff08;左连…

Hive-常用操作

一. 数据库操作 1、创建数据库 //用户可以用 IF NOT EXISTS 选项来忽略这个异常。create database [ if not exists ] myhive ;2、创建数据库并指定hdfs存储位置 create database myhive2 location /myhive2;3、修改数据库&#xff0c;可以使用alter database 命令来修改数据…