go Jenkins流水线极速打包镜像上传

在使用Jenkins流水线进行打包时,发现直接使用Dockerfile去构建一个java或者go程序会非常慢,go好一点也要一分钟,java则需要3分钟以上。Java&Gradle极速打包设置见:这里

dockerfile如下:

FROM golang:1.18.1 AS builder
ENV GO111MODULE=on \
    CGO_ENABLED=0 \
    GOOS=linux \
    GOARCH=amd64 \
	GOPROXY="https://goproxy.cn,direct"
WORKDIR /opt/test/
COPY . .
RUN go build -o test .

FROM alpine:latest
MAINTAINER Hao.Wu
WORKDIR /opt/
COPY --from=builder /opt/test/ .
RUN chmod +x test
EXPOSE 50001
CMD ["./test"]

在上述步骤中,第一步是打一个go的可执行文件,然后再构建一个linux环境。在linux环境中复制执行go环境中打好的包。在打包时发现还是有些慢。有时甚至超过了3分钟。

怎么样提升速度呢?

在上述构建中,最慢的步骤是go的打包,如果选择选用服务器安装go进行打包,再将打好的可执行文件直接构建成docker镜像,一定会快很多。

那就开始做吧,原先在Jenkinsfile中,只需要build镜像一步就够了。现在需要先clone代码,然后go打包,最后将打好的包打入镜像。

费了九牛二虎之力,终于,我做到了。

node  {
    def appimage
    def registry = ''
    def registryCredential = 'aliyun-docker-image-repository'
    def path
		def root = tool type: 'go', name: 'go-1.18.6'
  	
    stage("Checkout"){
        checkout([$class: 'GitSCM', 
            branches: [[name: '*/'+env.BRANCH_NAME]], 
            extensions: [[$class: 'SubmoduleOption', disableSubmodules: false, parentCredentials: false, recursiveSubmodules: true, reference: '', trackingSubmodules: false]], 
            userRemoteConfigs: [[credentialsId: '', url: '']]])
    }
  	// 拉代码 
    stage('Source') {
          git branch: env.BRANCH_NAME, credentialsId: '', url: ''
    }
  	// 打包
  	withEnv(["GOROOT=${root}", "PATH+GO=${root}/bin"]) {
            // Output will be something like "go version go1.19 darwin/arm64"
            sh 'go env -w  GOPROXY=https://goproxy.io,direct'
            sh 'go build -o "test"'
    }
		// 构建镜像
    stage('Build') {
        appimage = docker.build registry + ":" + env.BRANCH_NAME + "-$BUILD_NUMBER"
    }
   
    stage('Publish') {
        
    }

    stage('Deploy') {
        
    }
}

修改之后,就不再需要使用Dockerfile中的go环境了

FROM ubuntu:18.04
# 直接从本地复制
COPY simba-ranking /opt
WORKDIR /opt
RUN chmod +x simba-ranking
ENTRYPOINT ["/opt/simba-ranking"]

在这次尝试中,我遇到了几个问题:

  1. 找不到go环境
  2. 下载太慢
  3. 权限不够

这些问题是使用Jenkinsfile常见的问题,其中:

  • go环境需要在jenkins中安装好(见Jenkins系统配置),然后在Jenkinsfile中进行声明:
def root = tool type: 'go', name: 'go-1.18.6'

需要注意的是,以上的“go-1.18.6”是在Jenkins中进行安装时,起的名字,指向的是具体的插件,而不是这里填什么Jenkins下载什么。

  • 下载太慢,当你配置了Jenkins所在物理机的go环境,并在Jenkins的系统中指向该go,却发现打包速度极慢,还经常有IO异常时,应该就是这个问题了。这个go环境并不会从你物理机中读取环境变量。需要单独设置,如上的
 sh 'go env -w  GOPROXY=https://goproxy.io,direct'

就是设置了go的环境变量。

  • 另外权限不够的问题,我在上面的Jenkinsfile中也有解决,dockerfile中给可执行文件赋予权限即可:RUN chmod +x simba-ranking

经过这些改造,一般可以将go的构建缩短至20s以内。由于go本身打包机制良好,当依赖文件不多时,构建速度的优化可能并不明显,这时候我建议使用一体的Dockerfile直接构建,可以减少一些维护成本。


版权声明:本文为w_monster原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。