最近研究了一下gin-vue-admin框架,其中官方自带docker镜像打包。我们在jenkins流水线将后端服务打包镜像上次到K8s 平台中,发现每次打包docker镜像构建时间需要花费1分半左右。这样打包构建速度非常耽误工作。jenkins流水线打包时间如下图:
从以上图可以看出**生成镜像**最浪费时间。我们在分析一下这个步骤到底花费了哪些时间
镜像开始打包,接下来有一段下载第三方依赖包
下载完成后发现花费了 42.2秒,好家伙大概镜像构建 一半以上的时间都浪费在下载第三方GO的依赖包。我们检查一下它dockerfile看看里面到底干了哪些事情。
FROM golang:alpine as builder
WORKDIR /go/src/ahzz/gin-vue-admin
COPY . .
WORKDIR /go/src/ahzz/gin-vue-admin/server
RUN ls
RUN pwd
RUN go env -w GO111MODULE=on \
&& go env -w GOPROXY=https://goproxy.cn,direct \
&& go env -w CGO_ENABLED=0 \
&& go env \
&& go mod tidy \
&& go build -gcflags "all=-N -l" -o server .
FROM alpine:latest
LABEL MAINTAINER="wwwzhouhui"
WORKDIR /go/src/ahzz/gin-vue-admin
COPY --from=0 /go/src/ahzz/gin-vue-admin/server ./
COPY --from=0 /go/src/ahzz/gin-vue-admin/server/resource ./resource/
COPY --from=0 /go/src/ahzz/gin-vue-admin/server/config.yaml ./
COPY --from=0 /go/src/ahzz/gin-vue-admin/server/dongtai-go-agent-config.yaml ./
EXPOSE 8080
ENTRYPOINT ./server
我们从上面dockerfile里面可以看出,镜像采用了分层打包模式,第一步在镜像里面 使用go mod tidy 镜像build.第二步在
alpine镜像中复制打包好的二进制文件和需要运行配置文件。我们知道第二步文件的复制+设置启动端口这个不需要花费多少时间,那么时间应该是消费在go build 中。我们知道go mod tidy 第一次运行的时候需要从远程服务器上面下载第三依赖的GO语言包。第二次运行go mod tidy 本地电脑或者服务器有第三方依赖包了,程序打包二进制文件这时间是非常短的。问题就在docker build 的时候每次单独的镜像都需要go mod tidy 需要下载第三方依赖包,而我们刚才分析了每次下载时间都消耗在40秒中。目前公司的项目都是基于docker镜像打包,依赖jenkins流水线打包,而且每天几百次构建,每次构建都浪费40秒中一年下来 在打包上耽误的时间是惊人 的。所以接下来我们需要改造打包模式,看看能不能提高打包镜像的效率。
公司现有环境思考:
3台jenkins 集群环境
13台rancher 集群环境(开发环境)
我们知道既然go mod tidy 第一次需要下载第三方依赖GO语言的包,那么我们可不可以把go build 放在jenkins中打包,打包好后的二进制文件 在复制到docker镜像中作为制品,这样就省下了每次go mod tidy 的时间了。思路是对的接下来我们就按照想法来改造dockerfile 和Jenkinsfile 文件。
第一步 三台jenkins 服务器上安装 go 运行环境(这个比较简单这里面就不做介绍了)
我们运行 go env
以上确保go 环境是OK的。
第二步:修改Jenkinsfile 代码。这里面我们需要在 编译程序增加相应的修改
tage('编译程序') {
when {
expression { deploy == true || deploy == 'true' }
}
steps {
script {
def projectName = "${projectName}"
echo "项目容器名称:${projectName}"
//docker等相关配置文件拷贝到target下
copyConfigToTarget(projectName)
// 复制go 代码到target/settings 目录下
sh "cp -rf ${WORKSPACE}/server/ ${WORKSPACE}/target/settings/server/ "
sh """
cd ${WORKSPACE}/target/settings/server/
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn
go env -w CGO_ENABLED=0
go env
go mod tidy
go build -gcflags "all=-N -l" -o server .
cp ${WORKSPACE}/target/settings/Dockerfile ${WORKSPACE}/target/settings/server
"""
echo " go build 完成"
}
}
}
简单解释一下,上面主要作用就是把之前dockerfile 第一步放到Jenkins流水线stage 步骤中了。
下一步 镜像打包上传,Jenkins流水线 代码如下:
stage('镜像打包上传') {
when {
expression { deploy == true || deploy == 'true' }
}
steps {
script {
def projectName = "${projectName}"
echo "项目容器名称:${projectName}"
//镜像名称
imageName = "${harborUrl}/${harborUserName}/${projectNameAs}/${imageVersion}/${projectEnv}:${imageVersion}_${env.BUILD_TIMESTAMP}.${env.BUILD_NUMBER}"
//构建镜像
//sh "export DOCKER_BUILDKIT=0 "
sh "sudo DOCKER_BUILDKIT=0 docker build --build-arg projectName=${projectName} -t ${imageName} ${WORKSPACE}/target/settings/server "
//harbor登录
sh "sudo docker login --username=${harborUserName} --password=${harborPwd} ${harborUrl}"
//推送镜像
sh "sudo docker push ${imageName}"
}
}
}
第三步 dockerfile 文件修改
FROM alpine:latest
LABEL MAINTAINER="wwwzhouhui"
WORKDIR /home/ahzz
COPY ./server ./
COPY ./resource/ ./resource
COPY ./config.yaml ./config.yaml
COPY ./dongtai-go-agent-config.yaml ./dongtai-go-agent-config.yaml
RUN chmod +x /home/ahzz/config.yaml ;\
chmod +x /home/ahzz/dongtai-go-agent-config.yaml ;\
chmod +x /home/ahzz/server ;
EXPOSE 8080
ENTRYPOINT ./server
从以上dockerfile 它实际上就干了一件事就是复制server 二进制文件和resource 以及 配置文件config.yaml、dongtai-go-agent-config.yaml到镜像里面,并赋予docker 权限。
以上步骤就完成 流水线代码+dockerfile 文件的修改。
我们对比一下2个构建时间消耗
大家有没有发现 从1分14秒一下缩短到15秒中。缩短的时间差不多就是 go 第三方依赖包的下载。
我们对比了一下前后 构建时间 效率整整提升了 (16+74)/(12+15+5+1)=2.7倍。一次构建提升了2.7 多个项目多次构建一年下来这个时间是惊人的。
本文暂时没有评论,来添加一个吧(●'◡'●)