[转帖]docker 镜像分层原理及容器写时复制
https://xie.infoq.cn/article/19c98e8b15ff9f610a2ee26bd
一、镜像分层与容器层
在进行docker pull 下载镜像的时候,通过下图可以看到镜像是分层下载并解压的。如 nginx:1.20.2 的镜像,其镜像是分为 6 层。

当我们运行一个新的容器的时候,实际上是在镜像分层的基础上新添加了一层:container layer(容器层)。之后所有容器运行时对文件系统产生的修改实际都只影响这一层。并且针对这一层所作的修改(写操作),在容器重启之后会全部丢失。所以说在使用 docker 的过程中,在需要修改运行时容器文件数据的时候,尽量去重新构建镜像而不是直接修改容器内文件。如果重构镜像解决不了的问题,使用数据卷。
构建镜像的方法是通过 Dockerfile 定义,数据卷的使用详解,专栏后续文章笔者会详细介绍。

注意 :对于运行时的容器而言,镜像层只读的,容器层可读也可写。对于镜像层的只读文件,容器层如果想做修改,实际上是进行了写时复制操作。(下文介绍)。
二、为什么会产生分层?
通过上文的介绍,我们已经知道镜像是分层的,那么镜像分层的依据是什么?或者说构建镜像的时候究竟是什么动作产生了分层?我们来看下面的这张图,使用docker history查看镜像的构建历史。

注意上图中红色边框的部分,我们可以看到:在进行 ADD、COPY、执行 shell 脚本等操作的时候操作步骤对应的 SIZE 不等于 0,正好是 6 个操作,和我们上文中 nginx:1.20.2 镜像分层的数量是一样的。所以我们可以做一个大胆的猜想:在镜像构建过程中需要向镜像写入数据的时候会产生分层,一个写操作指令产生一个分层。 大家可以自己去观察更多的镜像去验证这个猜想。笔者要说的是:我读过 Dokcer 的源码,所以这是一个可以被信任的结论。

上面的这张图是 nginx:1.20.2 的 Dockerfile(镜像构建过程定义文档),也就是构建 nginx:1.20.2 镜像的构建步骤定义文档(官方)。其中 FROM(ADD)指令--添加基础镜像或文件、RUN 指令--执行命令行脚本、COPY 指令--文件复制,这些都是写操作命令,都会产生新的镜像分层。
三、什么是写时复制?
上文中我们提到了一个概念:写时复制。这个概念如果用专业名词的方式说明还是比较难以理解,所以我用白话的方式说明一下。举个例子:
一个授课老师写了一本练习册(原始镜像)。
然后老师留作业了,练习册第 12 页。全班同学把练习册的第 12 页全都复印了一份,带回家做作业。

老师的练习册是原始文稿(正本)(原始文稿构建之后就只读不写,镜像层文件也是),同学们的练习册是在需要使用到的时候复印出来的,并在复印本(副本)上完成作业书写,不影响原来老师那本练习册(正本)的内容。这个就是典型的“写时复制”。对于容器而言,复制出来的文件在面向容器内的运行时软件时,会覆盖原始镜像文件(对于学生而言也只看自己复制出来那份--不要抬杠:抄作业的除外,不看老师的原始文件)。也就是说发生写时复制之后原始镜像文件被隐藏,容器读写操作都只认复制出来的副本文件。注意:该副本文件存在于容器层,容器重启之后容器层重新建立,上一次容器运行时对于文件的修改全部丢失!
[转帖]docker 镜像分层原理及容器写时复制的更多相关文章
- 计算机程序的思维逻辑 (73) - 并发容器 - 写时拷贝的List和Set
本节以及接下来的几节,我们探讨Java并发包中的容器类.本节先介绍两个简单的类CopyOnWriteArrayList和CopyOnWriteArraySet,讨论它们的用法和实现原理.它们的用法比较 ...
- Java编程的逻辑 (73) - 并发容器 - 写时拷贝的List和Set
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- Java进阶知识点6:并发容器背后的设计理念 - 锁分段、写时复制和弱一致性
一.背景 容器是Java编程中使用频率很高的组件,但Java默认提供的基本容器(ArrayList,HashMap等)均不是线程安全的.当容器和多线程并发编程相遇时,程序员又该何去何从呢? 通常有两种 ...
- 理解Docker镜像分层
关于base镜像 base 镜像有两层含义: 不依赖其他镜像,从 scratch 构建. 其他镜像可以之为基础进行扩展. 所以,能称作 base 镜像的通常都是各种 Linux 发行版的 Docker ...
- Docker镜像分层技术
Docker镜像管理 1.镜像分层技术 2.创建镜像 3.下载镜像到主机 4.删除镜像 5.上传镜像到registry docker镜像: 早在集装箱没有出现的时候,码头上还有许多搬运的工人在搬运货物 ...
- [Docker镜像] 关于阿里云容器镜像服务的使用(以天池比赛提交镜像为例)
最近在参加天池比赛,由于比赛需要使用阿里云容器镜像服务完成线上预测任务,所以花费了3-4天的时间了解并使用Docker完成相关镜像操作,在此分享下我学习的内容,以下是本文的目录结构: 介绍 镜像 容器 ...
- Docker镜像构建原理解析(不装docker也能构建镜像)
在devops流程里面 构建镜像是一个非常重要的过程,一般构建镜像是写dockerfile文件然后通过docker client来构建的image. docker client 会先检查本地有没有im ...
- 『现学现忘』Docker基础 — 26、Docker镜像分层的理解
目录 1.分层的镜像 2.加深理解 3.特别说明 1.分层的镜像 我们可以去下载一个镜像,注意观察下载的日志输出,可以看到Docker的镜像是一层一层的在下载. 思考:为什么Docker镜像要采用这种 ...
- Docker:镜像构建与进入容器总结
构建镜像总结 docker构建镜像有两种方法: 1.使用docker commit + 容器 docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] ...
- docker 镜像仓库 Harbor 部署 以及 跨数据复制
docker 镜像仓库 Harbor 部署 跨数据复制 Harbor 是 Vmwar 公司开源的 企业级的 Docker Registry 管理项目 它主要 提供 Dcoker Registry 管理 ...
随机推荐
- MySQL篇:第四章_详解DML语言
DML语言 插入 一.方式一 语法: insert into 表名(字段名,...) values(值1,...); 特点: 1.字段类型和值类型一致或兼容,而且一一对应 2.可以为空的字段,可以不用 ...
- GaussDB技术解读系列之应用无损透明(ALT)
本文作者 :华为云GaussDB研发高级工程师 藏琦 1.背景 GaussDB作为一款企业级分布式数据库,提供了"同城跨AZ双活.两地三中心.双集群强一致"等极致的高可用容灾能力. ...
- Springboot中,如何读取配置文件中的属性
摘要:在比较大型的项目的开发中,比较经常修改的属性我们一般都是不会在代码里面写死的,而是将其定义在配置文件中,之后如果修改的话,我们可以直接去配置文件中修改,那么在springboot的项目中,我们应 ...
- 基于AIO架构smarthttp开发的完整MVC框架
基于AIO架构smarthttp开发的完整MVC框架 写了篇<基于jdk自带httpserver开发的最小完整MVC框架>,就再写篇AIO的MVC DEMO启动时间:0.1s(应该算少的吧 ...
- 收到一封CTO来信,邀约面试机器学习工程师
大家好,我是北海 很少登陆 Gmail,前天收验证码登了一下,发现居然收到一封某初创公司CTO的来信. 我在Github上看到了您的资料觉得很有意思,请问您是否考虑我们公司的全职工作机会呢?可供考虑的 ...
- kill 进程时遇到的一件有意思的事情
案例现象 一般来讲,我们在 kill 掉一个进程的时候通常有两个选择: 找到进程的 pid 号,然后执行 kill 命令 找到进程的名字,然后执行 pkill 命令 pkill 和 kill 命令都是 ...
- C++岗位面试真题宝典 -- 操作系统篇
2.1 Linux中查看进程运行状态的指令.查看内存使用情况的指令.tar解压文件的参数. 参考回答 查看进程运行状态的指令:ps命令."ps -aux | grep PID",用 ...
- AtCoder Beginner Contest 182 Person Editorial
Problem A - twiblr 直接输出 \(2A + 100 - B\) Problem B - Almost GCD 这里暴力枚举即可 int main() { ios_base::sync ...
- vue学习笔记 三、文件和目录结构
系列导航 vue学习笔记 一.环境搭建 vue学习笔记 二.环境搭建+项目创建 vue学习笔记 三.文件和目录结构 vue学习笔记 四.定义组件(组件基本结构) vue学习笔记 五.创建子组件实例 v ...
- 深度学习基础课:“判断性别”Demo需求分析和初步设计(下2)
大家好~我开设了"深度学习基础班"的线上课程,带领同学从0开始学习全连接和卷积神经网络,进行数学推导,并且实现可以运行的Demo程序 线上课程资料: 本节课录像回放1 本节课录像回 ...