返回顶部
首页 > 资讯 > 服务器 >彻底搞懂Docker镜像分层的实现
  • 184
分享到

彻底搞懂Docker镜像分层的实现

2024-04-02 19:04:59 184人浏览 八月长安
摘要

目录创建测试镜像查看镜像使用Docker inspect使用docker history镜像分层图镜像分层的好处镜像分层的实现Copy-on-write策略创建测试镜像 我们创建一个

创建测试镜像

我们创建一个最简单的镜像:

1.构建测试镜像v1.0:docker build -t image_test:1.0 .

FROM alpine:3.15.0 #除了继承基础镜像,啥也不做

2.构建测试镜像v2.0:docker build -t image_test:2.0 .

FROM alpine:3.15.0
RUN dd if=/dev/zero of=file1 bs=10M count=1 #添加一个10M的文件file1

3.构建测试镜像v3.0:docker build -t image_test:3.0 .

FROM alpine:3.15.0
RUN dd if=/dev/zero of=file1 bs=10M count=1 #添加一个10M的文件file1
RUN dd if=/dev/zero of=file2 bs=10M count=1 #添加一个10M的文件file2

这样本地就构建了3个测试镜像:

查看镜像

我们有2种方法查看镜像:

  1. 使用docker inspect:获取镜像的元数据
  2. 使用docker history:查看镜像的构建历史 使用docker inspect

使用docker inspect

查看镜像的元数据。
其中Parent可以看到父镜像, Layers这一项下面可以看到镜像的所有层。

使用docker history

使用docker history可以看到镜像的构建历史。
我们每一行列出了镜像包含的层。

使用docker history我们看到有一行很特别,就是镜像ID为的行,这一行是什么呢?
看了 官方文档 的描述,我们知道这些构建步骤要么是构建在另一个系统,要么是镜像的部分是从DockerHub上拉取下来的,要么是使用的是另一种构建工具BuildKit构建的。
很显然,我们这里就是第二种情况,因为我们的Dockerfile中第一句指令就是FROM alpine:3.15.0.

镜像分层图

根据上面的docker history命令,我们可以轻松的画出三个镜像的分层图:

从上面的图可以看到,我们的镜像是分层的,我们的Dockerfile中新增一条指令,就会新增一层!
如果我们将多个命令合成一个,那么也只会生成一层。修改一下上面的image_test:3.0,把两条RUN合并成一条:

FROM alpine:3.15.0
RUN dd if=/dev/zero of=file1 bs=10M count=1 && \
    dd if=/dev/zero of=file2 bs=10M count=1

使用docker history 查看image_test:4.0,可以看到,只有2层了!

镜像分层的好处

知道了镜像是分层的,那么我们是不是好奇为啥要这么设计呢?
试想一下我们如果不分层会有什么问题?

以拉取镜像为例!
拉取镜像的镜像很大,比如Redis的镜像有100多M
第一次我们拉取6.2版本的Redis,下载了完成的100M到本地,下次我要下载6.2.6版本的,是不是又得下载100M。
尽管可能两个版本之间就改了几行配置文件。

这样是非常低效的。如果能只下载有差异的部分就好了!

这个痛点,也就是镜像分层要解决的问题。实际上,Docker也是这么实现的。
第一次下载redis:6.2时,因为之前没有下载过,所以下载了所有的层,总共113M。网络慢点的话还是需要花一些时间的!

第二次下载redis:7.0-rc,就变得快了很多!因为前面3层是redis:6.2是一样的,这些层已经下载过了!

这种思想和我们常用的版本管理工具git也是一样的!
如果版本2是基于版本1的基础上,那么版本2不需要copy一份全量的数据,只需一份和版本1差异化的增量数据即可!

这样的最终好处是,可以体现在以下方面:

  • 拉取更快:因为分层了,只需拉取本地不存在的层即可!
  • 存储更少:因为共同的层只需存储一份即可!
  • 运行时存储更少容器运行时可以共享相同的层!

对于第3点,多个基于相同镜像运行的容器,都可以直接使用相同的镜像层,每个容器只需一个自己的可写层即可:

镜像分层的实现

前面说过,Docker镜像分层和git的版本很像!我们不妨以此类比!只是为了方便我们理解:

GitDocker
版本分层
在前一个版本的基础上在前一层的基础上
修改了代码Dockerfile中加了RUN等指令
commit了修改,新增了一个版本新建一个镜像层
新版本只包含差异新镜像只包含了差异修改
已提交的commit是不能修改的旧的镜像层是不能修改的

总而言之,镜像层是只读的,新的镜像层是基于前一个镜像层的修改,只保留了增量修改的部分!
使用了联合文件系统,对文件系统的修改作为一次提交来一层层的叠加!

容器本质上也是在镜像的基础上加了一层可写层!这个在另外的章节再详细讨论!

Copy-on-write策略

Copy-on-write是一种提高文件共享和复制效率的策略。
如果一个文件和目录在低一层的镜像层中存在,并且其它层想要读取这个文件,就直接使用这个文件。
如果其它层想要修改这个文件(不管是构建镜像时,还是在容器运行的过程中),这个文件都会被先拷贝到新的一层中,然后再修改它。

这样做的好处是可以大大减少每一层的大小!
更具体的实现请参考官方文档中:Copy-on-write策略

到此这篇关于彻底搞懂Docker镜像分层的文章就介绍到这了,更多相关Docker镜像分层内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 彻底搞懂Docker镜像分层的实现

本文链接: https://lsjlt.com/news/139850.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 彻底搞懂Docker镜像分层的实现
    目录创建测试镜像查看镜像使用docker inspect使用docker history镜像分层图镜像分层的好处镜像分层的实现Copy-on-write策略创建测试镜像 我们创建一个...
    99+
    2024-04-02
  • Docker镜像分层怎么实现
    今天小编给大家分享一下Docker镜像分层怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。创建测试镜像我们创建一个最简...
    99+
    2023-07-02
  • Docker 彻底删除私有库镜像的操作
    首先看看网上一般的做法 私有库默认是不支持删除镜像的,需要修改config.yml配置文件,在storage节点下加入 delete: enabled: true ,然后重启私有库。...
    99+
    2024-04-02
  • 一文带你彻底搞懂Docker中的cgroup的具体使用
    目录什么是cgroupcgroup的组成cgroup提供的功能限制cgroup中的CPU限制cgroup中的内存限制cgoup的进程数前言 进程在系统中使用CPU、内存、磁盘等计算资...
    99+
    2024-04-02
  • docker镜像分层的方法是什么
    Docker镜像分层是通过使用Union文件系统(UnionFS)实现的。UnionFS是一种轻量级的...
    99+
    2023-09-16
    docker
  • 【Redis进阶】一文搞懂Redisson的看门狗机制底层实现
    文章目录 1. 看门狗机制概述2. 源码解读3. 总结 1. 看门狗机制概述 看门狗机制是Redission提供的一种自动延期机制,这个机制使得Redission提供的分布式锁是可以自动续...
    99+
    2023-09-01
    redis java 数据库
  • Docker镜像分层的注意事项有哪些
    这篇文章主要讲解了“Docker镜像分层的注意事项有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Docker镜像分层的注意事项有哪些”吧!docker...
    99+
    2024-04-02
  • Docker镜像的分层存储机制是什么
    Docker镜像的分层存储机制是通过使用UnionFS(Union File System)技术来实现的。Uni...
    99+
    2024-05-07
    Docker
  • Spring Boot 分层打包 Docker 镜像实践及分析(推荐)
    目录1.准备springboot项目2.进行相关配置3.package4.Dockerfile5.应用程序修改&dive分析1. 准备 spring boot 项目 简单,略...
    99+
    2024-04-02
  • Docker 删除镜像的实现
    删除镜像 如果要删除本地的镜像,可以使用 docker rmi (注意rm为删除容器,而rmi为删除镜像,其中i代表image)命令,它的具体语法如下: docker rmi [OP...
    99+
    2023-03-02
    Docker 删除镜像
  • 一文带你彻底搞懂Behavior实现复杂的视觉联动效果原理
    目录1、什么是 Behavior ?2、Behavior 接口的重要方法2.1 Behavior 生命周期相关的回调方法2.2 子控件着色相关的回调方法2.3 测量和布局相关的回调方...
    99+
    2023-05-17
    Behavior复杂视觉联动 Behavior 视觉联动
  • 深入理解docker镜像的分层(小白必看)
    大家好,今天分享docker镜像的分层理解 我们拉取Redis 镜像 [root@localhost ~]# docker pull redis Using default tag:...
    99+
    2024-04-02
  • Docker容器的加载分层原理及commit镜像
    目录Docker容器的加载原理、分层原理、commit镜像一、什么是镜像二、docker镜像加载原理1. 联合文件系统UnionFS2. 镜像加载原理三、分层原理四、com...
    99+
    2024-04-02
  • 怎么进行Spring Boot 分层打包Docker 镜像实践及分析
    本篇文章给大家分享的是有关怎么进行Spring Boot 分层打包Docker 镜像实践及分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1. ...
    99+
    2023-06-22
  • Linux中Docker镜像如何实现文本切分
    这篇文章将为大家详细讲解有关Linux中Docker镜像如何实现文本切分,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。文本切分接下来,使用 cut 命令对结果进行进一步切分并取出第三个字段:$ ...
    99+
    2023-06-27
  • Docker镜像发布到Docker Hub的实现方法
    目录一、Docker 官网注册一个账号,新建仓库二、制作镜像,保存修改后的容器镜像为例三、镜像上传四、镜像下载在使用docker过程中,往往会用到镜像仓库,方便管理的同时也方便在其他...
    99+
    2024-04-02
  • C++ vector的底层实现分析
    这篇文章主要介绍“C++ vector的底层实现分析”,在日常操作中,相信很多人在C++ vector的底层实现分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++ vector的底层实现分析”的疑惑有所...
    99+
    2023-06-25
  • IDEA部署Docker镜像的实现示例
    目录Docker镜像操作容器操作开启Docker的远程连接IDEA 下载 插件IDEA 推送镜像安装MySQL安装nginx部署项目远程访问Docker 容器中文字体乱码问题Dock...
    99+
    2023-05-18
    IDEA部署Docker镜像 IDEA部署Docker
  • 一篇文章彻底弄懂C++虚函数的实现机制
    目录1、虚函数简介2、虚函数表简介3、有继承关系的虚函数表剖析3.1、单继承无虚函数覆盖的情况3.2、单继承有虚函数覆盖的情况3.3、多重继承的情况3.4、多层继承的情况4、总结1、...
    99+
    2024-04-02
  • Docker构建镜像的两种方式实现
    目录从已有镜像更新镜像:从零开始构建镜像:从 docker 镜像仓库中下载的镜像不能满足我们的需求时,可以通过以下两种方式对镜像进行更改。 从已有镜像更新镜像 从零...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作