个人亲自录制全套DevOps系列实战教程 :
手把手教你玩转DevOps全栈技术
我们将之前的案例,使用流水线构建一下
搭建一个Jenkinsfile模型
pipeline {
agent any
stages {
stage('拉取gitlab项目代码') {
steps {
echo "拉取git代码"
}
}
stage('构建代码') {
steps {
echo "通过maven构建代码"
}
}
stage('代码质量审计') {
steps {
echo "通过sonar进行代码质量审计"
}
}
stage('构建镜像/推送镜像') {
steps {
echo "构建docker镜像并推送私服"
}
}
stage('拉取镜像/发布容器') {
steps {
echo "宿主机拉取镜像并发布启动微服务容器"
}
}
}
}
创建pipeline job
1.gitlab脚本生成:
指定基于git参数为分支的构建配置,而此时如果我们选择构建,则会报错,因为还没有指定git仓库配置
此时,我们需要通过pipeline的阶段-步骤来完成git仓库的配置,我们选择语法生成工具,如下
注意:
配置完scm后,需要我们先构建一下,然后git参数才能正常显示,这里是jenkins的一个算是小bug吧,不运行一次他检测不到配置的scm仓库。
2.maven脚本生成:
接下来我们来生成maven的构建脚本
3.sonar脚本生成:
当然我们也可以将sonar的配置单独拎出去:而sonar是集成到jenkins中的,所以也是执行shell脚本,通过命令来运行,
此处我们借助sonar-scanner插件的pipeline脚本来执行,这样可以复用我们配置到jenkins中的sonar环境,如下:
withSonarQubeEnv(credentialsId: 'sonar-key') { // some block }
这里运行后有个报错,是因为生成器丢了一个参数,我们把他加上:
注意:因为sonar-scanner本身不支持覆盖率的生成而是借助jacoco生成报告,然后由scanner上报给sonar服务进行分析,即sonar不能生成报告而是只能分析,所以我们依然借助maven去生成覆盖率报告
// name是我们在系统配置中设置的name withSonarQubeEnv(installationName: 'sonar', credentialsId: 'sonar-key') { sh "$SCANNER_HOME/sonar-scanner -Dsonar.java.binaries=target -Dsonar.projectKey=$JOB_NAME" }
4.构建镜像/推送镜像到私服:
5.最后远程通知宿主机拉取镜像并部署容器:
最后我们稍微调整下变量的定制:sshPublisher(publishers: [sshPublisherDesc(configName: 'omv', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "sh /share/jenkins/demo/script/publish.sh $PUBLIC_REGISTRY $JOB_NAME $branch", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '$JOB_NAME', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'script/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
注意:最后我们可以把verbose参数设置成true,这样远程执行的日志就可以打印到jenkins了。
创建Jenkinsfile
pipeline {
agent any
tools {
// Install the Maven version configured as "M3" and add it to the path.
maven "maven3.8.6"
}
environment {
SCANNER_HOME = "${tool 'scanner4.7'}/bin"
// docker registry
PRIVATE_REGISTRY = '10.10.1.199:9082'
PUBLIC_REGISTRY = '10.10.1.199:9083'
USER = "admin"
PWD = "123456"
}
stages {
stage('拉取gitlab项目代码') {
steps {
// 检出代码
checkout([$class: 'GitSCM', branches: [[name: '$branch']], extensions: [], userRemoteConfigs: [[credentialsId: 'gitlab-ssh', url: 'ssh://git@10.10.1.199:2224/devops/helloworld.git']]])
}
}
stage('构建代码') {
steps {
// 执行shell脚本
sh 'mvn clean package verify'
}
}
stage('代码质量检测') {
steps {
// name是我们在系统配置中设置的name
withSonarQubeEnv(installationName: 'sonar', credentialsId: 'sonar-key') {
sh "$SCANNER_HOME/sonar-scanner -Dsonar.java.binaries=target -Dsonar.projectKey=$JOB_NAME"
}
}
}
stage('构建镜像/推送镜像') {
steps {
sh """set -e \\
&& mv target/*.jar docker/ \\
&& cd docker \\
&& docker build -t $JOB_NAME:$branch . \\
&& docker tag $JOB_NAME:$branch $PRIVATE_REGISTRY/$JOB_NAME:$branch \\
&& docker login -u $USER -p $PWD $PRIVATE_REGISTRY \\
&& docker push $PRIVATE_REGISTRY/$JOB_NAME:$branch \\
&& docker image prune -f"""
}
}
stage('拉取镜像/发布容器') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'omv', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "sh /share/jenkins/demo/script/publish.sh $PUBLIC_REGISTRY $JOB_NAME $branch", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '$JOB_NAME', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'script/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)])
}
}
}
}
提取共享库
如上我们有一些公共的变量,这些变量我们都可以定义到share liberary,方便其他流水线复用。
复用我们之前创建的jenkinslib项目,我们增加一个var/dockerVar.groovy
缺点:定义一个变量就需要@groovy.transform.Field注解,严重冗余,这时候我们可以通过src中定义类,将变量包装成属性即可,这个大家自己试一下就行了
// docker registry @groovy.transform.Field PRIVATE_REGISTRY = '10.10.1.199:9082' @groovy.transform.Field PUBLIC_REGISTRY = '10.10.1.199:9083' @groovy.transform.Field USER = "admin" @groovy.transform.Field PWD = "123456"
jenkinsfile做一下调整:同样创建在jenkinslib工程,目录:jenkinsfiles/docker.jenkinefile
只是拿环境变量来做一个演示
@Library('mylib@master') _ pipeline { agent any tools { // Install the Maven version configured as "M3" and add it to the path. maven "maven3.8.6" } environment { SCANNER_HOME = "${tool 'scanner4.7'}/bin" } stages { stage('拉取gitlab项目代码') { steps { // 检出代码 checkout([$class: 'GitSCM', branches: [[name: '$branch']], extensions: [], userRemoteConfigs: [[credentialsId: 'gitlab-ssh', url: 'ssh://git@10.10.1.199:2224/devops/helloworld.git']]]) } } stage('构建代码') { steps { // 执行shell脚本 sh 'mvn clean package verify' } } stage('代码质量检测') { steps { // name是我们在系统配置中设置的name withSonarQubeEnv(installationName: 'sonar', credentialsId: 'sonar-key') { sh "$SCANNER_HOME/sonar-scanner -Dsonar.java.binaries=target -Dsonar.projectKey=$JOB_NAME" } } } stage('构建镜像/推送镜像') { steps { sh """set -e \\ && mv target/*.jar docker/ \\ && cd docker \\ && docker build -t $JOB_NAME:$branch . \\ && docker tag $JOB_NAME:$branch $dockerVar.PRIVATE_REGISTRY/$JOB_NAME:$branch \\ && docker login -u $dockerVar.USER -p $dockerVar.PWD >$dockerVar.PRIVATE_REGISTRY \\ && docker push $dockerVar.PRIVATE_REGISTRY/$JOB_NAME:$branch \\ && docker image prune -f""" } } stage('拉取镜像/发布容器') { steps { sshPublisher(publishers: [sshPublisherDesc(configName: 'omv', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "sh /share/jenkins/demo/script/publish.sh $dockerVar.PUBLIC_REGISTRY $JOB_NAME $branch", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '$JOB_NAME', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'script/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)]) } } } }
我们新建一个jenkins job:pipeline-demo-sharelib,使用通过scm获取jenkinsfile文件,
注意:
我们这里将jenkinsfile名字前缀设置成了变量,这样我们可以随意使用其他前缀的文件,并且记住我们jenkinsfile中使用了git参数branch,不要漏掉
但我们不能通过当前工程的分支来作为参数了,因为当前工程拉取的是jenkinslib工程,而不是HelloWorld了,当然大家也可以做一下映射,我这里改成手动数据,简单演示一下