十分钟可以跟着Docker学分层复用思想
发布时间 - 2022-01-19 00:00:00 点击率:次本篇文章给大家带来了关于docker中镜像分层、容器分层和容器在磁盘占用空间的相关问题,希望对大家有帮助。
Docker是如何组织存储的
dokcer在组织存储内容时很巧妙的应用了分层复用的思想。所以我们可以以此为案例学习一下该思想。
1.镜像分层
一个Docker镜像在构建的过程中分了很多层,每一层都是只读的。结合下面例子进行说明:
# syntax=docker/dockerfile:1 FROM ubuntu:18.04 LABEL org.opencontainers.image.authors="org@example.com" COPY . /app RUN make /app RUN rm -r $HOME/.cache CMD python /app/app.py
这个Dockerfile中会有4条指令改变了文件系统并创建了新层。
-
FROM指令从ubuntu:18.04的镜像中创建了基础层。 -
LABEL指令仅仅修改了镜像的元数据,不会创建新层。 -
COPY指令将执行本次构建的当前目录中的内容添加到镜像当中,会创建一个新层记录改变。 - 第一个
RUN指令,构建了程序并将结果输出到镜像中,会创建一个新层记录改变。 - 第二个
RUN指令,删除了缓存目录,会创建一个新层记录改变。 -
CMD指令定义了容器中运行的指令,只是修改了镜像的元数据,并不会创建新层。
这里每层都只记录与其上一层的不同。当我们创建一个容器的时候,这是就会创建一层可写层,也叫容器层。对于正在运行中的容器的内容的变化都会记录在该层中。下图描述了该关系:
2.容器分层
容器和镜像的不同主要是最顶层的可写层的不同,所有对于容器的写操作都会记录在这层中,如果容器被删除,那么这个可写层也会被删除,但是镜像会被保留。
注意:如果想要多个容器共享相同的数据,可以通过Docker Volumes实现。
每个容器都有其自己的可写层,所有的变换都会被存放在其中,所以多个容器可共享同一个镜像。下图描述了该关系:
注意 :此处还有个细节,多个镜像可能共用相同的层,比如两个镜像中有相同的层,那么在构建或是拉取的时候发现本地以存在,则不会再次构建或拉取。所以计算镜像大小的时候,不能仅通过 docker images命令显示出的大小来汇总求和,该值有可能大于实际值。
3.容器在磁盘占用的空间
可以通过 docker ps -s命令,来看正在运行中的容器占用的空间(部分值)。两个列的不同代表的内容:
- size: 容器的可写层占用的磁盘大小
- virtual size: 包含了容器可写层和只读镜像的大小。
容器占用磁盘空间的其它途径:
- 容器产生的日志文件。
- 使用Volume和bind mounts挂载的内容。
- 容器的配置文件
- 内存中的内容(如果开启了swapping)
- Checkpoints(如果使用了该功能)
4.Copy-on-Write(CoW)策略
Docker中的存储驱动都是采用该策略。
CoW策略能够最大效率的共享和复制文件。如果一个文件在镜像的更低层存在,那么其上层(包括可写层)需要读取该内容则可以直接使用该文件。当需要对其进行修改时,会复制该文件到该层并进行修改。这最大限度的减少了IO和每个后续层的大小。
4.1共享使镜像更小
当我们使用 docker pull拉取镜像或是使用一个本地没有的镜像创建容器的时候,该镜像会被分层的存储到本地Dockers存储区域中。在linux中通常是 /var/lib/docker。
我们可以去 /var/lib/docker/目录下看我们已拉取各层镜像。比如使用 overlay2存储驱动。
这么多层,我们可以通过 docker image inspect来查看某个镜像包含哪些层
docker image inspect --format "{{json .RootFS.Layers}}" redis
docker image inspect --format "{{json .RootFS.Layers}}" mysql:5.7
通过上面查看我们可以看到redis和mysql5.7运用了同一层,这样共享相同层就大大节省了存储镜像的空间,同时也提升了拉取镜像的速度 。
我们可以通过 docker image history命令来查看镜像分层情况,以redis为例
docker history redis
注意 :
有些步骤的大小为0,是因为他们只改变了元数据,并不会产生新层,也不会占用额外的空间(除元数据本身)。所以上述redis镜像中包含了5层。
-
步骤,这些步骤可能是以下情况中的一种- 在另一个系统
上构建的 - 从Docker Hub中提取的
- 使用BuildKit作为构建器构建的。
- 在另一个系统
4.2复制让容器更有效率
当我们启动一个容器的时候,会添加一个可写层在镜像之上,用于存储所有的变化。当对已有文件进行修改的时候采用CoW策略。首先会到各层寻找到该文件,然后复制该文件到可写层,然后进行修改并存储。
这么做能够让我们最大限度地减少I/O操作。
但是,很明显的是当一个容器中的应用需要进行频繁的写操作,那么会造成可写层越来越庞大,此时我们可以通过Volume来帮助我们分担压力。
容器的元数据和日志是单独存放的,一般是存放在 /var/lib/docker/containers中,我们可以使用 du -sh /var/lib/docker/containers/*来查看各个容器占用多少。(容器ID其实就是文件夹名称的前12位)。
推荐学习:《docker视频教程》
# docker
# 镜像
# 我们可以
# 多个
# 创建一个
# 都是
# 当我们
# 该文件
# 放在
# 可以通过
# 到该
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
微信推文制作网站有哪些,怎么做微信推文,急?
jquery插件bootstrapValidator表单验证详解
jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】
如何为不同团队 ID 动态生成多个独立按钮
Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)
Laravel怎么实现验证码(Captcha)功能
Laravel安装步骤详细教程_Laravel环境搭建指南
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】
如何基于云服务器快速搭建个人网站?
1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤
高性能网站服务器配置指南:安全稳定与高效建站核心方案
昵图网官网入口 昵图网素材平台官方入口
Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作
晋江文学城电脑版官网 晋江文学城网页版直接进入
JavaScript如何操作视频_媒体API怎么控制播放
Laravel如何创建自定义中间件?(Middleware代码示例)
Python文件异常处理策略_健壮性说明【指导】
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
教学论文网站制作软件有哪些,写论文用什么软件
?
如何在Ubuntu系统下快速搭建WordPress个人网站?
制作旅游网站html,怎样注册旅游网站?
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
高端云建站费用究竟需要多少预算?
IOS倒计时设置UIButton标题title的抖动问题
Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】
Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出
利用vue写todolist单页应用
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
深入理解Android中的xmlns:tools属性
Bootstrap整体框架之JavaScript插件架构
C#如何调用原生C++ COM对象详解
jQuery validate插件功能与用法详解
深圳网站制作的公司有哪些,dido官方网站?
C++时间戳转换成日期时间的步骤和示例代码
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
轻松掌握MySQL函数中的last_insert_id()
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
Android实现代码画虚线边框背景效果
如何用花生壳三步快速搭建专属网站?
如何制作一个表白网站视频,关于勇敢表白的小标题?
Laravel如何实现密码重置功能_Laravel密码找回与重置流程
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件
如何在IIS中配置站点IP、端口及主机头?
Java解压缩zip - 解压缩多个文件或文件夹实例
如何用搬瓦工VPS快速搭建个人网站?


上构建的