gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 05:00:04 25 4
gpt4 key购买 nike

我最近正在尝试使用 Docker。我尝试构建一个像这样的镜像架构,以便于维护和扩展。

architecture

我使用以下 Dockerfile 构建了镜像,并对不同的容器大小感到好奇。为什么它们差别这么大?

以下 base/Dockerfile 会生成 210.9 MB 镜像(ubuntu:trusty 有 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

最佳答案

在不考虑所有深度差异的情况下,最可能的原因是您没有考虑分层文件系统。

Docker 为 Dockerfile 中的每条指令创建一个镜像层。基本上发生的事情是(非常简单):

所以,这将成为第一层:

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

减少了 20MB!

您可以在Dockerfile best practice中阅读更多相关信息。文档部分。

关于docker - 为什么继承的 Docker 镜像大小不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36237999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com