关于java:镜像分层原理及容器层写时复制

31次阅读

共计 1496 个字符,预计需要花费 4 分钟才能阅读完成。

一、镜像分层与容器层

在进行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 页全都复印了一份,带回家做作业。

老师的练习册是原始文稿(副本)(原始文稿构建之后就只读不写,镜像层文件也是),同学们的练习册是在须要应用到的时候复印进去的,并在复印本 (正本) 上实现作业书写,不影响原来老师那本练习册(副本)的内容。这个就是典型的“写时复制 ”。
对于容器而言,复制进去的文件在面向容器内的运行时软件时,会笼罩原始镜像文件(对于学生而言也只看本人复制进去那份 – 不要抬杠:抄作业的除外,不看老师的原始文件)。也就是说产生写时复制之后原始镜像文件被暗藏,容器读写操作都只认复制进去的正本文件。留神:该正本文件存在于容器层,容器重启之后容器层从新建设,上一次容器运行时对于文件的批改全副失落!

欢送关注我的博客,更多精品常识合集

本文转载注明出处(必须带连贯,不能只转文字):字母哥博客 – zimug.com

感觉对您有帮忙的话,帮我点赞、分享!您的反对是我不竭的创作能源!。另外,笔者最近一段时间输入了如下的精品内容,期待您的关注。

  • 《kafka 修炼之道》
  • 《手摸手教你学 Spring Boot2.0》
  • 《Spring Security-JWT-OAuth2 一本通》
  • 《实战前后端拆散 RBAC 权限管理系统》
  • 《实战 SpringCloud 微服务从青铜到王者》
正文完
 0