如何build立一个相对较小的磁盘空间消耗大docker图像?

背景

我正在尝试从虚拟机上的Dockerfile构build一个docker镜像。 VM正在运行Redhat 7.1(内核3.10),Docker是1.10.2

Dockerfile有以下内容

FROM rhel MAINTAINER MyName<me@email.com> RUN #yum install wget and other tools (less than 500 MB) COPY entitlementfile /opt/entitlementfile RUN wget -O /opt/installer.bin https://installer.com/installer.bin \ && chmod +x /opt/* \ && /opt/installer.bin --quiet \ && rm -f /opt/*.bin USER admin 

我的构build虚拟机有大约16G的可用空间

 [root@xrh701 DockerImage]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/rhel-root 18G 2.1G 16G 12% / ... 

安装程序在3G左右,安装包大约8G 。 这最多增加了11G,稍微超过docker默认的基础设备大小,即10G。

所以我手动调出一个更大的dm.size( 15G )的docker守护进程来解决这个问题。

 docker daemon --storage-opt dm.basesize=15G 

由于docker是基于联合FS,图像层叠在一起。 所以我的理解是这样的

(1)我的图片可以获得的最大尺寸是11G(安装在一层3G,封装层添加在顶部8G)

(2)如果我安装了安装程序,运行它,然后在同一个RUN命令中删除安装程序,图像应该只有8G(因为3G安装程序被删除)

无论哪种方式,底线是,16G的空间应该是绰绰有余的。

问题

但我目前的观察是,在我的docker构build过程中,它会一直挂起,因为它已经消耗了所有可用的空间

 [root@xrh701 DockerImage]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/rhel-root 18G 18G 20K 100% / ... 

我可以看到两个图像

 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> fa09e98656ba About an hour ago 258.1 MB rhel latest 32f8a1d5f019 9 days ago 203.2 MB 

“docker检查”显示<无>图像是复制授权文件后的中间图像。

 docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 232245023f90 fa09e98656ba "/bin/sh -c 'wget -O " About an hour ago Exited (0) About an hour ago lonely_curie 

此中间容器已完成RUN wget行,已成功退出,但由于空间不足而没有提交给Docker映像

更糟糕的是,我不能删除容器,也不能删除/ var / lib / docker来恢复空间

 # docker rm -f lonely_curie Failed to remove container (lonely_curie): Error response from daemon: Driver devicemapper failed to remove root filesystem 232245023f90b42a4dbd19a78bf32836f9f8618d7dbcba54159c3df029b5b114: mount still active 

  1. docker工人为什么用完了所有的空间? 根据计算,磁盘空间(16G)应该足够用于目标映像(8G)。 [我拥有这个虚拟机,所以我可以保证没有其他人或任何其他进程占用硬盘空间]

  2. 我如何强制拆除目前的容器,以便恢复空间?

  3. 我应该如何在16G虚拟机上构build这个8G映像(如果您计算安装程序,则为11G映像)? 如果这是不可能的,成功构build它的最小空间是多less? 我目前正在申请从实验室的32G虚拟机。

TL; DR

假设安装程序是3G,安装的软件包是8G。

如果我释放Dokcerfile,那么最小磁盘要求至less为22 G [(3 + 8)* 2 = 22]来构build这个镜像。

如果我释放图像并推送到Dockerhub,那么用户只需要11 G就可以拉出图像并运行一个容器。

================================================== ================

build立

我有一台大约50G的机器重新运行构build并监视磁盘的消耗。

开始之前

 # df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_01-lv_root 59G 6G 53G 9% / ... 

安装完成后

 # df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_01-lv_root 59G 19G 38G 34% / ... 

图像被提交后

 # df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_01-lv_root 59G 27G 30G 48% / ... 

所以要回答我自己的问题:(1)它用完了所有的磁盘,因为它至less需要那么多的磁盘空间。 以前的计算曾经假定正在运行的容器和要构build的图像将共享同一图层。

(2)还没有弄清楚这个部分。 现在我只是扔掉虚拟机,让它回收。

(3)所需的最小磁盘尺寸为(3G + 8G)* 2 = 22 G.所以我想为将来的参考,我应该保留两倍的理论计算的图像大小,因为该图层似乎是复制,而不是共享当提交正在运行的容器到图像。 [构buildDockerfile与手动运行容器并提交图像基本相同。]

================================================== ===============

而后续,我提交图像并删除容器后,磁盘可以回收

 # df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_01-lv_root 59G 15G 42G 26% / .... 

从此,启动一个正在运行的容器不会增加磁盘消耗(显着)。

 # df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_01-lv_root 59G 15G 42G 26% / ...