专业编程基础技术教程

网站首页 > 基础教程 正文

BuildKit一个下一代docker编译打包工具,打包实战

ccvgpt 2024-07-19 12:53:34 基础教程 8 ℃

Docker v18.09上引入的一组增强功能,它的名字叫做BuildKit,它可以减少构建时间,缩小镜像尺寸等特性,下面我们重点介绍一下测试一下它是如何加快镜像构建的。

  1. 首先需要docker升级到较新的版本,具体可以参考

1.1查看本地是否有docker,以及docker版本

BuildKit一个下一代docker编译打包工具,打包实战


1.2 删除旧版本的docker

          yum remove docker docker-common docker-client docker-compose

1.3 安装最新版docker

  curl -fsSL https://get.docker.com/ | sh


1.4 验证docker版本



我们首先在服务器上分别上传编写好的Dockerfile和helloworld-0.0.1-SNAPSHOT.jar上传带有docker最新版本的linux服务器

我们查看一下Dockerfile内容

# Use the Official OpenJDK image for a lean production stage of our multi-stage build.
# https://hub.docker.com/_/openjdk
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM docker.io/anapsix/alpine-java
# Copy the jar to the production image from the builder stage.
COPY /helloworld-*.jar /helloworld.jar
# Run the web service on container startup.
CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/helloworld.jar"]

以上的dockerfille 很好理解 加载alpine-java带有java运行环境的基础镜像,复制helloworld.jar到容器内,设置运行环境。

下面我们重点介绍一下测试

2.1 使用普通的 docker bulid 编译镜像,命令行如下

time docker build --no-cache -t=yf.registry.965432.com/sjjcb/helloworld-java-spring:helloworld001 .

我们知道如果docker build之前如果有依赖的基础镜像会从缓存中直接获取,这样对比就看不出来BuildKit优势,我们这里面统一设置--no-cache,执行结果如下:

可以看到打包执行时间 3.036秒,这个东西前面我们docker.io/anapsix/alpine-java 镜像是已经有的,所以执行3秒,这个我们是可以接受的。

2.2 使用BuildKit docker bulid 编译镜像,命令行如下:

time DOCKER_BUILDKIT=1 docker build --no-cache -t=yf.registry.965432.com/sjjcb/helloworld-java-spring:helloworld001 .

在执行以上命名前,我们启用 BuildKit 必须先设置 环境变量(由于是同一台机器,我只能临时设置这个值)

export DOCKER_BUILDKIT=1

下面执行 DOCKER_BUILDKIT=1 docker build 情况:

从以上执行我们可以看到 执行时间在1.749秒,比上面提升了50%,就是使用了DOCKER_BUILDKIT=1 这个属性,其他都没有变化。

3.启用 BuildKit 之后,RUN 新增了新的指令,这些指令也可以加快我们编译打包速度。下面我们挑选几个指令介绍

  • RUN --mount=type=cache
    RUN --mount=type=bind
    RUN --mount=type=tmpfs
    RUN --mount=type=secret
    RUN --mount=type=ssh

目前,几乎所有的程序都会使用依赖管理工具,例如 Go 中的 go mod、Node.js 中的 npm 等等,当我们构建一个镜像时,往往会重复地从互联网中获取依赖包,难以缓存,大大降低了镜像的构建效率。

我们以前后端分离项目前端项目打包为例重点介绍一下RUN --mount=type=cache,dockerfile文件如下

FROM node:alpine as builder
WORKDIR /app
COPY package.json /app/
RUN npm i --registry=https://registry.npm.taobao.org \
&& rm -rf ~/.npm
COPY src /app/src
#RUN npm run build
#FROM nginx:alpine
#COPY --from=builder /app/dist /app/dist

3.1 我们通过普通 docker bulid 编译镜像,命令行如下

time docker build --no-cache -t=yf.registry.965432.com/sjjcb/node:node001 .

我们修改dockerfile 增加RUN --mount=type=cache 对比

FROM node:alpine as builder
WORKDIR /app
COPY package.json /app/
RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
--mount=type=cache,target=/root/.npm,id=npm_cache \
npm i --registry=https://registry.npm.taobao.org
COPY src /app/src
#RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
# --mount=type=cache,target=/app/dist,id=my_app_dist,sharing=locked \
# npm run build
#FROM nginx:alpine
# COPY --from=builder /app/dist /app/dist
# 为了更直观的说明 from 和 source 指令,这里使用 RUN 指令
#RUN --mount=type=cache,target=/tmp/dist,from=builder,source=/app/dist \
# --mount=type=cache,target/tmp/dist,from=my_app_dist,sharing=locked \
# mkdir -p /app/dist && cp -r /tmp/dist/* /app/dist

第一个 RUN 指令执行后,id 为 my_app_npm_module 的缓存文件夹挂载到了 /app/node_modules 文件夹中。多次执行也不会产生多个中间层镜像。

执行后0.788秒

呵呵是不是比较快啊,详细资料可以参考

https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md

Tags:

最近发表
标签列表