[转帖]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 管理 ...
随机推荐
- rasa train nlu详解:1.2-_train_graph()函数
本文使用<使用ResponseSelector实现校园招聘FAQ机器人>中的例子,主要详解介绍_train_graph()函数中变量的具体值. 一.rasa/model_trainin ...
- 开源的代名词「GitHub 热点速览」
当开发者谈论开源时,通常会想到 GitHub,它不仅仅是一个代码托管平台,更是一个汇聚了全球开发者的社交中心.过去,开发者发布一款软件后,都是在自己的小圈子里默默努力和交流,现在通过 GitHub 平 ...
- C++篇:第六章_指针_知识点大全
C++篇为本人学C++时所做笔记(特别是疑难杂点),全是硬货,虽然看着枯燥但会让你收益颇丰,可用作学习C++的一大利器 六.指针 (一)指针规则 两个指针不能进行加法运算,因为指针是变量,其值是另一个 ...
- 第九部分_Shell脚本之case语句
case语句 关键词:确认过眼神,你是对的人 case语句为多重匹配语句 如果匹配成功,执行相匹配的命令 1. 语法结构 说明:pattern表示需要匹配的模式 case var in #定义变量;v ...
- 手绘流程图讲解spark是如何实现集群的高可用
摘要:本文讲述spark是怎么针对master.worker.executor的异常情况做处理的. 本文分享自华为云社区<图解spark是如何实现集群的高可用>,作者:breakDawn. ...
- mysql新增数据库新增用户并授权用户
-- 创建数据库CREATE DATABASE baseName; -- 创建用户CREATE USER 'userName' @ '访问限制' IDENTIFIED BY 'password'; ...
- iOS应用程序发布流程:从测试到上架的完整指南
目录 转载:iOS应用程序的签名.重签名和安装测试 前言 打开要处理的IPA文件 设置签名使用的证书和描述文件 开始ios ipa重签名 转载:iOS应用程序的签名.重签名和安装测试 前言 ipa ...
- Solon2 之基础:四、应用启动过程与完整生命周期
串行的处理过程(含六个事件扩展点 + 两个函数扩展点),代码直接.没有什么模式.易明 提醒: 启动过程完成后,项目才能正常运行(启动过程中,不能把线程卡死了) AppBeanLoadEndEvent ...
- PPT 流星动画
https://www.bilibili.com/video/BV1w54y1Q7cZ?p=6 星空背景绘制 绘制矩形框 背景不再被拖动 处理前先复制一份,用于后面做激光效果 星星效果 再次组合 按S ...
- Redis 数据一致性
概述 当我们在使用缓存时,如果发生数据变更,那么你需要同时操作缓存和数据库,而它们两个又分属不同的系统,因此无法做到同时操作成功或失败,因此在并发读写下很可能出现缓存与数据库数据不一致的情况 理论上可 ...