dockerfile 修改文件权限_网易技术实践|Docker文件系统实战

0f93a7202468cc1a90d89418a874ce2c.png

在本文中,我们来实战构建一个Docker镜像,然后实例化容器,在Docker的生命周期中详细分析一下Docker的文件存储情况和DockerFile优化策略。

74af5a95dfb2e081a2031f3a2432d645.png

23a46a296ffa4dcc0420e552c074e9a8.png

在开始实战之前,我们先介绍一个概念,联合文件系统(Union File System)。联合文件系统是实现Docker镜像的技术基础,支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。镜像的分层存储和继承就是基于此特性实现。

下面是Docker官方的一张描述文件系统的图片,显示了一张联合文件系统在串联镜像层和容器层起到的作用

ac92feae64cad1ffd22cbc228f42e843.png

Docker支持多种联合文件系统,常见的有aufs,deviceMapper,overlay,overlay2,本文章中使用的系统版本为debian9.1,Docker版本为17.06.2-ce,默认使用是overlay2。

看到这里如果你已经对Docker文件系统有了简单的概念,那么让我们开始实战,来对分层文件系统的存储方式进行更加深入的了解。

镜像层

这是一个云信私有化项目中基于debian系统镜像创建的jdk8基础镜像,为了方便阅读和分析,我们Dockerfile进行了一些精简,只保留核心部分内容

FROM hub.c.163.com/library/debian:stretch
MAINTAINER nim
#下载jdk
ADD http://10.173.11.100/nim/jdk-8u202-linux-x64.tar.gz /usr/local/nim/
#解压jdk并删除
RUN tar -xzvf /usr/local/nim/jdk-8u202-linux-x64.tar.gz -C /usr/local/nim/ 
&& rm /usr/local/nim/jdk-8u202-linux-x64.tar.gz
#设置环境变量
ENV JAVA_HOME=/usr/local/nim/jdk1.8.0_202
ENV PATH=$JAVA_HOME/bin:$PATH
CMD ["/bin/bash"]

根据构建镜像,查看构建结果,原基础镜像100M,构建后镜像体积697M。

5d5097e6630526a506f50287e9132d38.png

镜像存储

现在开始看一下构建镜像工作在文件层存储情况。首先我们使用Docker history查看一下刚刚构建镜像情况,可以看到基础镜像占用100M,两个镜像分层占用194MB和403M。

663af5e2589aa0f3d6af78af7bc5af94.png

接下来我们看查看一下文件系统中的存储情况,本环境使用overlay2,Docker镜像层存储默认路径为/var/lib/Docker/overlay2/,可以看到镜像存储目录下有4个目录,其中110M的对应是基础镜像,另外两个为ADD JDK(186M)和解压JDK压缩包的镜像分层(389M)。

e8f92dedccd822ea53835dac5b0f07f8.png

其中的l目录包含了所有层的软连接,软链接使用短名称,避免mount时候参数达到页面大小限制。

2b059d7a81913d04c3136e67d7a723ef.png

下面我们了解一下,每个分层中的文件内容。基础镜像分层包含diff文件夹和link文件,diff文件夹中存放当前分层内容,link文件记录短名称。

f68e4b952c38a6545d0469713de6d1c9.png

接下来看一下COPY JDK生成的内容,diff文件夹保存了jdk压缩包,本层相比基础镜像层,多了lower,merged,work三个文件/文件夹,其中lower记录了此层的下层ID(基础镜像层),merged目录作为提供了统一视图,在容器层读写层被使用,work目录用于联合挂载指定的工作目录,使用过程对用户不可见。

a288077ada1986aa8a97b6fea9e1ad00.png

解压JDK层的文件夹结构内容和上一层类似,主要关注jdk压缩包占用空间为0,表示已被删除。

033e306f3a894a85728c0873bece29e8.png

现在来重点关注一个问题,镜像大小等于所有分层相加,在后续分层中被删除的jdk压缩包仍然要占用存储空间,这并不是我们原本意图,因此这里就出现了镜像文件进行优化的点。优化后的Dockerfile如下

FROM hub.c.163.com/library/debian:stretch
MAINTAINER nim
RUN curl -o /usr/local/nim/jdk-8u202-linux-x64.tar.gz http://10.173.11.100/nim/jdk-8u202-linux-x64.tar.gz 
&& tar -xzvf /usr/local/nim/jdk-8u202-linux-x64.tar.gz -C /usr/local/nim/ 
&& rm /usr/local/nim/jdk-8u202-linux-x64.tar.gz 
&& export JAVA_HOME=/usr/local/nim/jdk1.8.0_202 
&& export PATH=$JAVA_HOME/bin:$PATH
CMD ["/bin/bash"]

借这个优化后的内容,我们再谈一下构建Docker镜像时在时间和空间可优化的点

  1. 组合运行语句:合并相同类型构建语句,可以有效减少镜像分层;
  2. 利用镜像构建缓存:时间同步,基础软件安装等固定内容在镜像前部分处理,镜像重新构建时会使用缓存,节省时间;
  3. 清理中间产物:注意安装过程中使用的软件和压缩包在一定要同一层里清理,否则仍然会占用镜像空间;
  4. 构建语句优化:比如ADD在处理本地文件时可以直接解压缩,起到COPY + RUN tar的作用;
  5. 优化基础镜像源:国内高校和大型IT企业都有创建镜像站,选择一个稳定更新及时的镜像站可以有效缩短构建时间;

举例的镜像中优化策略涉及1,3条,用curl替代add,与解压和删除合并为一层,Dockerfile减少了层数,清理中间过程的jdk安装包,下图是优化后镜像体积变化:

5d730889df26af34be622705d9fe86ec.png

构建镜像真的是层数越少越好吗?当然不是这么绝对,尤其在早期镜像版本不是很稳定或是后续迭代比较频繁时,合理的镜像分层会减少编译时间,降低出错概率,也可以让Dockerfile更具有可读性。可以再稳定版本形成之后对镜像进行二次优化。

镜像元数据

分析一个镜像元数据我们主要关注三个目录

/var/lib/Docker/image/overlay2/imaged/
/var/lib/Docker/image/overlay2/layerdb/
/var/lib/Docker/overlay2/

第一个目录保存镜像基础元数据,第二个目录保存镜像分层元数据,第三个是上文提到的分层存储目录,保存实际分层内容。下面就根据实际情况来看一下,元数据与存储信息是如何关联起来的。

Docker镜像的基本信息保存在/var/lib/Docker/image/overlay2/imaged/content/sha256/下面,可以根据Docker image ID在此目录下查找到对应ID开头文件。此文件中以json的形式保存了该镜像的分层文件系统、构建信息、相关容器等内容。

cb26872414828b313de36202b508bb4b.png

第二个目录/var/lib/Docker/image/overlay2/layerdb/sha256/保存分层元数据,每一个分层元数据目录下有cache-id,diff,size信息,其中cache-id对应分层存储层,diff关联镜像基础元数据信息。

d56db5f92b612f15a7656e5315a8ca8a.png

4f79f90238fd39456be2faa3b0e31828.png

967daa19d787a061378f23024f679249.png

容器层

首先我们来启动一个容器,挂载宿主机/opt/yunxin目录到容器/usr/local/yunxin目录

8493e86adedff9cc3caf2c2392063e9a.png

创建容器完成之后,在镜像存储目录/var/lib/Docker/overlay2/会生成容器的初始层和读写层,两者使用相同标识,初始层后面多了-init。初始层中主要保存初始化容器环境时,与容器相关的环境信息,如容器主机名,主机host信息以及域名服务文件等;读写层用于容器的读写,Docker容器内的进程只对读写层拥有写权限,而对其他层文件内容只拥有读权限

ae2aeb2027e67bd9d40529008f078ad5.png

接下来我们进入容器操作进行一系列操作,再根据结果分析一下读写层对于文件的保存和处理,下面是操作和对应结果以及读写层实际文件存储情况。

b8f2c7fcccfb98bdbd0d6acec6d76eb2.png

a0784a2aac93b1596bb2b644034cf656.png

读写层中的merged文件夹提供了统一视图,面向用户展示联合文件系统挂载完成的最终形态。

835626ae3d97989f5c33c0bbdd2d28b0.png

接下来我们再基于同一个镜像启动几个容器实例,然后来查询一下Docker容器使用空间,只有第一个容器由于上面修改文件只占用154k,新启动的容器并没有额外占用空间。可见基于同一个镜像创建容器时,所有的容器共享镜像层内容,有效节约了空间。读写层只保存修改内容,如果是操作镜像层文件,Docker采用的是修改时复制策略(copy-on-write)。这时回头再看一下第一节出现的两张图,会对Docker的文件系统有了更深的体会。

7e783c6170f1529896febadbb4a312ce.png

结语

Docker 镜像和容器文件系统相关知识在云信私有化产品的镜像管理和运维存储管理方面作出理论支撑,但这只是深入了解Docker的开始。随着时间的积淀和云信旗下IM、音视频、点播以及众多相关产品私有化工作的深入,更多的模块和镜像,更多的客户和需求,更复杂的网络和环境都逐渐呈现在我们面前。Docker作为构建云信私有化服务的基础,只有更深入的去了解原理才能在使用中去更好的优化产品和开展运维。希望我们能为用户提供更可靠的云信私有化服务,也希望能在后续的文章中能与大家分享更多关于Docker的知识。

立即了解网易云信私有云>>

更多技术干货,欢迎关注vx公众号“网易智慧企业技术+”。系列课程提前看,精品礼物免费得,还可直接对话CTO。

74af5a95dfb2e081a2031f3a2432d645.png

听网易CTO讲述前沿观察,看最有价值技术干货,学网易最新实践经验。网易智慧企业技术+,陪你从思考者成长为技术专家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/551079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stm32c语言写数码管定时器,使用TIM1产生1秒定时控制数码管显示0-9(STM32_10)

一、项目配置1、新建项目文件夹"TimSeg";2、通过Keil5创建新项目,保存在所创建的文件夹中(设项目名为pTimSeg),选择MCU芯片为"STM32F103ZE"(本程序使用的硬件为:STM32-PZ6806L开发板)3、在"TimSeg"…

for循环c语言流水灯,巧用数组与for循环为流水灯程序瘦身

数组——一种储存大量同性质数据的连续存储器空间a [6];b [] {2,4,8,3,6};c[6] {1,2,3,4,5,6};char d[6] "hello";以上方式均是数组创建的常用方式~数组是从…

java的map 使用string数组多了双引号_奥奥奥利给!!!再也不怕面试官问我String源码了!来吧...

简述字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了String 类来创建和操作字符串。字符串缓冲区支持可变字符串。因为String对象是不可变的,因此可以共享它们。String类代表字符串,Java程序中的所有字符串字…

C 语言 运算符怎么使用,详解C++编程中运算符的使用

C的运算符十分丰富,使得C的运算十分灵活方便。例如把赋值号()也作为运算符处理,这样,abc4就是合法的表达式,这是与其他语言不同的。C提供了以下运算符:算术运算符(加) -(减) *(乘) /(除) %(整除求余) (自加) --(…

面积积分_袁颖妍:用定理积分求平面区域面积(有代表性的9个例题)

考研竞赛智慧e数学的广告:鸡汤所谓“理解”,所谓“智商”,本质上最终都归到"记忆",还有一点就是能够发现自己“记忆”中各个零散的知识点的关系。所谓“智商”高低的人,其实是强化这些“记忆”的能力的不同,…

字体选择_十分钟带你掌握精准选择字体的方法!

文章序言:上次记得有粉丝评论需要讲讲字体,今天就给大家带来一期关于,如何快速选择合适的字体的文章,帮助大家以后把字体用对,用好,用准。在讲这个字体的时候会结合实际的案例操作给大家讲解,这…

android自动生成cardview,学习使用Material Design控件(三)使用CardView实现卡片效果...

本文主要介绍CardView的使用,CardView是继承自FrameLayout,使用比较简单,只需要用CardView包含其他View就可以实现卡片效果了。实现效果如下:加入依赖库dependencies {….compile com.android.support:cardview-v7:22.2.0}Layout布…

android最新设计规范,Android应用未来的设计规范

谷歌在2014 I/O大会上不但发布了Android L,还一同推出了全新的Material Design设计语言,它被认为是未来Android系统和应用的设计方向。虽然Android L和谷歌自家的应用都会按照这一设计规范来执行,但第三方应用却没能够积极的响应。究竟用Mate…

移除apt源_apt提示处理归档 (--unpack)时出错的解决办法

#apt##Ubuntu##Debian#1、问题现象今天在升级软件的时候遇到一个错误,如下:rootx:~# apt --fix-broken install正在读取软件包列表... 完成正在分析软件包的依赖关系树 正在读取状态信息... 完成 正在修复依赖关系... 完成下列软件包是自动安装的并且现…

android 滑动接听源码,android仿摩拜单车APP、炫酷RecyclerView、卡片滑动、仿饿了么点餐、自定义索引等源码...

Android精选源码Android优质博客前言permissions4m 最初的设计是仅仅做成一个编译器注解框架,在1.0.0版本时,它纯粹地实现了原生 Android 请求流程,关于它的设计思路可以查看这篇如何打造一个 Android 编译时注解框架。但是当投入笔者自己项目…

zip版mysql5.6_mysql 5.6 压缩包版安装方法

Mysql安装的时候可以有msi安装和zip解压缩两种安装方式。zip压缩包解压到目录,要使用它还需对它进行一定的配置。下面对Mysql压缩包版的安装方法进行详细的描述,要是此文有不正确的认识,希望大家指正,非常感谢。一、下载mysql压缩…

鸿蒙系统 产品,华为首款鸿蒙系统产品成行业公敌!只因开机无广告:遭十大品牌批评...

【4月6日讯】随着荣耀30s手机正式发布,全新的麒麟820处理器也是再次给我们带来了巨大惊喜,毫无疑问,麒麟820处理器将会继续继承麒麟810处理器的“神U”特质,成为5G网络时代的新一代中端“神U”,但在荣耀30s发布会上&am…

html在线摄像头,在HTML里加载摄像头的方法

效果图: 整体效果:视频加载:拍照:第一步:创建HTML元素首先,我们要创建一个HTML5的文档。无标题文档然后在插入以下代码:截图第二步:创建JavaScript首先,要在里创建一个JavaScript&am…

mysql怎样实现先判断后联合_MYSQ创建联合索引,字段的先后顺序,对查询的影响分析...

MYSQ创建联合索引,字段的先后顺序,对查询的影响分析前言对于联合索引我们知道,在使用的时候有一个最左前缀的原则,除了这些呢,比如字段放置的位置,会不会对索引的效率产生影响呢?最左匹配原则联…

上海事业编制 计算机 待遇怎么样,事业单位情况

2010-09-12我们在公路系统工作,用工单位是事业单位编制,由上级部门批准招录下达指标。由于单位缺人,单位临时招录我们(不带指标),我们已工作八年,自2003-2009一直签订合同,2009年到期后至今未签订合同&…

如何修改操作系统运行服务器,如何设置Bios 最常见bios设置与修改详细图解教程...

平时我们在使用计算机的时候一般很少会接触到BIOS,很多人都是在安装操作系统时才接触到的,因为在使用光盘安装系统时需将计算机的BIOS设置为从光驱启动,在重装系统、设置硬盘模式以及一些特殊情况都需要进入bios里面,进行相关设置…

mysql 回滚失败_Mysql非事务表回滚失败的现象

执行ROLLBACK(回滚)时,如果收到下述消息,表示事务中使用的1个或多个表不支持事务: 警告:某些更改的非事务性表不能被回滚。 这些非事务性表不受ROLLBACK语句的影响。 如果在事务中意外地混合了事务性表和非事务性表,导…

mysql连表查询on条件_mysql 外连接的时候,条件在on后面和条件在where后面的区别...

最近使用mysql的时候碰到一个问题:当一个表外联另一个表的时候,将一些查询条件放在on后面和放在where后面不太一样:学生分数表stuscore:当查询语句如下(查询语句1):SELECT a.name,a.subject,a.score,a.stuid ,b.name,b…

应运ajax的几种语言,Ajax指的是什么

Ajax指的是什么发布时间:2020-08-05 14:18:52来源:亿速云阅读:103作者:小新这篇文章将为大家详细讲解有关Ajax指的是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可…

oracle 数据导入 mysql_oracle数据库导出和oracle导入数据的二种方法(oracle导入导出数据)...

这篇文章主要介绍了oracle导入导出数据的二种方法,利用PL/SQL Developer工具导出和利用cmd的操作命令导出的出方法,大家参考使用吧方法一:利用PL/SQL Developer工具导出:菜单栏---->Tools---->Export Tables,如下…