前言
及時清醒,事事甘心
9.流水線
參考:https://gitee.com/tanqidi/gulimall
9.1第一步gitee拉取程式碼
官方demo
地址:https://github.com/kubesphere/devops-java-sample/blob/master/Jenkinsfile-online
選擇peng-mall-devops
,建立流水線
這裡預設無需修改,點選建立
選擇新建的流水線peng-mall-cicd
,選擇編輯流水線
選擇自定義流水線
選擇node
,選擇maven
新增步驟
新建碼雲憑證,我已經建立過了,自己輸入自己的賬號即可
新增步驟完成
選擇編輯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)
}
}
}
}
}
我這裡因為專案程式碼有幾層其他的目錄,所以加了dir('code/peng-mall-parent'){}
命令,代表拉取code/peng-mall-parent
目錄下的程式碼,沒有別的目錄層級的話刪除即可
選擇活動,選擇執行,我這裡已經執行成功了
點選執行記錄進去,可以檢視日誌
9.2第一步-引數化構建&環境變數
9.2.1引數化構建
選擇編輯Jenkinsfile
,新增版本號引數,預設為v0.0Beta
parameters {
string(name: 'PROJECT_VERSION', defaultValue: 'v0.0Beta', description: '')
}
選擇編輯流水線,選擇新增步驟,選擇shell
,然後把PROJECT_VERSION
引數輸出
echo $PROJECT_VERSION
選擇編輯操作、編輯配置、新增引數、選項引數,新增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
程式碼
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: '請選擇服務名稱')
}
選擇執行
檢視日誌,變數已經成功輸出
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'
}
9.3第二步-Sonar程式碼質量分析
官方demo
全域性配置檔案:https://github.com/kubesphere/devops-java-sample/blob/master/configuration/settings.xml
完整配置見9.4
9.4第二步-Sonar程式碼質量分析&除錯完成
9.4.1錯誤記錄
參考:https://www.jianshu.com/p/bed574ae9ccc
檢視jenkin
配置的sona
的token
是夠正確
# 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
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
地址配置錯誤,多個'/'
9.4.2配置
pom.xml
的sona
配置
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>
還有下面打包的部分
下面是完整配置
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>
總算成功了
程式碼質量
9.5第三步-構建&推送映象
9.5.1錯誤記錄
java:8環境無法拉取
可以使用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"]
無法將映象上傳到docker hub
因為國內docker老是被牆(docker hub也保留,後面有機會再調通),所以這次上傳到阿里雲,因為流程都是一樣的,只是配置一下阿里雲的憑證和相關命令
阿里雲配置見9.5.2
9.5.2配置阿里雲映象倉庫
參考:https://www.cnblogs.com/makalochen/p/14240796.html
官方地址:https://cr.console.aliyun.com/cn-shanghai/instance/repositories
建立本地倉庫
本地倉庫建立完成
我們需要留意docker login
、docker pull
、docker push
三條命令
需要留意自己的請求地址、名稱空間、倉庫名稱、賬號名稱
9.5.3流水線配置阿里雲
建立阿里雲賬號憑證,需要輸入自己阿里雲的賬號密碼
在環境變數新增自己阿里雲的相關引數,分別是憑證(配置阿里雲的賬號密碼)、請求地址、名稱空間、倉庫名稱、賬號名稱
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'
}
建立阿里雲的步驟,login
和push
地址拼對即可,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'
}
}
}
}
}
步驟都是成功狀態
push
完成
9.5.4配置docker-hub
地址:https://github.com/kubesphere/devops-java-sample/blob/master/Jenkinsfile-online
需要修改的地方
程式碼
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
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
配置的映象地址
9.7部署-移植資料庫
建立mysql8
的工作負載
選擇指定工作負載嗎,選擇mysql8
,暴露3302
埠
選擇外網訪問,選擇NodePort
,選擇開啟會話保持
使用資料庫連線工具,連線mysql8-node-port
把之前的資料全部匯出來
新建資料庫
把所有資料到入到k8s
的資料庫裡
9.8流水線細節最佳化&解決OOM
重新建立一個流水線
peng-mall-jenkinsfile-cicd
選擇程式碼倉庫,這裡選擇Git
高階設定
如何Jenkinsfile
不在根目錄,可以指定位置
code/peng-mall-parent/Jenkinsfile
如果一開始執行沒有選擇分支、版本、專案名稱,可以重新整理,或者停止執行重新執行,要不然Jenkinsfile
獲取不到PROJECT_NAME
專案名稱
在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: '請選擇服務名稱')
}
需要配置gulimall-gateway
的映象地址和埠
映象地址是阿里雲映象地址,KubeSphere
的埠號範圍是 30000 到 32767
容器OOMKilled
,說明容器部署異常,記憶體溢位
原因:jvm
啟動的時候,分配記憶體過大,而k8s
裡面部署的限制是500Mi【xx-deploy.yaml】
,導致記憶體溢位直接將pod
給殺
解決:構建docker
映象的時候,約束微服務jvm
最大佔用記憶體
配置gulimall-gateway
的Dockerfile
除了gulimall-gateway
閘道器服務,剩下的服務都在service
資料夾裡面,所以這裡加了一個判斷
k8s
配置這裡也需要根據服務判斷路徑
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
創作不易,感謝支援。