07-Docker-Image深入理解
07-Docker-Image深入理解
Docker Version: 19.03.5
😄 Written by Zak Zhu
参考
- Breeze老师的docker培训
- 马哥docker视频
- sparkdev/Docker镜像之进阶篇(https://www.cnblogs.com/sparkdev/p/9092082.html)
- ly2020_/Docker镜像的分层结构介绍以及镜像的创建(https://blog.csdn.net/ly2020_/article/details/98492786)
- {-) 大傻逼/docker学习系列(三):docker镜像的分层结构(https://www.cnblogs.com/s-b-b/p/8533936.html)
镜像简介
什么是Docker镜像
Docker镜像是一个只读的容器模板, 包含运行容器所需的文件系统及其内容.
什么是Docker容器
Docker容器是由镜像创建的运行实例, 包含只读的镜像层和可读写的容器层.
镜像结构
-
最上层是可读写的容器层
运行的容器会在镜像上面多加一层可读写的容器层, 任何对文件的更改都只存在容器层. 因此任何对容器的操作均不会影响到镜像.
-
容器层以下的所有镜像层都是只读的
-
上层镜像依赖下层镜像, 从上往下依次查找文件
-
最底层是基础镜像
基础镜像提供的是最小安装的linux发行版.
-
共享宿主机内核
bootfs主要包含bootlooder和kernel, bootloader主要是引导加载kernel, 当kernel被加载到内存中后, bootfs会被卸载以节约内存资源.
镜像特性
镜像层
-
分层只读
- Docker镜像采用分层方式构建, 由一系列只读的镜像层组成.
- 同一个镜像构建的多个容器共享镜像层.
-
内容寻址
- 即Content Addressable Storage, 对镜像层的内容进行计算校验和, 生成一个内容哈希值, 并以此哈希值作为镜像层的唯一标识.
- 提高了镜像的安全性, 并在pull, push, load和save操作后检测数据的完整性.
- 增强了镜像层的共享, 对于来自不同构建的镜像层, 只要拥有相同的内容哈希, 也能被不同的镜像共享.
容器层
-
写时复制
- 即Copy on Write, 表示只在需要写时才会去复制, 这个是针对已有文件的修改场景.
- 在多个容器之间共享镜像, 每个容器在启动的时候并不需要单独复制一份镜像文件, 而是将所有镜像层以只读的方式挂载到一个挂载点, 再在上面覆盖一个可读写的容器层. 在未更改文件内容时, 所有容器共享同一份数据, 只有在容器运行过程中文件系统发生变化时, 才会把变化的文件内容写到容器层, 并隐藏镜像层中的老版本文件.
- 写时复制配合分层机制减少了镜像对磁盘空间的占用和容器启动时间.
-
用时分配
- 即Allocate on Demand, 表示在使用时才分配存储空间, 这个是针对写入新文件的场景.
- 在容器启动的时候, 并不会为这个容器预分配可读写的存储空间(容器层), 而是当有新文件写入时, 才按需分配空间.
镜像存储
目前最新版本的Docker默认使用OverlayFS驱动来存储镜像.
OverlayFS
- OverlayFS是Linux内核3.18后支持的, 也是一种UnionFS技术.
- OverlayFS只有两层文件系统: 一个lower文件系统和一个upper文件系统, 分别代表镜像结构中的镜像层和容器层.
- 当需要修改一个文件时, Docker使用Cow和AoD技术将文件从只读的lower文件系统复制到可读写的upper文件系统中进行修改, 并保存在upper文件系统中, 最后将两层文件系统通过联合挂载的方式巧妙地表现为一层,使得容器进程对这些层的存在一无所知.