本文目录一览:
为什么docker上自己创建的mysql镜像特别大
在制作镜像的过程中,我们要注意几点:
1.文件系统是UnionFs,Dockerfile中每一条RUN都会生成一个层次(layer)。所以我们需要在每一条RUN之后清理产生的数据。因为生成的结果(3G的大小)是各层次大小的线性叠加。
2.为什么官方的镜像普遍偏小呢?我们就以mysql:5.6来作为参考,来分析一下:
RUN apt-get update apt-get install -y perl --no-install-recommends rm -rf /var/lib/apt/lists/*在更新组建以后,接着删除了apt的缓存的包文件。通常来说这个文件夹视情况会占用100M左右。-docker镜像文件大小
RUN { ... apt-get update apt-get install -y
mysql-server="${MYSQL_VERSION}" rm -rf /var/lib/apt/lists/* rm
-rf /var/lib/mysql mkdir -p /var/lib/mysql 在安装db以后,照例删除缓存的包文件。删除/var/lib/mysql能清除示例数据库。
而我们观察一下,hub.docker.com中最常用的vim包,我们发现haron/vim镜像是300M用的scratch作为基础镜像。
在hub.docker.com上粗略找了下,没有找到用centos做基础的mysql镜像。个人估计是缓存的包没有删掉,导致的问题。
至于@ShawnTaoo兄弟提到的基础镜像大小问题,我也做了下调查:centos:latest 190+MB, debian:jessie: 130+MB, ubuntu:latest 180+MB
Docker镜像存储格式分析
新版本的docker镜像存储其实是很绕的,各种ID和目录定义较多,不是很直观,本文较详细的分析一下镜像本地存储和在registry存储的格式。测试用的docker版本是20.10.9,存储引擎overlay2。-docker镜像文件大小
为了方便分析镜像层级结构,我们基于ubuntu加两个文件,使用 docker build -t myubuntu . 创建一个新镜像myubuntu。
镜像元数据存储在 /var/lib/docker/image/overlay2 :
imagedb目录存储的是镜像元数据。
镜像ID是从Image Json文件得到的,即 sha256sum(ImageJson)。
Layer DiffID是没有压缩的对应层的tar文件的sha256sum值。当然,打包和截包文件的适合得保证是可以可重复操作的,不然会导致Layer的DiffID出错(可以使用tar-split保存tar headers)。比如上面例子中ubuntu镜像只有一层,diff_ids列表只有 (history里面的CMD不占磁盘空间) "sha256:350f36b271dee3d47478fbcd72b98fed5bbcc369632f2d115c3cb62d784edaec"。每一层的tar文件我们可以通过 docker save ubuntu -o ubuntu.tar 得到,解压ubuntu.tar后可以得到对应的层级的打包后的layer.tar文件,如下可以验证DiffID的值计算原理。-docker镜像文件大小
ChainID用于标识镜像层级栈,它的值由DiffID计算得来。ChainID对应的layer目录是 /var/lib/docker/image/overlay2/layerdb/sha256 ,这下面的目录就是ChainID,其中内容存储了镜像的层级栈关系。比如这一层的parent是什么,以及对应的镜像数据存储目录的cache_id。本身layerdb只是存储layer的元数据信息,并不存储实际镜像数据。-docker镜像文件大小
即最底层的ChainID跟DiffID一样,而其他层的ChainID则是通过计算从最底层到这层的Digest得到。
查看Image Json文件可以看到myubuntu相比ubuntu的diff_ids加了两层,imagedb目录下面也多了两个镜像元数据信息文件,对应新增加的两层镜像。
除了之前的350f...对应ubuntu,其中7c7e是one.txt那层,而a58f则是two.txt那层。
我们可以看下ChainID目录下的内容,可以看到除了ubuntu的基础层,其他层都有一个文件parent,值就是父层的diff_id,diff是diff_id值,cache-id则是镜像实际存储目录,位于 /var/lib/docker/overlay2/{cache-id} ,size是这一层实际增加文件的大小,tar-split.json.gz是打包这层镜像的配置(参考 )。-docker镜像文件大小
CacheID是一个uuid值,每次都不一样。它对应的目录 /var/lib/docker/overlay2/${CacheID} ,该目录存储了镜像每层文件和下一层的链接等。验证一下:
其中diff目录下面便是这一层的文件。link是对应的diff目录的短链接,lower则是下一层diff目录的短链接。
在layerdb目录的size文件可以看到每一层的镜像大小,但是加起来跟 docker images 显示的大小会有点差距,比如myubuntu镜像每一层计算加起来是 4 + 65593591 + 4 = 65593599 / 1024 / 1024 = 62.55MiB ,实际显示是 65.6MB,这是因为 docker images 里面计算是按 65593599/1000/1000=65.59 计算的。-docker镜像文件大小
另外,因为镜像每层记录的是相对前一层的文件变化,即便删除了文件和软件包,新镜像大小也不会变小。除非使用 docker export 重新导出一个新镜像。
这个目录存储的是layer diffid和digest的关系,其中digest是镜像仓库里面的目录ID。
其中 v2metadata-by-diff存储了layer diffid对应在镜像仓库的信息,包括digest,sourcerepository等。
diffid-by-digest则是反过来的,文件名是仓库里面的layer digest,内容是layer diffid。因为我们新加的镜像myubuntu并没有push到仓库,所以这个目录下面没有信息。-docker镜像文件大小
我们创建一个本地的registry,然后对myubuntu另外打个tag, docker tag myubuntu 127.0.0.1:5000/myubuntu ,则respositories.json会多一条新的记录。此时,distribution目录还没有变化。-docker镜像文件大小
当我们执行 docker push 127.0.0.1:5000/myubuntu ,则会发现distribution的两个目录分别多了两条记录,对应的是myubuntu的 7c7e... 和 a58f... 两个diffid。此时repository.json里面 127.0.0.1:5000/myubuntu 会多一条带digest的记录,这就是镜像仓库里面对应的digest。其中push时显示的 digest:sha256:bb3c... 对应的是registry的manifest文件的digest,下一节分析。-docker镜像文件大小
registry中存储的镜像文件是经过gzip压缩,比如myubuntu本地大小是65.6MB,推到registry压缩后大小约27MB,压缩比还是不错的。registry存储目录如下,主要分为blobs和repositories两个目录。-docker镜像文件大小
repositories的一级子目录是镜像名,这里是myubuntu。下面对应三个子目录 _manifests,_layers, _uploads。
blobs存储的内容除了各镜像layer的压缩后的文件,还包括Manifest Json和Image Json文件(未压缩)。
选一个layer的压缩文件data解压看一下内容:
另外需要注意的是, docker pull 时前面显示的值是对应层在registry的压缩文件的digest值,并不是layer diffid,size也是registry存储的压缩文件大小。
构建Docker镜像应该遵循哪些原则?
整体远侧上,尽量保持镜像功能的明确和内容的精简,要点包括:
(1)尽量选取满足需求但较小的基础系统镜像,建议选择debian:wheezy镜像,仅有86MB大小
(2)清理编译生成文件、安装包的缓存等临时文件
(3)安装各个软件时候要指定准确的版本号,并避免引入不需要的依赖
(4)从安全的角度考虑,应用尽量使用系统的库和依赖
(5)使用Dockerfile创建镜像时候要添加.dockerignore文件或使用干净的工作目录
我推荐你去看看时速云,他们是一家全栈云原生技术服务提供商,提供云原生应用及数据平台产品,其中涵盖容器云PaaS、DevOps、微服务治理、服务网格、API网关等。大家可以去体验一下。 如果我的回答能够对您有帮助的话,求给大大的赞。-docker镜像文件大小
docker镜像限制请求大小
您好!Docker镜像的请求大小受限是指使用者无法在Docker Hub上上传超过100MB的镜像,如果您想要将大体积的文件上传到Docker Hub中,您可以选择其它非Docker Hub存储空间,例如Amazon S3,将文件上传至您的该存储空间,再利用Dockerfile指令来拉取文件即可。-docker镜像文件大小