将docker用于CI / CD时,节省空间的最佳实践是什么?

时间:2019-04-01 21:08:44

标签: docker dockerfile circleci

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

我的问题是这些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

由于运行环境在映像中占用大量空间,并且不会频繁更改(不像更改代码那样频繁),因此我假设通过一遍又一遍地构建相同的依赖项/环境来浪费大量空间。所以问题是我做对了吗?如果不是,最好的做法是什么。预先感谢!

P.S。我使用的环境需要一些依赖项(numpy,tensorflow等),这些依赖项需要GCC,因此,如果我没有记错的话,我将无法使用python高山图像。

我的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映像历史记录:

$ 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  

4 个答案:

答案 0 :(得分:3)

  1. 弄清楚您的应用程序的共同点。这将成为您部署应用程序的基准映像。
  2. 创建以您的公司命名的基准图像。称为app-base
  3. 每个图像都基于应用程序库。它执行使用基础的构建步骤。查找多阶段构建。
  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或您自己的自定义项)。采用这种方法可能会节省大量空间(转化为速度)。

但这取决于您的应用程序以及它的历史悠久程度。

“最佳”做法(没有这种做法,但是这里有一些技巧):

  • 如果可以,请使用高山linux映像作为基准。与GCC部门进行权衡。
  • 为公司制作自己的微型图像,并根据需要进行自定义。
  • 添加尽可能少的内容。如果您需要编译某些内容,请分阶段添加编译工具,并且不要附带该工具。您不需要它。
  • 换句话说,使用多阶段构建
  • 如果可以的话,请针对小型二进制文件。你可以编译成二进制文件吗?节省很多。
  • 尽量不要像VM那样处理它。即:不要安装ssh。

答案 1 :(得分:2)

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

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 . ./

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

答案 2 :(得分:1)

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

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

docker image history my-app:0.1.23

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

您还可以检查图像并查看共有多少层:

docker inspect my-app:0.1.23

答案 3 :(得分:0)

docker_layer_caching添加到您的配置文件中:

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

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