Docker 对 container 的使用基本是建立在 LXC 基础之上,然而 LXC 存在的问题是难以移动,难以通过标准化的模板去制作、重建、复制和移动 container。

在以 VM 为基础的虚拟化中,有 image 和 snapshot 可以用于 VM 的复制、重建以及移动的功能。

想要通过 container 来实现快速的大规模部署和更新,这些功能不可或缺。

在 Docker 0.7 中引入了 Storage Driver(储存驱动), 现在已经支持 AUFS、Btrfs、Device Mapper、OverlayFS、ZFS、VFS。

一、储存驱动

https://docs.docker.com/storage/storagedriver/select-storage-driver/

1.Union FileSystem

简称 Union FS(联合文件系统),储存驱动的一种。

一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

2.Overlay2

Overlay2 是一种 Union FS,支持为每一个成员目录(AKA branch)设定 readonly、readwrite 和 whiteout-able 权限。

通常 Union FS 有两个用途:

  • 不借助 LVM, RAID 将多个 disk 和挂载到一个目录下。
  • 将一个 readonly 的 branch 和一个 writeable 的 branch 联合在一起,Live CD 正是基于此,可以允许在 OS image 不变的基础上允许用户在其上进行一些写操作。

Docker 在 Overlay2 上构建的 container image 也正是如此。

OverlayFS 将单个 Linux 主机上的两个目录分层,并将它们显示为单个目录。这些目录称为层,统一过程称为联合安装。

Overlay2 原生支持多达 128 OverlayFS 层。

下图显示了 Docker镜像 和 Docker容器 的分层方式。图像层是 lowerdir,容器层是 upperdir。统一视图通过一个被称为 merged 容器挂载点的目录公开。

二、Linux 系统启动

典型的 Linux 启动到运行需要两个FS - bootfs + rootfs (从功能角度而非文件系统角度)

bootfs(boot file system):

主要包含 bootloader 和 kernel,bootloader 主要是引导加载 kernel,当 kernel 被加载到内存中后,bootfs 就被 umount 了,此时内存的使用权已由 bootfs 转交给 kernel。

rootfs (root file system) :

在 bootfs 之上。包含的就是典型 Linux 系统中的 /dev、/proc、/bin、/etc 等标准目录和文件。

由此可见对于不同的 linux 发行版,bootfs 基本是一致的,rootfs 会有差别,,因此不同的发行版可以公用 bootfs。如下图:

三、Docker image 结构

典型的 Linux 在启动后,首先将 rootfs 置为 readonly,进行一系列检查, 然后将其切换为 "readwrite" 供用户使用。

在 Docker 中,起初也是将 rootfs 以 readonly 方式加载并检查,然而接下来利用 union mount 将一个 readwrite 文件系统挂载在 readonly 的 rootfs 之上,并且允许再次将下层的 file system 设定为 readonly,并且向上叠加。

这样一组 readonly 和一个 writeable 的结构构成一个 container 的运行目录,每一个被称作一个 Layer。如下图:

得益于 AUFS 的特性,每一个对 readonly 层文件或目录的修改都只会存在于上层的 writeable 层中。

这样,由于不存在竞争, 多个 container 可以共享 readonly 的 layer。

所以 docker 将 readonly 的层称作 image,对于 container 而言整个 rootfs 都是 read-write 的,但事实上所有的修改都写入最上层的 writeable 层中。

image 不保存用户状态,可以用于模板、重建和复制。

某个镜像:

基于该镜像创建的容器:

上层的 image 依赖下层的 image,因此 docker 中把下层的 image 称作父 image,没有父 image 的 image 称作 base image。

因此想要从一个 image 启动一个 container,docker 会先加载其父 image 直到 base image,用户的进程运行在 writeable 的 layer 中。

所有 parent image 中的数据信息以及 ID、网络和 lxc 管理的资源限制等具体 container 的配置,构成一个 docker 概念上的 container。如下图:

Docker image 采用分层结构的好处

共享资源,节省存储空间:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份 base 镜像,同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

快速部署:如果要部署多个 container,base image 可以避免多次拷贝。

内存更省:因为多个 container 共享 base image,以及 OS 的 disk 缓存机制,多个 container 中的进程命中缓存内容的几率大大增加。

升级更方便:相比于 copy-on-write 类型的文件系统,base-image 也是可以挂载为可 writeable 的,可以通过更新 base image 而一次性更新其之上的 container。

允许在不更改 base-image 的同时修改其目录中的文件,所有写操作都发生在最上层的 writeable 层中。

四、Docker 镜像 commit

docker commit 提交容器副本使之成为一个新的镜像

# docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]

# 下载镜像
docker pull tomcat
# 启动镜像
docker run -d -p : tomcat
# 查看容器ID
docker ps -a
# 进入容器
docker exec -it a41c393cfa45 /bin/bash
# 删除 tomcat
rm -rf /usr/local/tomcat/webapps/*
# 退出容器
exit
# 生成新镜像
docker commit -m=“没有webapps的tomcat镜像” -a=“jhxxb” a41c393cfa45 jhxxb/tomcat-del:1.0
# 查看生成的新镜像
docker images # 运行新镜像(需要指定版本,默认为 latest)
docker run -d -p 8080:8080 jhxxb/tomcat-del:1.0

可以看到新镜像的 webapps 目录下没有文件


http://tiewei.github.io/cloud/Docker-Getting-Start/

https://docs.docker.com/storage/storagedriver/overlayfs-driver/#how-the-overlay2-driver-works

Docker Image的更多相关文章

  1. docker——容器安装tomcat

    写在前面: 继续docker的学习,学习了docker的基本常用命令之后,我在docker上安装jdk,tomcat两个基本的java web工具,这里对操作流程记录一下. 软件准备: 1.jdk-7 ...

  2. Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境

    首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...

  3. Docker 第一篇--初识docker

    已经多年不写博客, 看完<晓松奇谈>最后一期猛然觉醒, 决定仔细梳理下自己这几年的知识脉络. 既然决定写, 那么首先就从最近2年热门的开源项目Docker开始.Docker 这两年在国内很 ...

  4. 在docker中运行ASP.NET Core Web API应用程序(附AWS Windows Server 2016 widt Container实战案例)

    环境准备 1.亚马逊EC2 Windows Server 2016 with Container 2.Visual Studio 2015 Enterprise(Profresianal要装Updat ...

  5. docker for mac 学习记录

    docker基本命令 docker run -d -p 80:80 --name webserver nginx 运行容器并起别名 docker ps 展示目前启动的容器 docker ps -a 展 ...

  6. scrapy爬虫docker部署

    spider_docker 接我上篇博客,为爬虫引用创建container,包括的模块:scrapy, mongo, celery, rabbitmq,连接https://github.com/Liu ...

  7. [原][Docker]特性与原理解析

    Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...

  8. 开发者的利器:Docker 理解与使用

    困扰写代码的机器难免会被我们安装上各种各样的开发工具.语言运行环境和引用库等一大堆的东西,长久以来不仅机器乱七八糟,而且有些相同的软件还有可能会安装不同的版本,这样又会导致一个项目正常运行了,却不小心 ...

  9. 使用python自动生成docker nginx反向代理配置

    由于在测试环境上用docker部署了多个应用,而且他们的端口有的相同,有的又不相同,数量也比较多,在使用jenkins发版本的时候,不好配置,于是想要写一个脚本,能在docker 容器创建.停止的时候 ...

  10. 微服务与Docker介绍

    什么是微服务 微服务应用的一个最大的优点是,它们往往比传统的应用程序更有效地利用计算资源.这是因为它们通过扩展组件来处理功能瓶颈问题.这样一来,开发人员只需要为额外的组件部署计算资源,而不需要部署一个 ...

随机推荐

  1. interrupt分析

    转载自 https://blog.csdn.net/zhangliangzi/article/details/52485319 interrupt简述 interrupt() 方法只是改变中断状态而已 ...

  2. delphi Tidhttp 发送json格式报文

    type TwmsThreadpostJson = class(TThread) private Furl: string; Fpostcmd: string; FResult: string; FB ...

  3. VS---《在VS2010中 使用C++创建和使用DLL》(001)

    VS---<在VS2010中 使用C++创建和使用DLL>(001) 需要学习制作和使用动态库,现在知道:DLL调用有两种方式,一种是静态调用,另外一种是动态调用.详细的还不算明白,等后期 ...

  4. async 与 await

    async 关键字 1.含义:表示函数是一个异步函数,意味着该函数的执行不会阻塞后面代码的执行 2.定义与调用 async function hello (flag) { if (flag) { re ...

  5. 数据库 Redis:Windows环境安装

    1. 下载 Redis (1)前往 GitHub 下载:https://github.com/microsoftarchive/redis (2)点击 release : (3)选择好版本号后,下载文 ...

  6. Gym - 101981B Tournament (WQS二分+单调性优化dp)

    题意:x轴上有n个人,让你放置m个集合点,使得每个人往离他最近的集合点走,所有人走的距离和最短. 把距离视为花费,设$dp[i][k]$表示前i个人分成k段的最小花费,则有递推式$dp[i][k]=m ...

  7. Eclipse中使用Maven的Jetty插件Debug Web项目

    1.环境配置 JAVA_HOME=D:\Program Files\Java\jdk1.7.0_80 JRE_HOME=%JAVA_HOME%\jre CLASSPATH=.;%JAVA_HOME%/ ...

  8. ubuntu 16.04中文输入法安装

    转自: http://blog.csdn.net/u011795345/article/details/53041707 最近刚给笔记本装了Ubuntu+win10双系统,但是ubuntu16.04没 ...

  9. C# WebBrowser使用 网络(二)

    WebBrowser 简单操作 Form 代码 public partial class Form1 : Form { public Form1() { InitializeComponent(); ...

  10. 51nod 1989 竞赛表格 (爆搜+DP算方案)

    题意 自己看 分析 其实统计出现次数与出现在矩阵的那个位置无关.所以我们定义f(i)f(i)f(i)表示iii的出现次数.那么就有转移方程式f(i)=1+∑j+rev(j)=if(j)f(i)=1+\ ...