为什么继承的Docker镜像大小不同

时间:2016-03-26 16:47:21

标签: docker

我最近在试验Docker。我尝试构建一个看起来像这样的图像架构,以便于维护和扩展。

architecture

我使用以下Dockerfiles构建了图像,并对不同的容器大小感到好奇。为什么他们差异很大?

base / Dockerfile 之后会产生 210.9 MB 图像(ubuntu:可信任,具有188 MB,这样就可以了)。

FROM ubuntu:trusty
RUN apt-get -qq update && \
    DEBIAN_FRONTEND=noninteractive apt-get -qq install \
    nano
ENV TERM xterm
RUN apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

apache / Dockerfile 会产生 224.4 MB

FROM ubuntu:trusty
RUN apt-get -qq update && \
    DEBIAN_FRONTEND=noninteractive apt-get -qq install \
    nano \
    apache2
ENV TERM xterm
RUN apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
COPY apache2-foreground /usr/local/bin/
RUN chmod a+x /usr/local/bin/apache2-foreground
EXPOSE 80
WORKDIR /var/www/html
CMD ["apache2-foreground"]

apache-php / Dockerfile 会产生 266.7 MB

FROM ubuntu:trusty
RUN apt-get -qq update && \
    DEBIAN_FRONTEND=noninteractive apt-get -qq install \
    nano curl \
    apache2 \
    libapache2-mod-php5 php5-mysql php5-mcrypt php5-gd php5-curl php-pear php-apc && \
    curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN /usr/sbin/php5enmod mcrypt
# + last 7 lines from apache/Dockerfile

到目前为止这很好但我们直到现在才使用继承。我们来看看:

为什么 apache-php-on-base / Dockerfile 导致 289.4 MB ?它基本上是相同的步骤,但分为两个图像。我本来期望有一点开销,但不是10%左右。

FROM base
# + apache-php/Dockerfile without "install nano"

使用多重继承甚至更大: apache-php-on-apache-on-base / Dockerfile 会导致 314.9 MB

FROM apache-on-base
# + apache-php/Dockerfile without "install nano apache2"

apache-on-base / Dockerfile 当然是(导致 247 MB​​ ):

FROM base
# + apache/Dockerfile without "install nano"

问题:是否有办法阻止图像增长,同时保持可维护性?

更新:实施thaJeztah的建议我得到了关注:)再次感谢!

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
apache-php-on-aob   latest              2cf12a3b5872        2 minutes ago       249.9 MB
apache-on-base      latest              121c8a098ff5        3 minutes ago       203.7 MB
base                latest              ee95e4f8aaee        3 minutes ago       189.3 MB
apache-php-on-aob   v1                  e43df5e61aed        3 days ago          314.9 MB
apache-on-base      v1                  c291f91f1a10        3 days ago          247 MB
base                v1                  b181fc6f181d        3 days ago          210.9 MB
ubuntu              trusty              97434d46f197        10 days ago         188 MB

1 个答案:

答案 0 :(得分:2)

没有经历所有深度差异,最可能的原因是 你没有考虑分层文件系统。

Docker为Dockerfile中的每条指令创建一个 new imagelayer。基本上 会发生什么(非常简化):

所以,这将成为第一层:

FROM ubuntu:trusty

(和Docker一样)

Docker build -t layer1 .

这将成为第二层:

FROM layer1
RUN apt-get -qq update && \
    DEBIAN_FRONTEND=noninteractive apt-get -qq install \
    nano

(和Docker一样)

Docker build -t layer2 .

等等。

最终图像是所有这些图像的组合"堆叠"。重要的是 意识到在" layer1"中添加了一个文件,但是" layer2"中的已删除 仍然是图像的一部分; Docker只将其标记为"删除"在layer2中,但那 不会使图像变小。

让我们来看看你的第一个Dockerfile。正如您所看到的那样,添加很多 第一个RUN指令中的文件,然后添加一个仅设置的空图层 ENV var,后跟另一个RUN删除所有冗余文件 从第一个RUN。但是,这些文件不会从早期图层中删除, 所以仍然占用最终图像中的空间;

FROM ubuntu:trusty
RUN apt-get -qq update && \
    DEBIAN_FRONTEND=noninteractive apt-get -qq install \
    nano
ENV TERM xterm
RUN apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

构建(docker build -t foobar .)后,这给了我:

REPOSITORY  TAG      IMAGE ID      CREATED        SIZE
foobar      latest   363aa5572838  2 minutes ago  210.9 MB

进行小的更改,并结合两个RUN指令,以便同时进行 apt-get updateapt-get clean步骤发生在相同的 RUN中,因此 相同的层;

FROM ubuntu:trusty
RUN apt-get -qq update && \
    DEBIAN_FRONTEND=noninteractive apt-get -qq install \
    nano && \
    apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
ENV TERM xterm

构建它,产生这个图像:

REPOSITORY  TAG      IMAGE ID      CREATED        SIZE
foobar      latest   ac8fb5e4db16  9 minutes ago  189.3 MB

那个小20英尺!

您可以在Dockerfile best practice中详细了解相关内容 文档部分。