Docker Image
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的更多相关文章
- docker——容器安装tomcat
写在前面: 继续docker的学习,学习了docker的基本常用命令之后,我在docker上安装jdk,tomcat两个基本的java web工具,这里对操作流程记录一下. 软件准备: 1.jdk-7 ...
- Docker笔记一:基于Docker容器构建并运行 nginx + php + mysql ( mariadb ) 服务环境
首先为什么要自己编写Dockerfile来构建 nginx.php.mariadb这三个镜像呢?一是希望更深入了解Dockerfile的使用,也就能初步了解docker镜像是如何被构建的:二是希望将来 ...
- Docker 第一篇--初识docker
已经多年不写博客, 看完<晓松奇谈>最后一期猛然觉醒, 决定仔细梳理下自己这几年的知识脉络. 既然决定写, 那么首先就从最近2年热门的开源项目Docker开始.Docker 这两年在国内很 ...
- 在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 ...
- docker for mac 学习记录
docker基本命令 docker run -d -p 80:80 --name webserver nginx 运行容器并起别名 docker ps 展示目前启动的容器 docker ps -a 展 ...
- scrapy爬虫docker部署
spider_docker 接我上篇博客,为爬虫引用创建container,包括的模块:scrapy, mongo, celery, rabbitmq,连接https://github.com/Liu ...
- [原][Docker]特性与原理解析
Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...
- 开发者的利器:Docker 理解与使用
困扰写代码的机器难免会被我们安装上各种各样的开发工具.语言运行环境和引用库等一大堆的东西,长久以来不仅机器乱七八糟,而且有些相同的软件还有可能会安装不同的版本,这样又会导致一个项目正常运行了,却不小心 ...
- 使用python自动生成docker nginx反向代理配置
由于在测试环境上用docker部署了多个应用,而且他们的端口有的相同,有的又不相同,数量也比较多,在使用jenkins发版本的时候,不好配置,于是想要写一个脚本,能在docker 容器创建.停止的时候 ...
- 微服务与Docker介绍
什么是微服务 微服务应用的一个最大的优点是,它们往往比传统的应用程序更有效地利用计算资源.这是因为它们通过扩展组件来处理功能瓶颈问题.这样一来,开发人员只需要为额外的组件部署计算资源,而不需要部署一个 ...
随机推荐
- 数据库 master拒绝了 create database 权限
1.通过windows身份验证方式登录 2.为登录名赋予服务器角色权限,其中dbcreator权限表示允许新增和修改权限,sysadmin权限是管理员权限,包含dbcreator范围,若不追求权限精准 ...
- 6.移动端自动化测试-小知识 if __name__==’__main__:是什么意思?
1 引言 在Python当中,如果代码写得规范一些,通常会写上一句“if __name__==’__main__:”作为程序的入口,但似乎没有这么一句代码,程序也能正常运行.这句代码多余吗?原理又在哪 ...
- 根据CPU核心数确定线程池并发线程数(转)
一.抛出问题 关于如何计算并发线程数,一般分两派,来自两本书,且都是好书,到底哪个是对的?问题追踪后,整理如下: 第一派:<Java Concurrency in Practice>即&l ...
- 14.SpringMVC核心技术-类型转换器
类型转换器 在前面的程序中,表单提交的无论是 int 还是 double 类型的请求参数,用于处理该请求 的处理器方法的形参, 均可直接接收到相应类型的相应数据,而非接收到 String 再手工转换. ...
- paypal支付 NVP支付 paypal 手续费 GetTransactionDetails
主要内容: 本文章主要讲解的是NVP的对接,以最简单的接口案例,讲解一下对接NVP的方案. 先提供下paypal 官方文档的主要功能对接说明,如下 1.请求API 服务器端点 描述 https://a ...
- JS和jQuery用法区别
目录 JS和jQuery用法区别 外观区别 查找元素 操作标签 操作内容 操作属性 操作位置 操作样式 事件 JS和jQuery用法区别 外观区别 jQuery与JS最直观的区别就是外观上jQuery ...
- 将windows当做linux/Mac来用 scoop强大的包管理工具
在Linux中有apt-get.yum这些包安装管理 安装相当方便:如ubuntu安装一个mysql5.7,只需要一个简单的命令: apt-get 而在windows中需要在MySQL官网下载对应版本 ...
- 远程操控批量复制应用(scp/pssh/pscp.pssh/rsync/pslurp)
scp命令: scp [options] SRC... DEST/两种方式: scp [options] [user@]host:/sourcefile /destpath scp [options] ...
- Srping事物的隔离策略
spring事务: 什么是事务: 事务逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败. 事务特性(4种): 原子性 (atomicity):强调事务的不可分割. 一致性 (c ...
- linux下动态库中的soname
soname( Short for shared object name) 其是应用程序加载dll 时候,其寻找共享库用的文件名.其格式为 lib + math+.so + ( major versi ...