我最近在试验Docker。我尝试构建一个看起来像这样的图像架构,以便于维护和扩展。
我使用以下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
答案 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 update
和apt-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中详细了解相关内容 文档部分。