我们在上篇介绍了容器技术中资源隔离与限制docker容器技术基础之linux cgroup、namespace

这篇小作文我们要尝试学习容器的另外一个重要技术之联合文件系统之OverlayFS,在介绍OverlayFS之前我们会学习一下镜像、容器、层的相关知识,然后是OverlayFS及相关实例,最后介绍docker中overlay2驱动即overlayfs在容器中的实现。


一、镜像、容器和层

docker中镜像是层级结构的,即图中的image layers,每一层只是与它之前的层的一组差异。这些层堆叠在彼此的顶部。当我们创建一个新容器时,会在镜像层加一个新的可写层。这一层通常被称为“容器层”。对正在运行的容器所做的所有更改,例如写入新文件、修改现有文件和删除文件,都将写入这个薄的可写容器层。

那么一个镜像创建多个容器时是怎样的景象呢?如下图所示,添加新数据或修改现有数据的所有写入容器都存储在此可写层中。当容器被删除时,可写层也被删除。底层镜像保持不变。因为每个容器都有自己的可写容器层,所有的变化都存储在这个容器层中,所以多个容器可以共享对同一个底层镜像的访问,同时又拥有自己的数据状态。

到这里你可能要问了:镜像为什么要分层啊?乱七八糟的!

其实不然,通过镜像的层级结构主要的一个优点是你可以把你的基础镜像进行共享,什么意思呢?比如你现在需要一个Nginx镜像、一个Tomcat镜像它们都可以通过一个base镜像如centos或者ubuntu制作而成,它看起来是这样的

如此一来通过镜像分层可以大大减少磁盘空间占用,同时降低镜像复构建杂度,何乐而不为。


二、联合文件系统OverlayFS

通过上面我们大概了解了镜像、容器和层的关系,那么又有一个问题了:镜像层和可写容器层的文件或者内容是如何来管理的?明明是分层的又是怎么合并的?

接下来我们将介绍UnionFS(联合文件系统),它的厉害之处在于可以将多个目录挂载到一个根目录。OverlayFS 是linux现代联合文件系统的一个代表,合并于Linux内核的3.18版本。从 docker 18.06后docker为OverlayFS提供了两个存储驱动,原始的overlay及overlay2(改善 inode 利用率),overlay2是目前docker推荐和首选存储驱动,通过它来管理镜像层和可写容器层内容。

我们可以在docker info中查看docker存储驱动版本

[root@i-k9pwet2d ~]# docker info
...
Server Version: 20.10.6
Storage Driver: overlay2
Backing Filesystem: extfs
...

OverlayFS这种堆叠的文件系统,依赖于其他文件系统之上,比如我们在info 中看到的extfs或者xfs等,它的结构如下图:

我们的基础层称为“lowerdir”即原始文件所在的位置。

客户端所做的任何修改都将反映在“upperdir”层上:

  • 如果更改文件,新版本将写入其中(file1)。
  • 如果删除文件,将在该层上创建一个删除标记(file2)。
  • 创建一个新文件(file4)。

最后,“merged”是所有层合并后的最终视图。

假如你有一些数据,需要多个进程来访问和修改它。每个进程都要创建一个独立的数据视图,你要存储多份原始数据,数据量大的话显然这会非常低效的。使用OverlayFS将会是very good!

接下来我们来我们搞个实验看看

我建立如下目录结构,workdir在OverlayFS中需要为空,用作内部临时存储。lowerdir包含3个文件file1、file2、file3

[root@i-k9pwet2d overlayfs_test]# tree .
.
├── client_1
│   ├── upperdir
│   └── workdir
├── client_2
│   ├── upperdir
│   └── workdir
├── lowerdir
│   ├── file1.txt
│   └── file2.txt
│ └── file3.txt
└── merged
├── client_1
└── client_2 10 directories, 3 files

挂载overlay

mount -t overlay overlay \
-o lowerdir=/overlaytest/lowerdir \
-o upperdir=/overlaytest/client_1/upperdir \
-o workdir=/overlaytest/client_1/workdir \
/overlaytest/merged/client_1 mount -t overlay overlay \
-o lowerdir=/overlaytest/lowerdir \
-o upperdir=/overlaytest/client_2/upperdir \
-o workdir=/overlaytest/client_2/workdir \
/overlaytest/merged/client_2

挂载后查看我们的视图,可以看到三个文件已经被合并到merged区了

[root@i-k9pwet2d overlaytest]# tree .
.
├── client_1
│   ├── upperdir
│   └── workdir
│   └── work
├── client_2
│   ├── upperdir
│   └── workdir
│   └── work
├── lowerdir
│   ├── file1.txt
│   ├── file2.txt
│   └── file3.txt
└── merged
├── client_1
│   ├── file1.txt
│   ├── file2.txt
│   └── file3.txt
└── client_2
├── file1.txt
├── file2.txt
└── file3.txt

下一步我们修改merged/client_1下修改我们的都数据

[root@i-k9pwet2d client_1]# echo "data no.1">>file1.txt
[root@i-k9pwet2d client_1]# rm file2.txt
[root@i-k9pwet2d client_1]# echo "data4" > file4.txt
[root@i-k9pwet2d client_1]# ls
file1.txt file3.txt file4.txt

再看我们的视图,可以看到修改只作用于client_1/upperdir,对我们lowerdir下原始数据以及client_2数据并不影响。

[root@i-k9pwet2d overlaytest]# tree .
.
├── client_1
│   ├── upperdir
│   │   ├── file1.txt
│   │   ├── file2.txt
│   │   └── file4.txt
│   └── workdir
│   └── work
├── client_2
│   ├── upperdir
│   └── workdir
│   └── work
├── lowerdir
│   ├── file1.txt
│   ├── file2.txt
│   └── file3.txt
└── merged
├── client_1
│   ├── file1.txt
│   ├── file3.txt
│   └── file4.txt
└── client_2
├── file1.txt
├── file2.txt
└── file3.txt 12 directories, 12 files

OverlayFS在容器中的实现

下图显示了 在Docker 中镜像和 容器是如何通过OverlayFS分层与互相构造的映射。图像层是lowerdir,容器层是upperdir。统一视图合并到merged目录,该目录实际上是容器安装点。

我们查看一个真正运行容器centos的inspect

docker inspect ca9a9e0a35c7

可以看到OverlayFS对应的目录地址,lowerDir即我们的原始数据包含image的rootfs(根文件)以及init相关文件,关于docker init层可以自行检索一下哈,这里不做介绍了。

"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/444808f5d6566eebf4ea73ea593b2c2076d4347ff57bd98cbc179dbac9265968-init/diff:/var/lib/docker/overlay2/0d6b94986ba1af1cc75e7c237f78d7e02d40f5ae5ec3f67ddb699ae6d07a2ca8/diff",
"MergedDir": "/var/lib/docker/overlay2/444808f5d6566eebf4ea73ea593b2c2076d4347ff57bd98cbc179dbac9265968/merged",
"UpperDir": "/var/lib/docker/overlay2/444808f5d6566eebf4ea73ea593b2c2076d4347ff57bd98cbc179dbac9265968/diff",
"WorkDir": "/var/lib/docker/overlay2/444808f5d6566eebf4ea73ea593b2c2076d4347ff57bd98cbc179dbac9265968/work"
},
"Name": "overlay2"
},

LowerDir下查看原始rootfs

[root@i-k9pwet2d client_1]# ls /var/lib/docker/overlay2/0d6b94986ba1af1cc75e7c237f78d7e02d40f5ae5ec3f67ddb699ae6d07a2ca8/diff
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var

我们进入容器添加和删除文件看看

[root@i-k9pwet2d ~]# docker exec -it ca9a /bin/bash

[root@ca9a9e0a35c7 /]# echo "newfile" >file 

[root@ca9a9e0a35c7 /]# rm /tmp/ks-script-esd4my7v

显然到到LowerDir下查看原始rootfs并不受影响而是把变更写入到了upperdir即容器层

cd  /var/lib/docker/overlay2/444808f5d6566eebf4ea73ea593b2c2076d4347ff57bd98cbc179dbac9265968/diff

[root@i-k9pwet2d diff]# tree .
.
├── file
└── tmp
└── ks-script-esd4my7v 1 directory, 2 files

以上的操作也就是docker中所谓的CoW(写时复制)策略。在docker中overlay2驱动对联合文件系统操作的更多场景可以参阅官方文档


这样我们实现容器的三大基础技术Namespace、Cgroup、UnionFS联合文件系统已经介绍完啦,希望这三篇小作文对想了解容器实现原理的读者有些许帮助。


参考:


小作文有不足的地方欢迎指出。

感谢收藏、点赞。关注顶级饮水机管理员,除了烧热水,有时还做点别的。

您的支持是我烧热水最大的动力...

docker容器技术基础之联合文件系统OverlayFS的更多相关文章

  1. docker容器技术基础入门

    目录 docker容器技术基础入门 容器(Container) 传统虚拟化与容器的区别 Linux容器技术 Linux Namespaces CGroups LXC docker基本概念 docker ...

  2. Docker容器技术-基础与架构

    一.什么是容器 容器是对应用程序及其依赖关系的封装. 1.容器的优点 容器与主机的操作系统共享资源,提高了效率,性能损耗低 容器具有可移植性 容器是轻量的,可同时运行数十个容器,模拟分布式系统 不必花 ...

  3. Docker容器技术基础

    Docker基础 目录 Docker基础 容器(Container) 传统虚拟化与容器的区别 Linux容器技术 Linux Namespaces CGroups LXC docker基本概念 doc ...

  4. Docker容器技术-基础命令

    一.基础命令 1.运行一个镜像 [root@bogon ~]# docker run debian echo "Hello World" Unable to find image ...

  5. 1.docker容器技术基础入门

    内容来自:https://www.cnblogs.com/marility/p/10215062.html https://blog.51cto.com/gouyc/2310785?source=dr ...

  6. docker容器技术基础之linux cgroup、namespace

    一.开头 接触过docker的同学多多少少听过这样一句话"docker容器通过linux namespace.cgroup特性实现资源的隔离与限制".今天我们来尝试学习一下这两个东 ...

  7. 1、docker容器技术基础入门

    Docker和传统虚拟机的区别               参考文章: https://lwn.net/Articles/531114/    操作中的命名空间详解 https://blog.yadu ...

  8. 1.云原生之Docker容器技术基础知识介绍

    转载自:https://www.bilibili.com/read/cv15180540/?from=readlist

  9. Docker核心实现技术(命名空间&控制组&联合文件系统&Linux网络虚拟化支持)

    作为一种容器虚拟化技术,Docker深度应用了操作系统的多项底层支持技术. 早期版本的Docker是基于已经成熟的Linux Container(LXC)技术实现的.自Docker 0.9版本起,Do ...

随机推荐

  1. ICCV2019论文点评:3D Object Detect疏密度点云三维目标检测

    ICCV2019论文点评:3D Object Detect疏密度点云三维目标检测 STD: Sparse-to-Dense 3D Object Detector for Point Cloud 论文链 ...

  2. TVM部署预定义模型

    TVM部署预定义模型 本文通过深度学习框架量化的模型加载到TVM中.预量化的模型导入是在TVM中提供的量化支持之一. 本文演示如何加载和运行由PyTorch,MXNet和TFLite量化的模型.加载后 ...

  3. 计图MPI分布式多卡

    计图MPI分布式多卡 计图分布式基于MPI(Message Passing Interface),主要阐述使用计图MPI,进行多卡和分布式训练.目前计图分布式处于测试阶段. 计图MPI安装 计图依赖O ...

  4. postman之内建变量的基础应用

    一.Postman有以下内建变量,适合一次性使用:{{$guid}}//生成GUID{{$timestamp}}//当前时间戳{{$randomInt}}//0-1000的随机整数 简单应用举例: 二 ...

  5. 编译原理-NFA转化成DFA

    1.假定NFA    M=<S,∑,f,S0,F>    对M的状态转换图进行以下改造: ①引进新的初态结点X和终态结点Y,    X,Y∈S,    从X到S0中的任意结点连一条ε箭弧, ...

  6. C++ QT安装教程2021

    第一步 去官网下载 https://download.qt.io/archive/qt/ 第二步 next 然后 我是注册的账号 注意密码的格式,要求至少7位,包含大小写字母和数字 第三步 点击下一步 ...

  7. 不下软件,照样可以完美正确格式化树莓派SD卡!(恢复U盘/SD卡到满容量)

    树莓派作用千千万,系统崩溃的理由也数不胜数(不要问我为啥知道),所以系统的重装和sd卡的格式化也在所难免.顺便给大家看一下我今天的成果,我不就是不小心摔了一下我的树莓派...我和sd卡一定是冤家! 捡 ...

  8. Java IO学习笔记八:Netty入门

    作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...

  9. Etcd中linearizable read实现

    linearizable 有点疑惑,不确定是现在浏览的版本没开发完全,还是没有按照论文的linearizable来实现. 按照论文所说,在客户端请求的时候,实际上是一个强一致的 exactly onc ...

  10. 《算法详解:C++11语言描述》已出版

    经过漫长的编写.修订和印刷过程,书籍<算法详解:C++11语言描述>终于出版了!目前本书已在各大电商平台上架,搜索书名即可找到对应商品.本书的特色在于: 介绍最新的C++11.C++14和 ...