您现在的位置是:首页 >技术杂谈 >golang微服务项目通用流水线网站首页技术杂谈

golang微服务项目通用流水线

帅大大的架构之路 2023-06-15 20:00:02
简介golang微服务项目通用流水线

golang微服务项目通用流水线

工作中随着业务越来越大,微服务的项目也越来越多,最开始的时候是一个服务一个流水线,然后还分了三个环境,也就是一个服务三个流水线,后面就越来越不利于管理维护了,因此,进行了一个改造整合

golang这边的微服务基本分成三类,service、schedule、mq,所以将所有流水线整合为三条通用流水线,再通过参数传递的形式,去构建每个服务

一、dockerfile和jenkinsfile

这是service里面的dockerfile和jenkinsfile,schedule、mq大同小异

dockerfile

FROM ccr.ccs.tencentyun.com/chens/golang:1.17.13
ENV ZBE_PATH /biz-code
ARG SERVICENAME=message
COPY $SERVICENAME /biz-code/$SERVICENAME
WORKDIR /biz-code
RUN chmod 777 $(echo `ls -l` |awk -F ' ' '{print $NF}')
USER root
RUN ls -l
CMD ./$(echo `ls -l` |awk -F ' ' '{print $NF}')

jenkinsfile

pipeline {
  agent {
    kubernetes {cloud 'kubernetes'
      cloud 'kubernetes-test'
      slaveConnectTimeout 1200
      workspaceVolume hostPathWorkspaceVolume(hostPath:"/opt/workspace", readOnly: false)
      yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
    - args: ['$(JENKINS_SECRET)', '$(JENKINS_NAME)']
      image: 'jenkins/jnlp-slave:latest-jdk11'
      name: jnlp
      imagePullPolicy: IfNotPresent
      volumeMounts:
        - mountPath: "/etc/localtime"
          name: "localtime"
          readOnly: false 
    - command:
        - "cat"
      env:
        - name: "LANGUAGE"
          value: "en_US:en"
        - name: "LC_ALL"
          value: "en_US.UTF-8"
        - name: "LANG"
          value: "en_US.UTF-8"
      image: "ccr.ccs.tencentyun.com/chens/golang:1.17.13"
      imagePullPolicy: "IfNotPresent"
      name: "build"
      tty: true
      volumeMounts:
        - mountPath: "/etc/localtime"
          name: "localtime"
        - mountPath: "/go/pkg/"
          name: "cachedir"
          readOnly: false
    - command:
        - "cat"
      env:
        - name: "LANGUAGE"
          value: "en_US:en"
        - name: "LC_ALL"
          value: "en_US.UTF-8"
        - name: "LANG"
          value: "en_US.UTF-8"
      image: "registry.cn-beijing.aliyuncs.com/citools/kubectl:self-1.17"
      imagePullPolicy: "IfNotPresent"
      name: "kubectl"
      tty: true
      volumeMounts:
        - mountPath: "/etc/localtime"
          name: "localtime"
          readOnly: false
    - command:
        - "cat"
      env:
        - name: "LANGUAGE"
          value: "en_US:en"
        - name: "LC_ALL"
          value: "en_US.UTF-8"
        - name: "LANG"
          value: "en_US.UTF-8"
      image: "registry.cn-beijing.aliyuncs.com/citools/docker:19.03.9-git"
      imagePullPolicy: "IfNotPresent"
      name: "docker"
      tty: true
      volumeMounts:
        - mountPath: "/etc/localtime"
          name: "localtime"
          readOnly: false
        - mountPath: "/var/run/docker.sock"
          name: "dockersock"
          readOnly: false
  restartPolicy: "Never"
  imagePullSecrets:
  - name: qcloudregistrykey
  nodeSelector:
    build: "true"
  securityContext: {}
  volumes:
    - hostPath:
        path: "/var/run/docker.sock"
      name: "dockersock"
    - hostPath:
        path: "/usr/share/zoneinfo/Asia/Shanghai"
      name: "localtime"
    - name: "cachedir"
      hostPath:
        path: "/opt/gopkg"
    - name: "phpdir"
      hostPath:
        path: "/opt/phppkg"
'''
   }
}
stages {
  stage('Pulling Code') {
	parallel {
	  stage('Pulling Code by Jenkins') {
		when {
		  expression {
			env.giteeBranch == null
		  }
		}
		steps {
		  git(changelog: true, poll: true, url:'https://gitee.com/chens-go/kobe.git', branch:"${BRANCH}", credentialsId: 'gitee-mima')
   		  script {
   		    COMMIT_ID = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
   		    TAG = BUILD_TAG + '-' + COMMIT_ID
   		    println "Current branch is ${BRANCH}, Commit ID is ${COMMIT_ID}, Image TAG is ${TAG}"

		  }
		}
     }
	  stage('Pulling Code by trigger') {
		when {
		  expression {
			env.giteeBranch != null
		  }
		}
		steps {
		  git(url: 'https://gitee.com/chens-go/kobe.git', branch: env.giteeBranch, changelog: true, poll: true, credentialsId: 'gitee-mima')
		  script {
			COMMIT_ID = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
			TAG = BUILD_TAG + '-' + COMMIT_ID
			println "Current branch is ${env.giteeBranch}, Commit ID is ${COMMIT_ID}, Image TAG is ${TAG}"
		  }
		}
	}
  }
}
	  stage('Building') {
		steps {
		  container(name: 'build') {
			sh """ 
                go env -w GO111MODULE=on
                go env -w GOPROXY=https://goproxy.io,direct
                go env -w GOPRIVATE=gitee.com/chens-go/jordan
                export GIT_TERMINAL_PROMPT=1
                go build -o ${SERVICENAME} services/${SERVICENAME}/${SERVICENAME}-service/cmd/${SERVICENAME}/main.go
                chmod +x ${SERVICENAME}
                cp -p ${SERVICENAME} build-work/k8s2/service
			"""
		  }
		}
	  }
	  stage('Docker build for creating image') {
		environment {
		  HARBOR_USER = credentials('registry-secret')
		}
		steps {
		  container(name: 'docker') {
			sh """
              cd build-work/k8s2/service
			  echo ${HARBOR_USER_USR} ${HARBOR_USER_PSW} ${TAG}
              docker login -u ${HARBOR_USER_USR} -p ${HARBOR_USER_PSW} ${HARBOR_ADDRESS}
			  docker build -t ${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG} --build-arg SERVICENAME=${SERVICENAME} .
			  docker push ${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG}
			"""
		  }
		}
	  }
	  stage('Deploying to K8s') {
		environment {
		  MY_KUBECONFIG = credentials('k8s-config')
		}
		steps {
		  container(name: 'kubectl'){
			sh """
			  /usr/local/bin/kubectl --kubeconfig $MY_KUBECONFIG set image deploy -l app=${KOBE_NAME} ${KOBE_NAME}=${HARBOR_ADDRESS}/${REGISTRY_DIR}/${IMAGE_NAME}:${TAG} -n $NAMESPACE
			"""
		  }
		}
	  }
	}
  environment {
    COMMIT_ID = ""
    HARBOR_ADDRESS = "ccr.ccs.tencentyun.com"
    REGISTRY_DIR = "chens"
    IMAGE_NAME = "kobe"
    NAMESPACE = "${ENV}"
    TAG = ""
    KOBE_NAME = "${SERVICENAME}"
}
  parameters {
	gitParameter(branch: '', branchFilter: 'origin/(.*)', defaultValue: "${BRANCH}", description: 'Branch for build and deploy', name:'BRANCH', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH')
  }
}

二、参数传递

流水线里面需要传递三个参数

在这里插入图片描述

具体配置

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

最后的这个build-work/k8s2/service/Jenkinsfile,是jenkinsfile在项目代码中的路径

所有参数名称和路径皆可根据自己项目来定义

三、写在最后

这里面有些语法看着很离谱,其实是我在做的过程中踩的一些坑,你们可以试试不那样写会发生什么,当然也有可能还有别的解决方法,可多尝试

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。