使用docker for CI / CD时节省空间的最佳做法是什么?

问题描述 投票:3回答:4

我正在使用CircleCI和docker进行CI / CD管道。 基本上,每次我将新代码推送到GitHub时,我都会将(python)应用程序和环境包装在一个新的docker镜像中。 然后我将图像推送到我用Nexus托管的私有Docker注册表,并通过从此注册表中提取最新图像并运行容器来部署我的应用程序。

我的问题是这些码头图像占用了大量的空间:

    REPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
my-app   0.1.23              6f13476770c2        3 minutes ago       1.99GB
my-app   0.1.22              7ff62dddb50a        10 minutes ago      1.99GB
my-app   0.1.21              55af2d3235c7        3 hours ago         1.99GB
my-app   0.1.20              304543b7fc71        5 hours ago         1.99GB
my-app   0.1.17              fddcef3f262b        2 weeks ago         1.99GB
my-app   0.1.16              a62c9ba1f997        2 weeks ago         1.99GB
my-app   0.1.12              a8d87d86699a        2 weeks ago         1.99GB

由于运行环境在图像中占用了大量空间并且不会频繁更改(不像更改代码那样频繁),我认为通过一遍又一遍地构建相同的依赖关系/环境来浪费大量空间。 所以问题是我是以正确的方式做到的吗? 如果不是最佳做法。 提前致谢!

PS我正在使用的环境需要一些需要GCC的依赖项(numpy,tensorflow等),因此如果我没有弄错的话,我无法使用python alpine图像。

我的Dockerfile:

FROM python:3.6-stretch
# Install app dependencies
RUN apt-get update && apt-get install -y \
    python3-dev \
    python3-pip

RUN mkdir /opt/working_dir/
WORKDIR /opt/working_dir/

# Copy the entire project into the current directory
COPY . ./
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

一些码头图像历史:

$ docker image history my-app:0.1.23
6f13476770c2        19 hours ago        /bin/sh -c pip install -r requirements.txt      955MB               
<missing>           19 hours ago        /bin/sh -c pip install --upgrade pip            4.97MB              
<missing>           19 hours ago        /bin/sh -c #(nop) COPY dir:5bb6533618d16964c…   16.5MB              
<missing>           19 hours ago        /bin/sh -c #(nop) WORKDIR /opt/reco_engine/     0B                  
<missing>           19 hours ago        /bin/sh -c mkdir /opt/reco_engine/              0B                  
<missing>           19 hours ago        /bin/sh -c apt-get update && apt-get install…   90.6MB              
<missing>           6 days ago          /bin/sh -c #(nop)  CMD ["python3"]              0B                  
<missing>           6 days ago          /bin/sh -c set -ex;   wget -O get-pip.py 'ht…   6.04MB              
<missing>           6 days ago          /bin/sh -c #(nop)  ENV PYTHON_PIP_VERSION=19…   0B                  
<missing>           6 days ago          /bin/sh -c cd /usr/local/bin  && ln -s idle3…   32B                 
<missing>           6 days ago          /bin/sh -c set -ex   && wget -O python.tar.x…   65.3MB              
<missing>           6 days ago          /bin/sh -c #(nop)  ENV PYTHON_VERSION=3.6.8     0B                  
<missing>           6 days ago          /bin/sh -c #(nop)  ENV GPG_KEY=0D96DF4D4110E…   0B                  
<missing>           6 days ago          /bin/sh -c apt-get update && apt-get install…   16.9MB              
<missing>           6 days ago          /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B                  
<missing>           6 days ago          /bin/sh -c #(nop)  ENV PATH=/usr/local/bin:/…   0B                  
<missing>           6 days ago          /bin/sh -c set -ex;  apt-get update;  apt-ge…   562MB               
<missing>           6 days ago          /bin/sh -c apt-get update && apt-get install…   142MB               
<missing>           6 days ago          /bin/sh -c set -ex;  if ! command -v gpg > /…   7.81MB              
<missing>           6 days ago          /bin/sh -c apt-get update && apt-get install…   23.2MB              
<missing>           6 days ago          /bin/sh -c #(nop)  CMD ["bash"]                 0B                  
<missing>           6 days ago          /bin/sh -c #(nop) ADD file:843b8a2a9df1a0730…   101MB 

$ docker image history my-app:0.1.22
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
7ff62dddb50a        19 hours ago        /bin/sh -c pip install -r requirements.txt      955MB               
<missing>           19 hours ago        /bin/sh -c pip install --upgrade pip            4.97MB              
<missing>           19 hours ago        /bin/sh -c #(nop) COPY dir:f054e43f5766a4738…   16.5MB              
<missing>           19 hours ago        /bin/sh -c #(nop) WORKDIR /opt/reco_engine/     0B                  
<missing>           19 hours ago        /bin/sh -c mkdir /opt/reco_engine/              0B                  
<missing>           19 hours ago        /bin/sh -c apt-get update && apt-get install…   90.6MB              
<missing>           6 days ago          /bin/sh -c #(nop)  CMD ["python3"]              0B                  
<missing>           6 days ago          /bin/sh -c set -ex;   wget -O get-pip.py 'ht…   6.04MB              
<missing>           6 days ago          /bin/sh -c #(nop)  ENV PYTHON_PIP_VERSION=19…   0B                  
<missing>           6 days ago          /bin/sh -c cd /usr/local/bin  && ln -s idle3…   32B                 
<missing>           6 days ago          /bin/sh -c set -ex   && wget -O python.tar.x…   65.3MB              
<missing>           6 days ago          /bin/sh -c #(nop)  ENV PYTHON_VERSION=3.6.8     0B                  
<missing>           6 days ago          /bin/sh -c #(nop)  ENV GPG_KEY=0D96DF4D4110E…   0B                  
<missing>           6 days ago          /bin/sh -c apt-get update && apt-get install…   16.9MB              
<missing>           6 days ago          /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B                  
<missing>           6 days ago          /bin/sh -c #(nop)  ENV PATH=/usr/local/bin:/…   0B                  
<missing>           6 days ago          /bin/sh -c set -ex;  apt-get update;  apt-ge…   562MB               
<missing>           6 days ago          /bin/sh -c apt-get update && apt-get install…   142MB               
<missing>           6 days ago          /bin/sh -c set -ex;  if ! command -v gpg > /…   7.81MB              
<missing>           6 days ago          /bin/sh -c apt-get update && apt-get install…   23.2MB              
<missing>           6 days ago          /bin/sh -c #(nop)  CMD ["bash"]                 0B                  
<missing>           6 days ago          /bin/sh -c #(nop) ADD file:843b8a2a9df1a0730…   101MB  
docker dockerfile circleci
4个回答
3
投票
  1. 找出你的应用程序的共同点。 这将成为您的应用程序部署的基准图像。
  2. 创建以公司命名的基准图像。 称之为app-base
  3. 每张图片都基于app-base。 它执行使用基础的构建步骤。 查找多阶段构建。
  4. 您的app-base图像绝对是您可以制作的小图像。 它不包括VM所做的事情。 你从一个小的基础图像开始,你工作,工作,工作,使它非常小。
  5. 提交和部署是微小的变化。 您的应用版本依赖于app-base 您的应用程序大小取决于您但不应提供开发工具。

我假设你运行python。 例如,您的图像为2GB。 Alpine Linux Python docker镜像为80MB。 您的应用可能会添加说法,另外100MB。 如果您有许多本机依赖项,​​那么可能很难将其分解或使用Alpine(比如说您需要GCC)。

如果一切都很幸运,您的应用程序基础映像将为80MB,您将部署的CI构建的应用程序映像将为100MB。 80MB将不会被反复使用,因为您的Nexus服务器将重用其中包含Python的app-base (来自Alpine Python或您自己的自定义)。 采用这种方法可能会为您节省大量空间(转化为速度)。

但这取决于您的应用程序及其遗产方式。

“最好”的做法(没有这样的东西,但这里有一些提示):

  • 如果可以的话,使用alpine linux映像作为基线。 与GCC deps进行权衡。
  • 为您的公司制作自己的小图像,并根据需要进行自定义。
  • 添加尽可能少。 如果你需要编译一些东西,可以在一个阶段添加编译工具,不要发送它。 你不需要它。
  • 换句话说,使用多阶段构建
  • 如果可以的话,瞄准小二进制文件。 你能编译成二进制吗? 巨额储蓄。
  • 尽量不要像虚拟机那样接近它。 即:不要安装ssh。

2
投票

大多数python Dockerfile示例都将requirements.txt文件与其余的python代码分开处理,如:

FROM python:3.6-stretch
# Install app dependencies
RUN apt-get update && apt-get install -y \
    python3-dev \
    python3-pip

RUN mkdir /opt/working_dir/
WORKDIR /opt/working_dir/

# Copy the entire project into the current directory
RUN pip install --upgrade pip
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . ./

通过这样做,您的构建将更快,并重用除最后一层之外的所有构建,除非requirements.txt文件得到更新。 您仍会在image ls输出中看到大图像,但如果您检查图层,您会发现几乎所有图像之间的图像都是相同的。


1
投票

有许多方法可以优化图像。 如果你发布你的Dockerfile,我可以给你提示。

您还可以检查图像的历史记录:

docker image history my-app:0.1.23

这会告诉您每个命令在其构建的特定层中添加了多少空间。

您还可以检查图像并查看共用的层数:

docker inspect my-app:0.1.23

0
投票

docker_layer_caching添加到配置文件中:

jobs:
 jobName:
   machine:
     enabled: true
     docker_layer_caching: true

在此之后,所有旧图层都缓存在CircleCI上。

© www.soinside.com 2019 - 2024. All rights reserved.