赞
踩

作者 | Andy
来源 | 进击云原生
最近,有一个需求:向镜像构建管道添加一个参数,以允许用户在构建时配置超时时间。
我们计划在构建时配置 10 分钟的默认超时,并且允许用户覆盖此配置,因为他们的某些镜像构建需要长达 60 分钟才能完成。而且每天都在进行多次构建。
为了便于阅读,我删除了一些内容,Dockerfile 看起来像这样:
- FROM ubuntu:focal-20210119
- RUN apt-get -y update && \
- apt-get -y upgrade && \
- apt-get install -y --no-install-recommends \
- dos2unix \
- jq \
- libpython3.10 \
- python3-pip \
- software-properties-common \
- tar \
- unzip \
- wget \
- zip && \
- echo "Cleaning up" && \
- rm -rf /var/lib/apt/lists/* && \
- apt-get clean
- RUN pip3 install boto3 flask
- RUN echo "Installing AWS CLIv2" && \
- TMPDIR=$(mktemp -d) && \
- wget -P $TMPDIR --no-check-certificate "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" && \
- unzip $TMPDIR/awscli-exe-linux-x86_64.zip -d $TMPDIR && \
- $TMPDIR/aws/install && \
- rm -rf /usr/local/aws-cli/v2/dist/awscli/examples/ && \
- rm -rf $TMPDIR
- RUN echo "Installing kubectl" && \
- wget -P /usr/bin/ --no-check-certificate https://storage.googleapis.com/kubernetes-release/release/$(wget --no-check-certificate -O - https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \
- chmod +x /usr/bin/kubectl
- # Install the app
- COPY dummyapp.py /app/

rebuild 的重点是应用程序更改,而不是对底层依赖项的更改。
由于 Dockerfile 已被精简,现在大约 5 分钟内构建完成。但讲真,这时间仍然很长,因为通常可能只要几秒钟。
这是我构建的部分输出:
- # time docker build --no-cache --progress=plain -t test:test .
- Sending build context to Docker daemon 3.072kB
- Step 1/5 : FROM ubuntu:focal-20210119
- ---> f63181f19b2f
- Step 2/5 : RUN apt-get -y update && apt-get -y upgrade && apt-get install -y --no-install-recommends dos2unix jq libpython3.10 python3-pip software-properties-common tar unzip wget zip && echo "Cleaning up" && rm -rf /var/lib/apt/lists/* && apt-get clean
- ---> Running in 37bff266446e
- Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
- Get:2 http://security.ubuntu.com/ubuntu focal-security/main amd64 Packages [1470 kB]
- <snip>
- 45400K .......... .......... .......... .......... .......... 99% 2.31M 0s
- 45450K .......... .......... .......... .......... ...... 100% 8.05M=18s
- 2022-01-28 19:37:06 (2.40 MB/s) - '/usr/bin/kubectl' saved [46587904/46587904]
- Removing intermediate container 86223b438cef
- ---> b8f9a2cc1d9a
- Step 6/6 : COPY dummyapp.py /app/
- ---> b95d22cdca6f
- Successfully built b95d22cdca6f
- Successfully tagged test:test
- real 5m11.679s
- user 0m1.248s
- sys 0m1.961s

怎样才能让这个构建更快?
每次构建这个 Dockerfile 时,都会重复很多处理,其结果不太可能经常改变。
更新 ubuntu 软件包列表
升级 ubuntu 软件包
安装一些额外的软件包
使用 pip3 安装一些 python 包
安装 AWS CLI
安装 kubectl
安装应用程序
还 FROM 一个相当旧的 Ubuntu 版本,需要升级更多的包,因此升级步骤将花费更长的时间。
此镜像的大多数重新 build 的目的是合并应用程序更改(即仅 Dockerfile 中的最后一行)。因此,最明显的变化是将此 Dockerfile 拆分为 2 个(或更多)Dockerfile,并且将 FROM 语句更改为使用最新的 Ubuntu 基础镜像。
第一个 Dockerfile 看起来像这样:
- FROM ubuntu:latest
- RUN apt-get -y update && \
- apt-get -y upgrade && \
- apt-get install -y --no-install-recommends \
- dos2unix \
- jq \
- libpython3.10 \
- python3-pip \
- software-properties-common \
- tar \
- unzip \
- wget \
- zip && \
- echo "Cleaning up" && \
- rm -rf /var/lib/apt/lists/* && \
- apt-get clean
- RUN pip3 install boto3 flask
- RUN echo "Installing AWS CLIv2" && \
- TMPDIR=$(mktemp -d) && \
- wget -P $TMPDIR --no-check-certificate "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" && \
- unzip $TMPDIR/awscli-exe-linux-x86_64.zip -d $TMPDIR && \
- $TMPDIR/aws/install && \
- rm -rf /usr/local/aws-cli/v2/dist/awscli/examples/ && \
- rm -rf $TMPDIR
- RUN echo "Installing kubectl" && \
- wget -P /usr/bin/ --no-check-certificate https://storage.googleapis.com/kubernetes-release/release/$(wget --no-check-certificate -O - https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \
- chmod +x /usr/bin/kubectl

第二个 Dockerfile 可能看起来像这样:
- FROM dummyapp-dependencies:latest
- # Install the app
- COPY dummyapp.py /app/
构建第一个 Dockerfile 并没有为我们节省任何时间,虽然需要大约 5 分钟,但只需要相对不频繁地构建第一个 Dockerfile。
然而,构建第二个 Dockerfile 的效果要好得多,只需要大约 2 秒:
- # time docker build --no-cache --progress=plain -t tes
- t:test -f Dockerfile.app .
- Sending build context to Docker daemon 5.12kB
- Step 1/2 : FROM dummyapp:1.0.0
- pull access denied for dummyapp, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
- real 0m2.125s
- user 0m0.043s
- sys 0m0.030s
鉴于应用程序的更改比底层依赖项更频繁,刚刚节省了大量时间。

往期推荐
如何跨 Namespace 同步 Secret 和 ConfigMap?

点分享

点收藏

点点赞

点在看
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。