03-kubesphere流水线搭建

前言

及时清醒,事事甘心

9.流水线

参考:https://gitee.com/tanqidi/gulimall

9.1第一步gitee拉取代码

官方demo地址:https://github.com/kubesphere/devops-java-sample/blob/master/Jenkinsfile-online

image-20240930000947446

选择peng-mall-devops,创建流水线

image-20240930001239601

这里默认无需修改,点击创建

image-20240930001335750

选择新建的流水线peng-mall-cicd,选择编辑流水线

image-20240930001529323

选择自定义流水线

image-20240930001613873

选择node,选择maven

image-20240930001657621

添加步骤

image-20240930002300044

新建码云凭证,我已经创建过了,自己输入自己的账号即可

image-20240930002405006

添加步骤完成

image-20240930002500415

选择编辑Jenkinsfile,查看代码

pipeline {
  agent {
    node {
      label 'maven'
    }

  }
  stages {
    stage('拉取代码') {
      agent none
      steps {
         dir('code/peng-mall-parent') { 
             git(url: 'https://gitee.com/xxxxx/peng-mall.git', credentialsId: 'gitee-id', branch: 'master', changelog: true, poll: false)
        }
      }
    }
  }
}

image-20240930003414308

我这里因为项目代码有几层其他的目录,所以加了dir('code/peng-mall-parent'){}命令,代表拉取code/peng-mall-parent目录下的代码,没有别的目录层级的话删除即可

image-20240930003526009

选择活动,选择运行,我这里已经运行成功了

image-20240930003818398

点击运行记录进去,可以查看日志

image-20240930003931092

image-202409300054398479.2第一步-参数化构建&环境变量

9.2.1参数化构建

选择编辑Jenkinsfile,添加版本号参数,默认为v0.0Beta

 parameters {
    string(name: 'PROJECT_VERSION', defaultValue: 'v0.0Beta', description: '')
  }

image-20240930005552269

选择编辑流水线,选择添加步骤,选择shell,然后把PROJECT_VERSION参数输出

 echo $PROJECT_VERSION

image-20240930005438461

选择编辑操作、编辑配置、添加参数、选项参数,添加PROJECT_NAME参数,他的值是

gulimall-gateway
gulimall-auth-service
gulimall-cart
gulimall-coupon
gulimall-member
gulimall-order
gulimall-product
gulimall-search
gulimall-seckill
gulimall-third-party
gulimall-ware

image-20240930010029803

代码

image-20240930011406488

  parameters {
        string(name: 'PROJECT_VERSION', defaultValue: '1.0.0', description: '请输入版本号')
        choice(name: 'PROJECT_NAME', choices: ['gulimall-gateway', 'gulimall-auth-service', 'gulimall-cart', 'gulimall-coupon', 'gulimall-member', 'gulimall-order', 'gulimall-product', 'gulimall-search', 'gulimall-seckill', 'gulimall-third-party', 'gulimall-ware'], description: '请选择服务名称')
    }

选择运行

image-20240930011356118

查看日志,变量已经成功输出

image-20240930012014906

9.2.2环境变量

 environment {
        DOCKER_CREDENTIAL_ID = 'dockerhub-id'
        GITEE_CREDENTIAL_ID = 'gitee-id'
        KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
        REGISTRY = 'docker.io'
        DOCKERHUB_NAMESPACE = 'pengeng'
        GITEE_ACCOUNT = '15549996135'
        SONAR_CREDENTIAL_ID = 'sona-qube'
  }

image-20240930012254606

9.3第二步-Sonar代码质量分析

官方demo全局配置文件:https://github.com/kubesphere/devops-java-sample/blob/master/configuration/settings.xml

image-20240930020520405

完整配置见9.4

9.4第二步-Sonar代码质量分析&调试完成

9.4.1错误记录

参考:https://www.jianshu.com/p/bed574ae9ccc

image-20241002041154182

查看jenkin配置的sonatoken是够正确

# curl -u YOUR_SONAR_TOKEN: "http://SONARQUBE_HOST/api/projects/search"
curl -u b36a45e8c313beb1c99b9924082deed039bf1861: "http://192.168.188.181:32467/api/projects/search"

查看sona服务

kubectl get pod -n kubesphere-devops-system

查看jenkins地址:http://192.168.188.181:30180/sonarqube-webhook/

export NODE_PORT=$(kubectl get --namespace kubesphere-devops-system -o jsonpath="{.spec.ports[0].nodePort}" services ks-jenkins)
export NODE_IP=$(kubectl get nodes --namespace kubesphere-devops-system -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT

export NODE_PORT=$(kubectl get --namespace kubesphere-devops-system -o jsonpath="{.spec.ports[0].nodePort}" services ks-jenkins)
export NODE_IP=$(kubectl get nodes --namespace kubesphere-devops-system -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT/sonarqube-webhook/

查看sonaqube地址:http://192.168.188.181:30180

export NODE_PORT=$(kubectl get --namespace kubesphere-devops-system -o jsonpath="{.spec.ports[0].nodePort}" services sonarqube-sonarqube)
export NODE_IP=$(kubectl get nodes --namespace kubesphere-devops-system -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT

image-20241002024304528

Checking status of SonarQube task 'AZJJSjLVHdLHyflgZstE' on server 'sonar' java.lang.IllegalStateException: Unable to parse response from http://192.168.188.181:32467//api/ce/task?id=AZJJSjLVHdLHyflgZstE:

请求http://192.168.188.181:32467//api/ce/task?id=AZJJSjLVHdLHyflgZstE返回的是个html,不是json结果,是我jenkins地址配置错误,多个'/'

image-20241002024421923

9.4.2配置

pom.xmlsona配置

https://github.com/kubesphere/devops-java-sample/blob/master/pom.xml

<sonar.jacoco.reportPaths>${PWD}/./target/jacoco.exec</sonar.jacoco.reportPaths>
<sonar.groovy.binaries>target/classes</sonar.groovy.binaries>

image-20240930024048599

还有下面打包的部分

image-20241002024853712

下面是完整配置

Jenkinsfile

pipeline {
    agent {
        node {
            label 'maven'
        }
    }

    parameters {
        string(name: 'PROJECT_VERSION', defaultValue: '1.0.0', description: '请输入版本号')
        choice(name: 'PROJECT_NAME', choices: ['gulimall-cart', 'gulimall-coupon', 'gulimall-member'], description: '请选择服务名称')
    }

    environment {
        DOCKER_CREDENTIAL_ID      = 'dockerhub-id'
        GITEE_CREDENTIAL_ID       = 'gitee-id'
        KUBECONFIG_CREDENTIAL_ID  = 'demo-kubeconfig'
        REGISTRY                  = 'docker.io'
        DOCKERHUB_NAMESPACE       = 'pengeng'
        GITEE_ACCOUNT             = '15549996135'
        SONAR_CREDENTIAL_ID       = 'sonar-token'
        BRANCH_NAME               = 'master'
    }

    stages {
        stage('拉取代码') {
            agent none
            steps {
                git(url: 'https://gitee.com/peng_p/peng-mall.git', credentialsId: 'gitee-id', branch: 'master', changelog: true, poll: false)
                dir('code/peng-mall-parent') {             
                    sh 'echo 正在构建:$PROJECT_NAME 版本号:$PROJECT_VERSION 将会提交给 $REGISTRY 镜像仓库'     
                    container('maven') {
                        sh "echo 当前目录:`pwd`"
                        sh 'ls -al `pwd`'
                        sh "mvn clean install -U -Dmaven.test.skip=true -e -X -gs `pwd`/mvn-settings.xml"
                    }
                }
            }
        }

        stage('SonarQube 分析') {
            steps {
                dir('code/peng-mall-parent') {
                    container('maven') {  
                        withCredentials([string(credentialsId: "$SONAR_CREDENTIAL_ID", variable: 'SONAR_TOKEN')]) {
                            withSonarQubeEnv("sonar") {
                                sh "echo 当前目录:`pwd`"
                                // sh "mvn sonar:sonar -gs `pwd`/mvn-settings.xml -Dsonar.branch=$BRANCH_NAME -Dsonar.login=$SONAR_TOKEN"
                                sh "mvn sonar:sonar -gs `pwd`/mvn-settings.xml -Dsonar.login=$SONAR_TOKEN"
                            }
                        }
                    }
                }
            }
        }
		
        stage('阈值判断') {
            steps {
                script {
                    timeout(time: 1, unit: "HOURS") {
                        def qualityGate = waitForQualityGate()
                        if (qualityGate.status != 'OK') {
                            error "SonarQube 检测不通过: ${qualityGate.status}"
                        }
                    }
                }
            }
        }
    }
}

mvn-settings.xml

<settings>
  <mirrors>
	<mirror>
        <id>alimaven</id>
        <mirrorOf>central</mirrorOf>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
    </mirror>
  </mirrors>
  <profiles>
    <profile>
        <id>jdk-1.8</id>
        <activation>
            <activeByDefault>true</activeByDefault>
            <jdk>1.8</jdk>
        </activation>
        <properties>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
        </properties>
    </profile>
  </profiles>
</settings>

pom.xml

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <sonar.jacoco.reportPaths>${PWD}/./target/jacoco.exec</sonar.jacoco.reportPaths>
    <sonar.groovy.binaries>target/classes</sonar.groovy.binaries>
  </properties>
  
  
 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.2</version>
                <configuration>
                    <append>true</append>
                </configuration>
                <executions>
                    <execution>
                        <id>agent-for-ut</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>agent-for-it</id>
                        <goals>
                            <goal>prepare-agent-integration</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>jacoco-site</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
            <!-- 跳过单元测试 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.sonarsource.scanner.maven</groupId>
                <artifactId>sonar-maven-plugin</artifactId>
                <version>3.6.0.1398</version>
            </plugin>
        </plugins>
    </build> 

总算成功了

image-20241002030509701

代码质量

image-20241002030531161

9.5第三步-构建&推送镜像

9.5.1错误记录

java:8环境无法拉取

image-20241002043933877

可以使用openjdk:8-jdk-alpine版本的镜像

但在 openjdk:8-jdk-alpine 镜像中,默认没有安装 bash,只有 sh。因此,bash -c 'touch /app.jar' 这条命令会失败。

你可以将 Dockerfile 中的 RUN bash -c 'touch /app.jar' 替换为 RUN touch /app.jar,这样可以直接使用 sh 来执行。

这里测试我只改了gulimall-cart/Dockerfile,后面所有服务都需要修改

FROM openjdk:8-jdk-alpine
EXPOSE 8080

VOLUME /tmp
ADD target/*.jar /app.jar
# RUN bash -c 'touch /app.jar'
# 使用 sh 替代 bash
RUN touch /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar", "--spring.profiles.active=prod"]

image-20241002050716823

无法将镜像上传到docker hub

因为国内docker老是被墙(docker hub也保留,后面有机会再调通),所以这次上传到阿里云,因为流程都是一样的,只是配置一下阿里云的凭证和相关命令

阿里云配置见9.5.2

image-20241002063053199

9.5.2配置阿里云镜像仓库

参考:https://www.cnblogs.com/makalochen/p/14240796.html

image-20241002063458924

官方地址:https://cr.console.aliyun.com/cn-shanghai/instance/repositories

image-20241002053704838

创建本地仓库

image-20241002053804868

本地仓库创建完成

image-20241002064641285

我们需要留意docker login docker pulldocker push 三条命令

需要留意自己的请求地址、命名空间、仓库名称、账号名称

image-20241002064800789

9.5.3流水线配置阿里云

创建阿里云账号凭证,需要输入自己阿里云的账号密码

image-20241002055409888

在环境变量添加自己阿里云的相关参数,分别是凭证(配置阿里云的账号密码)、请求地址、命名空间、仓库名称、账号名称

  environment {
        DOCKER_CREDENTIAL_ID      = 'dockerhub-id'
        GITEE_CREDENTIAL_ID       = 'gitee-id'
        KUBECONFIG_CREDENTIAL_ID  = 'demo-kubeconfig'
        REGISTRY                  = 'docker.io'
        DOCKERHUB_NAMESPACE       = 'pengeng'
        GITEE_ACCOUNT             = '15549996135'
        SONAR_CREDENTIAL_ID       = 'sonar-token'
        BRANCH_NAME               = 'master'
		ALIYUN_CREDENTIAL_ID      = 'aliyun-id'
		ALIYUN_URL                = 'crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com' 
		ALIYUN_NAMESPACE          = 'pengpeng-namespace'
		ALIYUN_ACCOUNT            = 'pengpengservice'
    }

image-20241002080811694

创建阿里云的步骤,loginpush地址拼对即可,tag版本号可以小点

 stage ('构建镜像-推送阿里云') {
            steps {
                dir('code/peng-mall-parent') {
                    container ('maven') {
                        sh 'cd service/$PROJECT_NAME && docker build -f Dockerfile -t $BRANCH_NAME-$BUILD_NUMBER .'
                        sh "echo 镜像:$ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER"
						sh 'docker images'
                        withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD', usernameVariable : 'DOCKER_USERNAME', credentialsId : "$ALIYUN_CREDENTIAL_ID")]) {                   
                            sh 'echo "$DOCKER_PASSWORD" | docker login --username="$ALIYUN_ACCOUNT" "$ALIYUN_URL" --password-stdin'
                            sh 'docker tag $BRANCH_NAME-$BUILD_NUMBER $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER'
                            sh 'docker push $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER'
                        }
                    }
                }
            }
        }

image-20241002080904864

步骤都是成功状态

image-20241002081112629

push完成

image-20241002081037969

9.5.4配置docker-hub

地址:https://github.com/kubesphere/devops-java-sample/blob/master/Jenkinsfile-online

image-20241002031423582

需要修改的地方

image-20241002034306824

代码

        stage ('构建镜像-推送镜像') {
            steps {
                dir('code/peng-mall-parent') {
                    container ('maven') {
                        sh 'mvn -Dmaven.test.skip=true -gs `pwd`/mvn-settings.xml clean package'
                        sh 'ls -al `pwd`'
                        sh 'cd service/$PROJECT_NAME && docker build -f Dockerfile -t $REGISTRY/$DOCKERHUB_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER .'

                        withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD', usernameVariable : 'DOCKER_USERNAME', credentialsId : "$DOCKER_CREDENTIAL_ID", )]) {
                            sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
                            sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
                        }
                    }
                }
            }
        }

查看自己能否正常登录docker hub

因为老是登不上,所以选择了上传阿里云

echo "YOUR_PASSWORD" | docker login --username YOUR_USERNAME --password-stdin

image-20241002081348527

9.6第四步-流水线编写完成

  • 构建镜像 & 推送快照镜像
  • 推送最新镜像
  • 部署到开发集群环境
  • 发布版本
 stage ('构建镜像 & 推送快照镜像') {
            steps {
                dir('code/peng-mall-parent') {
                    container ('maven') {
					    sh 'mvn -Dmaven.test.skip=true -gs `pwd`/mvn-settings.xml clean package'	
                        sh 'cd service/$PROJECT_NAME && docker build -f Dockerfile -t $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER .'
                        sh "echo 快照镜像:$ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER"
						sh 'docker images'
                        withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD', usernameVariable : 'DOCKER_USERNAME', credentialsId : "$ALIYUN_CREDENTIAL_ID")]) {                   
                            sh 'echo "$DOCKER_PASSWORD" | docker login --username="$ALIYUN_ACCOUNT" "$ALIYUN_URL" --password-stdin'
                            sh 'docker push $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
                        }
                    }
                }
            }
        }
		
		stage('推送最新镜像'){
		  steps{
			dir('code/peng-mall-parent') {
				container ('maven') {
				  sh 'docker tag $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:latest '
				  sh 'docker push $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:latest '
				}
		    }
		  }
		}

		stage('部署到开发集群环境') {
		  steps {
			  dir('code/peng-mall-parent') {
				input(id: "deploy-to-prod-$PROJECT_NAME", message: "是否将 $PROJECT_NAME 部署到开发集群环境?")
				kubernetesDeploy(configs: "service/$PROJECT_NAME/deploy/**", enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
			  }
		   }
		}

		stage('发布版本'){
		  when{
			expression{
			  return params.PROJECT_VERSION =~ /v.*/
			}
		  }
		  steps {
			container ('maven') {
			  input(id: 'release-image-with-tag', message: '是否发布当前版本?')
			  sh 'docker tag $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$PROJECT_VERSION '
			  sh 'docker push $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$PROJECT_VERSION '
			  withCredentials([usernamePassword(credentialsId: "$GITEE_CREDENTIAL_ID",
			  passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
				sh 'git config --global user.email "pengpeng6135@163.com" '
				sh 'git config --global user.name "peng" '
				sh 'git tag -a $PROJECT_NAME-$PROJECT_VERSION -m "$PROJECT_VERSION" '
                // https://gitee.com/peng_p/peng-mall.git
				sh 'git push http://$GIT_USERNAME:$GIT_PASSWORD@gitee.com/$GITEE_NAME/peng-mall.git --tags --ipv4'
			  }
			}
		  }
		}	

修改每个服务k8s配置的镜像地址

image-20241004001027333

9.7部署-移植数据库

创建mysql8的工作负载

image-20241004004939873

选择指定工作负载吗,选择mysql8,暴露3302端口

image-20241004005027865

选择外网访问,选择NodePort,选择开启会话保持

image-20241004005118276

使用数据库连接工具,连接mysql8-node-port

image-20241004005232184

把之前的数据全部导出来

image-20241004012956038

新建数据库

image-20241004012910398

把所有数据到入到k8s的数据库里

image-20241004013034678

9.8流水线细节优化&解决OOM

重新创建一个流水线

peng-mall-jenkinsfile-cicd

image-20241004014635758

选择代码仓库,这里选择Git

image-20241004014812229

高级设置

如何Jenkinsfile不在根目录,可以指定位置

code/peng-mall-parent/Jenkinsfile

image-20241004020439770

如果一开始运行没有选择分支、版本、项目名称,可以刷新,或者停止运行重新运行,要不然Jenkinsfile获取不到PROJECT_NAME项目名称

image-20241004033629552

Jenkinsfile中配置所有服务,数组第一个就是默认值

 parameters {    
        choice(name: 'PROJECT_NAME', choices: ['gulimall-gateway', 'gulimall-auth-service', 'gulimall-cart', 'gulimall-coupon', 'gulimall-member', 'gulimall-order', 'gulimall-product', 'gulimall-search', 'gulimall-seckill', 'gulimall-third-party', 'gulimall-ware'], description: '请选择服务名称')
    }

image-20241004021044941

需要配置gulimall-gateway的镜像地址和端口

镜像地址是阿里云镜像地址,KubeSphere 的端口号范围是 30000 到 32767

image-20241004021933345

容器OOMKilled,说明容器部署异常,内存溢出

原因:jvm启动的时候,分配内存过大,而k8s里面部署的限制是500Mi【xx-deploy.yaml】,导致内存溢出直接将pod给杀

解决:构建docker镜像的时候,约束微服务jvm最大占用内存

配置gulimall-gatewayDockerfile

image-20241004031253583

除了gulimall-gateway网关服务,剩下的服务都在service文件夹里面,所以这里加了一个判断

image-20241004024423104

k8s配置这里也需要根据服务判断路径

image-20241004032742624

9.9流水线部署所有微服务

完整Jenkinsfile

pipeline {
    agent {
        node {
            label 'maven'
        }
    }

    parameters {
        string(name: 'PROJECT_VERSION', defaultValue: '1.0', description: '请输入版本号')
        choice(name: 'PROJECT_NAME', choices: ['gulimall-gateway', 'gulimall-auth-service', 'gulimall-cart', 'gulimall-coupon', 'gulimall-member', 'gulimall-order', 'gulimall-product', 'gulimall-search', 'gulimall-seckill', 'gulimall-third-party', 'gulimall-ware'], description: '请选择服务名称')
    }

    environment {
        DOCKER_CREDENTIAL_ID      = 'dockerhub-id'
        GITEE_CREDENTIAL_ID       = 'gitee-id'
        KUBECONFIG_CREDENTIAL_ID  = 'peng-mall-kubeconfig'
        REGISTRY                  = 'docker.io'
        DOCKERHUB_NAMESPACE       = 'pengeng'
        GITEE_ACCOUNT             = '15549996135'
		GITEE_NAME                = 'peng_p'
        SONAR_CREDENTIAL_ID       = 'sonar-token'
        BRANCH_NAME               = 'master'
		ALIYUN_CREDENTIAL_ID      = 'aliyun-id'
		ALIYUN_URL                = 'crpi-e3iemos7j8ulr18e.cn-shanghai.personal.cr.aliyuncs.com' 
		ALIYUN_NAMESPACE          = 'pengpeng-namespace'
		ALIYUN_ACCOUNT            = 'pengpengservice'
    }

    stages {
        stage('拉取代码') {
            agent none
            steps {
                git(url: 'https://gitee.com/peng_p/peng-mall.git', credentialsId: 'gitee-id', branch: 'master', changelog: true, poll: false)
                dir('code/peng-mall-parent') {             
                    sh 'echo 正在构建:$PROJECT_NAME 版本号:$PROJECT_VERSION 将会提交给 $REGISTRY 镜像仓库'     
                    container('maven') {
                        sh "echo 当前目录:`pwd`"
                        sh 'ls -al `pwd`'
                        sh "mvn clean install -U -Dmaven.test.skip=true -e -X -gs `pwd`/mvn-settings.xml"
                    }
                }
            }
        }

        stage('SonarQube 分析') {
            steps {
                dir('code/peng-mall-parent') {
                    container('maven') {  
                        withCredentials([string(credentialsId: "$SONAR_CREDENTIAL_ID", variable: 'SONAR_TOKEN')]) {
                            withSonarQubeEnv("sonar") {
                                sh "echo 当前目录:`pwd`"
                                // sh "mvn sonar:sonar -gs `pwd`/mvn-settings.xml -Dsonar.branch=$BRANCH_NAME -Dsonar.login=$SONAR_TOKEN"
                                sh "mvn sonar:sonar -gs `pwd`/mvn-settings.xml -Dsonar.login=$SONAR_TOKEN"
                            }
                        }
                    }
                }
            }
        }
        
        stage('阈值判断') {
            steps {
                script {
                    timeout(time: 1, unit: "HOURS") {
                        def qualityGate = waitForQualityGate()
                        if (qualityGate.status != 'OK') {
                            error "SonarQube 检测不通过: ${qualityGate.status}"
                        }
                    }
                }
            }
        }
        
        //stage ('构建镜像-推送镜像') {
        //    steps {
        //        dir('code/peng-mall-parent') {
        //            container ('maven') {
        //                sh 'mvn -Dmaven.test.skip=true -gs `pwd`/mvn-settings.xml clean package'
        //                sh 'ls -al `pwd`'
        //                sh 'cd service/$PROJECT_NAME && docker build -f Dockerfile -t $REGISTRY/$DOCKERHUB_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER .'
		//
        //                withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD', usernameVariable : 'DOCKER_USERNAME', credentialsId : "$DOCKER_CREDENTIAL_ID", )]) {
        //                    sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
        //                    sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
        //                }
        //            }
        //        }
        //    }
        //}
		
		 stage ('构建镜像 & 推送快照镜像') {
            steps {
                dir('code/peng-mall-parent') {
                    container ('maven') {
					    sh 'mvn -Dmaven.test.skip=true -gs `pwd`/mvn-settings.xml clean package'	

						sh """
						if [ "$PROJECT_NAME" = "gulimall-gateway" ]; then
							cd $PROJECT_NAME && docker build -f Dockerfile -t "$ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER" .
						else
							cd service/$PROJECT_NAME && docker build -f Dockerfile -t "$ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER" .
						fi
						"""					
						
						// sh 'cd service/$PROJECT_NAME && docker build -f Dockerfile -t $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER .'                					
                        sh "echo 快照镜像:$ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER"
						sh 'docker images'
                        withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD', usernameVariable : 'DOCKER_USERNAME', credentialsId : "$ALIYUN_CREDENTIAL_ID")]) {                   
                            sh 'echo "$DOCKER_PASSWORD" | docker login --username="$ALIYUN_ACCOUNT" "$ALIYUN_URL" --password-stdin'
                            sh 'docker push $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
                        }
                    }
                }
            }
        }
		
		stage('推送最新镜像'){
		  steps{
			dir('code/peng-mall-parent') {
				container ('maven') {
				  sh 'docker tag $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:latest '
				  sh 'docker push $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:latest '
				}
		    }
		  }
		}

		stage('部署到开发集群环境') {
		  steps {
			  dir('code/peng-mall-parent') {
				input(id: "deploy-to-prod-$PROJECT_NAME", message: "是否将 $PROJECT_NAME 部署到开发集群环境?")
				// kubernetesDeploy(configs: "service/$PROJECT_NAME/deploy/**", enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
				script {
					if (PROJECT_NAME == "gulimall-gateway") {
						kubernetesDeploy(configs: "$PROJECT_NAME/deploy/**", enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
					} else {
						kubernetesDeploy(configs: "service/$PROJECT_NAME/deploy/**", enableConfigSubstitution: true, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID")
					}
				}				
			  }
		   }
		}

		stage('发布版本'){
		  when{
			expression{
			  return params.PROJECT_VERSION =~ /v.*/
			}
		  }
		  steps {
			container ('maven') {
			  input(id: 'release-image-with-tag', message: '是否发布当前版本?')
			  sh 'docker tag $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$PROJECT_VERSION '
			  sh 'docker push $ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:$PROJECT_VERSION '
			  withCredentials([usernamePassword(credentialsId: "$GITEE_CREDENTIAL_ID",
			  passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
				sh 'git config --global user.email "pengpeng6135@163.com" '
				sh 'git config --global user.name "peng" '
				sh 'git tag -a $PROJECT_NAME-$PROJECT_VERSION -m "$PROJECT_VERSION" '
				sh 'git push http://$GIT_USERNAME:$GIT_PASSWORD@gitee.com/$GITEE_NAME/peng-mall.git --tags --ipv4'
			  }
			}
		  }
		}		
	      
    }
}

所有项目的Dockerfile是一样的

FROM openjdk:8-jdk-alpine
EXPOSE 8080

VOLUME /tmp
ADD target/*.jar /app.jar
# RUN bash -c 'touch /app.jar'
# 使用 sh 替代 bash
RUN touch /app.jar
ENTRYPOINT ["java", "-jar", "-Xms128m", "-Xmx300m", "/app.jar", "--spring.profiles.active=prod"]

【xx-deploy.yaml】需要修改镜像地址

镜像地址固定的,打包的时候就是发布最新的

$ALIYUN_URL/$ALIYUN_NAMESPACE/$PROJECT_NAME:latest

端口号范围必须是 30000 到 32767,我这里都是31000-31019

image-20241004034225243

创作不易,感谢支持。

wxzf
posted @ 2024-10-14 01:00  peng_boke  阅读(113)  评论(0编辑  收藏  举报