您的位置:首页 > 房产 > 家装 > 大网站的二级域名_沧州seo包年优化软件排名_宁德市医院东侨院区_网络推广外包搜索手机蛙软件

大网站的二级域名_沧州seo包年优化软件排名_宁德市医院东侨院区_网络推广外包搜索手机蛙软件

2024/12/23 8:42:58 来源:https://blog.csdn.net/ginkov/article/details/142980920  浏览:    关键词:大网站的二级域名_沧州seo包年优化软件排名_宁德市医院东侨院区_网络推广外包搜索手机蛙软件
大网站的二级域名_沧州seo包年优化软件排名_宁德市医院东侨院区_网络推广外包搜索手机蛙软件

先说结论:
有些时候能,有些时候不能,但你要明白原理 – Docker 使用 UnionFS,镜像尺寸随着层数增多,是单调非减的。

问题

看到一个 Dockerfile:

FROM python:3.17.7-alpine3.20
RUN pip3 install pillow
RUN pip3 install django
RUN pip3 install jieba
RUN pip3 install nltk
RUN pip3 install colormap

有人建议,把这几个 pip3 install 合并成一个 pip3 install -r requirements.txt,可以减小最终打包出来的镜像尺寸,真得是这样吗?

实验一:一次 pip 安装 vs 多次 pip 安装

多次 pip 安装

我们把上面这个最初始的 Dockerfile 打包出来的镜像起名为 temp:multi。
通过 docker image ls temp:multi 看到,这个包的大小为 396MB
然后,通过 docker history temp:multi 看到这个包的层级如下:

IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
a934e19243c7   2 hours ago   RUN /bin/sh -c pip3 install colormap   -i ht…   177MB     buildkit.dockerfile.v0
<missing>      2 hours ago   RUN /bin/sh -c pip3 install nltk       -i ht…   22.8MB    buildkit.dockerfile.v0
<missing>      2 hours ago   RUN /bin/sh -c pip3 install django     -i ht…   39.1MB    buildkit.dockerfile.v0
<missing>      2 hours ago   RUN /bin/sh -c pip3 install jieba      -i ht…   83.5MB    buildkit.dockerfile.v0
<missing>      2 hours ago   RUN /bin/sh -c pip3 install pillow     -i ht…   27.1MB    buildkit.dockerfile.v0
<missing>      2 weeks ago   CMD ["python3"]                                 0B        buildkit.dockerfile.v0
<missing>      2 weeks ago   RUN /bin/sh -c set -eux;  for src in idle3 p…   36B       buildkit.dockerfile.v0
<missing>      2 weeks ago   RUN /bin/sh -c set -eux;   apk add --no-cach…   38.1MB    buildkit.dockerfile.v0
<missing>      2 weeks ago   ENV PYTHON_VERSION=3.12.7                       0B        buildkit.dockerfile.v0
<missing>      2 weeks ago   ENV GPG_KEY=7169605F62C751356D054A26A821E680…   0B        buildkit.dockerfile.v0
<missing>      2 weeks ago   RUN /bin/sh -c set -eux;  apk add --no-cache…   999kB     buildkit.dockerfile.v0
<missing>      2 weeks ago   ENV LANG=C.UTF-8                                0B        buildkit.dockerfile.v0
<missing>      2 weeks ago   ENV PATH=/usr/local/bin:/usr/local/sbin:/usr…   0B        buildkit.dockerfile.v0
<missing>      5 weeks ago   /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>      5 weeks ago   /bin/sh -c #(nop) ADD file:5758b97d8301c84a2…   7.8MB

可以看到,pip 安装的这些包,总大小应该在 350MB 左右,加上 python-alpine 原来46MB 的大小,整好是在 396 MB

一次 pip 安装

创建 requirements.txt 文件,用于 pip 集中安装:

-i https://pypi.tuna.tsinghua.edu.cn/simple
pillow
django
jieba
nltk
colormap

修改 Dockerfile

FROM python:3.12.7-alpine3.20
COPY requirements.txt /root/
RUN pip install -r /root/requirements.txt

使用 docker build 打包镜像 temp:one。 可以看到,temp:one 的大注也是 396 MB。
使用 docerk history temp:one 查看:

IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
a802510b2faa   2 hours ago   RUN /bin/sh -c pip3 install -r /home/require…   349MB     buildkit.dockerfile.v0
<missing>      2 hours ago   COPY requirements.txt /home/ # buildkit         79B       buildkit.dockerfile.v0
<missing>      2 weeks ago   CMD ["python3"]                                 0B        buildkit.dockerfile.v0
<missing>      2 weeks ago   RUN /bin/sh -c set -eux;  for src in idle3 p…   36B       buildkit.dockerfile.v0
<missing>      2 weeks ago   RUN /bin/sh -c set -eux;   apk add --no-cach…   38.1MB    buildkit.dockerfile.v0
<missing>      2 weeks ago   ENV PYTHON_VERSION=3.12.7                       0B        buildkit.dockerfile.v0
<missing>      2 weeks ago   ENV GPG_KEY=7169605F62C751356D054A26A821E680…   0B        buildkit.dockerfile.v0
<missing>      2 weeks ago   RUN /bin/sh -c set -eux;  apk add --no-cache…   999kB     buildkit.dockerfile.v0
<missing>      2 weeks ago   ENV LANG=C.UTF-8                                0B        buildkit.dockerfile.v0
<missing>      2 weeks ago   ENV PATH=/usr/local/bin:/usr/local/sbin:/usr…   0B        buildkit.dockerfile.v0
<missing>      5 weeks ago   /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>      5 weeks ago   /bin/sh -c #(nop) ADD file:5758b97d8301c84a2…   7.8MB

可以看到,把所有 pip 安装一个 requirements 里安装,实际上并没有减小镜像包的尺寸

使用 pip --no-cache-dir 实际能减少大小

在一次性 pip 安装的基础上,给 Dockerfile 的 RUN pip 命令加上 --no-cache-dir 的参数

FROM python:3.12.7-alpine3.20
COPY requirements.txt /root/
RUN pip install -r /root/requirements.txt

添加这个参数之后,最后生成的镜像大小为 300MB。

实验二:添加一个文件,然后删除

再看这个 Dockerfile

FROM alpine
COPY bigfile /home
RUN rm -f /home/bigfile

这里,我们基于 alpine 镜像,先往里面拷贝了一个 6.4 MB 的大文件,然后又把它给删除了。相当于什么都没做。
最理想的结果,是打包出来的镜像(起名为 temp:add_remove),大小和 alpine 差不多,也应该是 7.8MB 左右的样子。
但实际结果不是这样。
通过 docker image ls temp:add_remove 可以看到,镜像大小为 14.4MB
而用 docker history temp:add_remove 看,结果如下:

IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
81de752d816c   55 minutes ago   RUN /bin/sh -c rm -f /home/bigfile # buildkit   0B        buildkit.dockerfile.v0
<missing>      56 minutes ago   COPY bigfile /home/ # buildkit                  6.62MB    buildkit.dockerfile.v0
<missing>      47 hours ago     RUN /bin/sh -c adduser -D dot # buildkit        3.03kB    buildkit.dockerfile.v0
<missing>      5 weeks ago      /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>      5 weeks ago      /bin/sh -c #(nop) ADD file:5758b97d8301c84a2…   7.8MB

可以看到,原来 COPY 的内容实际仍然在打包的镜像里面。为什么删除没有效果呢?

原因是 Docker 的 Union FS

Docker 使用 Union FS 来管理文件系统。
它允许将多个目录挂载到同一个挂载点上,这些目录在挂载点处表现为一个连贯的文件系统。
在 Docker 的上下文中,这意味着可以创建含多个只读层的堆叠,并在顶部添加一个可写层。
Union FS支持层叠多个目录,其中每个目录都可以被视为一个独立的层。
这允许 Docker 镜像由多个只读层组成,每个层代表一个 Dockerfile 指令的结果。

Docker 早期使用的是 AUFS,后来改为使用 overlay2。目前的 Linux 内核,决大多数都支持 oerverlay2。

Overlay2 的一个持点就是:写时复制(Copy-on-Write)
当容器尝试修改一个文件时,overlay2 会检查该文件是否存在于下面的只读层中。
如果是,overlay2 会在可写层创建该文件的副本并进行修改,保持原始只读层不变。

所以,每次 RUN 操作,实际上就是对原始记录加了一层。
如果两个动作如果没有重叠,就像用多个 pip install 不同的包,产生的多层和合在一个 pip 安装产生的一层的大小差不多。
但是,对于先添加,又删除,添加的那层文件始终是在的,只是之后又被删除动作在新的一层上标记为删除。

相当于一个本子上先写了一笔,然后又划掉了(而不是用橡皮擦掉),并不能使本子恢复空白。

最根本的原因,是 overlay2,除了最上层的读写层之外,底下的每一层都是只读的。

打个比方 – 就像钢笔写字,不能擦除

每一次 RUN 操作执行完成后,就生成一层。这层生成之后,就是只读的,不可修改的。
对于下一个操作,以前 RUN 的结果生成的各层,就象是一份份由钢笔书写的文件。
就算是我想修改以前的内容,也只能是做一个标记(就像用钢笔把以前某个文件上的某句话划掉),然后在最新的文件上加上要修改的内容。
总而言之,每新做一个操作,会添加一层。总体的镜像尺寸随着层数增多,是单调非减的。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com