03-kubesphere流水線搭建

peng_boke發表於2024-10-14

前言

及時清醒,事事甘心

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

相關文章