如何构建一个磁盘空间消耗相对较小的大型docker镜像?

时间:2016-03-10 22:39:45

标签: docker dockerfile docker-build

背景

我正在尝试从VM上的Dockerfile构建一个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

我的构建虚拟机有 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基于Union FS,因此图像层叠在一起。 所以我的理解是

(1)我的图像可以获得的最大尺寸是11G(一层3G安装程序,顶层8G添加包层)

(2)如果我忘记安装程序,运行它,然后在相同的RUN命令中删除安装程序,图像应该只是8G(因为删除了3G安装程序)

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

问题

但我目前的观察是在我的码头工程构建过程中, 它会一直挂起,因为它占用了所有可用空间

[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 inspect”显示&lt;没有&gt;图像是COPY权利文件后的中间图像。

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. 为什么码头工人占用了所有空间?根据计算,磁盘空间(16G)应该足够用于目标图像(8G)。 [我拥有这个虚拟机,所以我可以保证没有其他人或任何其他进程占用硬盘空间]

  2. 如何在当前情况下强制移除容器,以便我可以恢复空间?

  3. 如何在16G虚拟机上构建此8G映像(如果算上安装程序,则为11G映像)?如果无法做到这一点,成功构建它的最小空间是多少?我目前正在申请实验室的32G虚拟机。

1 个答案:

答案 0 :(得分:1)

<强> TL; DR

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

如果我发布Dokcer文件,那么构建此图像的最小磁盘要求至少为22 G [(3 + 8)* 2 = 22]。

如果我发布图像并推送到Dockerhub,那么用户只需要11 G来拉动图像并运行基于它的容器。

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

<强>构建

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

在构建开始之前

# 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)它耗尽了所有磁盘,因为它至少需要很多磁盘空间。以前的计算一直以为假设正在运行的容器和要构建的图像将共享同一层。

(2)尚未弄清楚这一部分。现在我只是扔掉VM并让它回收它。

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

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

生成

为了跟进,在我提交图像并删除容器后,可以回收磁盘

# 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% /
...