實踐005-Gitlab CICD全項目整合

文章目錄

    • 環境準備
      • 環境準備
      • 集成Kubernetes
    • Gitlab CICD項目整合
      • 項目整合
        • 整合設計
      • 后端Java項目部署
        • 后端Java項目靜態檢查
        • 后端Java項目鏡像構建
        • 創建Java項目部署文件
        • 創建完整流水線
      • 前端webui項目部署
        • 前端webui項目鏡像構建
        • 創建webui項目部署文件
        • 創建完整流水線
      • 構建父子類型流水線
      • 查看流水線
      • 確認驗證
        • 部署情況確認
        • 驗證后端應用
        • 驗證前端應用
      • Ddevops梳理

環境準備

環境準備

單獨測試前后端項目的時候已成功部署相關應用,為便于后續整合,將已部署的應用進行清理。

root@master01:~# kubectl -n gitlabci delete deployments.apps deploy-apiserver-ci deploy-webui-ci
root@master01:~# kubectl -n gitlabci delete service service-apiserver-ci service-webui-ci
root@master01:~# kubectl delete ns gitlabciroot@master01:~# kubectl get ns

整個環境需要發布鏡像至阿里云,需要將應用部署到 Kubernetes 。
因此提前在 gitlab 中創建 ALIYUN_USER 和 ALIYUN_PASSWORD 、KUBE_CONFIG 變量,配置阿里云鏡像推送的賬號和密碼。

集成Kubernetes

當前 Gitlab 的 runner 是基于 helm 部署 gitla 的同時配套部署的,即 runner 是運行在 Kubernetes 中的一個 Pod,runner 類型是 Kubernetes ,如下所示:

root@master01:~# kubectl -n gitlab exec -ti mygitlab-gitlab-runner-798986f578-h2thf -- bash
camygitlab-gitlab-runner-798986f578-h2thf:/$ cat /home/gitlab-runner/.gitlab-runner/config.toml
#……
[[runners]]
#……executor = "kubernetes"

因此該 runner 后續需要直接在 Kubernetes 中部署業務,需要安裝 kubectl 命令,以及配置 kubeconfig 上下文。

從而需要提前將 kubeconfig 內容以變量形式引入到 runner Pod 中。

root@master01:~# echo $(cat ~/.kube/config | base64) | tr -d " "
YXBpVmVyc2lvbjogdjEKY2x1c3RlcnM6Ci0gY2x1c3RlcjoKICA……

添加變量 KUBE_CONFIG 。
227

提示:由于后續流水線中作業有 main 和 tag 兩種觸發方式,因此建議將變量取消受保護。
同時對于 Kubernetes 的部署可參考: 附042.Kubernetes_v1.33.0生成環境高可用部署方案

Gitlab CICD項目整合

項目整合

整合設計

當前后端 java 和前端 web 的構建、測試、編譯基于學習目的,都由獨立項目通過 gitlab 驗證,基于生產環境需要,現需要整合至一個項目中,從而將多個子項目放在一個項目代碼倉中。

gitlab 創建總項目: mycicd 。
由于整合后的新項目為 mycicd ,因此原有部分文件的內容涉及路徑部分均需要稍作調整,sonarqube代碼檢查對接的gitlab項目也需要重新調整。
213

[root@gitclient ~]# git clone git@gitlab.linuxsb.com:mygroup/mycicd.git
[root@gitclient ~]# cd mycicd/

復制前后端項目至該目錄。

[root@gitclient mycicd]# cp -rp ../apiserver .
[root@gitclient mycicd]# cp -rp ../webui .
[root@gitclient mycicd]# tree -L 2 .
.
├── apiserver
│   ├── deployjavaci.yaml
│   ├── deployjavaprod.yaml
│   ├── deployjavatest.yaml
│   ├── Dockerfile
│   ├── HELP.md
│   ├── mvnw
│   ├── mvnw.cmd
│   ├── pom.xml
│   ├── README.md
│   └── src
├── README.md
└── webui├── babel.config.js├── deploywebuici.yaml├── deploywebuiprod.yaml├── deploywebuitest.yaml├── Dockerfile├── jsconfig.json├── node_modules├── package.json├── package-lock.json├── public├── README.md├── src└── vue.config.js

后端Java項目部署

后端Java項目靜態檢查

參考實踐002-Gitlab CICD靜態代碼檢查 ,重新配置 sonarqube 對 gitlab 新建的 mycicd 項目的檢查。

214

后端Java項目鏡像構建

目錄有所調整。

[root@gitclient mycicd]# vim apiserver/Dockerfile
FROM uhub.service.ucloud.cn/imxhy/maven:3.8.5-openjdk-17MAINTAINER xhy@itzgr.cnRUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezoneEXPOSE 8080WORKDIR /opt/apiserviceCOPY target/apiservice-0.0.1-SNAPSHOT.jar ./ENTRYPOINT ["java","-jar","/opt/apiservice/apiservice-0.0.1-SNAPSHOT.jar"]
創建Java項目部署文件

調整如下 ci 、 test 、 prod 部署文件。

  • ci 部署文件
[root@gitclient mycicd]# vim apiserver/deployjavaci.yaml
---
apiVersion: v1
kind: Namespace
metadata:name: gitlabci---
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-apiserver-cinamespace: gitlabci
spec:replicas: 2revisionHistoryLimit: 5selector:matchLabels:app: apiserver-cistrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 25%maxSurge: 25%template:metadata:labels:app: apiserver-cispec:containers:- name: apiserver-cienv:- name: TZvalue: Asia/Shanghaiimage: __POD_CONTAINERS_IMAGE__imagePullPolicy: IfNotPresentports:- containerPort: 8080protocol: TCPreadinessProbe:httpGet:path: /demo/helloport: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10livenessProbe:httpGet:path: /demo/helloport: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10---
apiVersion: v1
kind: Service
metadata:name: service-apiserver-cinamespace: gitlabci
spec:ports:- nodePort: 32101port: 8080protocol: TCPtargetPort: 8080selector:app: apiserver-cisessionAffinity: ClientIPtype: NodePort
  • test 部署文件
[root@gitclient mycicd]# vim apiserver/deployjavatest.yaml
---
apiVersion: v1
kind: Namespace
metadata:name: gitlabtest---
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-apiserver-testnamespace: gitlabtest
spec:replicas: 2revisionHistoryLimit: 5selector:matchLabels:app: apiserver-teststrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 25%maxSurge: 25%template:metadata:labels:app: apiserver-testspec:containers:- name: apiserver-testenv:- name: TZvalue: Asia/Shanghaiimage: __POD_CONTAINERS_IMAGE__imagePullPolicy: IfNotPresentports:- containerPort: 8080protocol: TCPreadinessProbe:httpGet:path: /demo/helloport: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10livenessProbe:httpGet:path: /demo/helloport: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10---
apiVersion: v1
kind: Service
metadata:name: service-apiserver-testnamespace: gitlabtest
spec:ports:- nodePort: 32102port: 8080protocol: TCPtargetPort: 8080selector:app: apiserver-testsessionAffinity: ClientIPtype: NodePort
  • prod 部署文件
[root@gitclient mycicd]# vim apiserver/deployjavaprod.yaml
---
apiVersion: v1
kind: Namespace
metadata:name: gitlabprod---
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-apiserver-prodnamespace: gitlabprod
spec:replicas: 2revisionHistoryLimit: 5selector:matchLabels:app: apiserver-prodstrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 25%maxSurge: 25%template:metadata:labels:app: apiserver-prodspec:containers:- name: apiserver-prodenv:- name: TZvalue: Asia/Shanghaiimage: __POD_CONTAINERS_IMAGE__imagePullPolicy: IfNotPresentports:- containerPort: 8080protocol: TCPreadinessProbe:httpGet:path: /demo/helloport: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10livenessProbe:httpGet:path: /demo/helloport: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10---
apiVersion: v1
kind: Service
metadata:name: service-apiserver-prodnamespace: gitlabprod
spec:ports:- nodePort: 32103port: 8080protocol: TCPtargetPort: 8080selector:app: apiserver-prodsessionAffinity: ClientIPtype: NodePort
創建完整流水線

創建如下流水線,并且將后端 Java 項目的編譯構建階段全部整合到一起。并且最后直接使用 git clone 使用 autotest 項目進行最后的測試。

即對于后端 Java 項目,整合 UnitTest+compile+sonarqube-check ----> build ----> deploy_java_ci/deploy_java_test ----> check_java_ci_pod/check_java_test_pod ----> test 全鏈路流程。

[root@gitclient mycicd]# vim apiserver/.gitlab-ci.yml
stages:- compile- build- deploy- check- testvariables:KUBECONFIG: "/.kube/config"PROJECT_DIR: "${CI_PROJECT_DIR}/apiserver"GITLAB_HOST: gitlab.linuxsb.comGITLAB_PORT: "32222"REPO_URL: git@${GITLAB_HOST}:mygroup/autotest.gitunittest_java:stage: compileimage: maven:3.8.5-openjdk-17script:- cd ${PROJECT_DIR}- mvn verify -Dmaven.test.failure.ignore=true- ls target/surefire-reports/*.xmlrules:- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAGartifacts:when: alwaysreports:junit:- apiserver/target/surefire-reports/TEST-*.xml- apiserver/target/failsafe-reports/TEST-*.xmltags:- study-runnercompile_java:stage: compileimage: uhub.service.ucloud.cn/imxhy/maven:3.8.5-openjdk-17artifacts:paths:- apiserver/target/apiservice-0.0.1-SNAPSHOT.jarscript:- pwd- cd ${PROJECT_DIR}- mvn clean- mvn compile- mvn package -Dmaven.test.skip=true- ls targetrules:- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAGtags:- study-runnersonarqube_check_java:stage: compileimage: maven:3.8.5-openjdk-17variables:SONAR_USER_HOME: "${CI_PROJECT_DIR}/apiserver/.sonar"GIT_DEPTH: "0"cache:key: "${CI_JOB_NAME}"paths:- .sonar/cachescript:- cd ${PROJECT_DIR}- mvn verify sonar:sonar -Dsonar.projectKey=mygroup_mycicd_AZaRvvQBjzPXArMYpIcZallow_failure: truerules:- if: $CI_COMMIT_BRANCH == "main"tags:- study-runnerbuild_java:stage: buildimage: uhub.service.ucloud.cn/imxhy/executor:v1.9.0-debugneeds:- unittest_java- compile_javascript:- cd ${PROJECT_DIR}- ls target- IMAGE_TAG=$(echo "${CI_COMMIT_TIMESTAMP}" | sed 's/T/_/g; s/-//g; s/://g' | cut -c1-15)- IMAGE_TAG_TO_INSTALL=${CI_COMMIT_TAG:-$IMAGE_TAG}- echo ${IMAGE_TAG_TO_INSTALL}- mkdir -p /kaniko/.docker- echo "{\"auths\":{\"registry.cn-hangzhou.aliyuncs.com\":{\"username\":\"${ALIYUN_USER}\",\"password\":\"${ALIYUN_PASSWORD}\"}}}" > /kaniko/.docker/config.json- cat /kaniko/.docker/config.json- echo ${PROJECT_DIR}- echo {\"username\":\"${ALIYUN_USER}\",\"password\":\"${ALIYUN_PASSWORD}\"}- ls ${PROJECT_DIR}/Dockerfile- >/kaniko/executor--context "${PROJECT_DIR}"--dockerfile "${PROJECT_DIR}/Dockerfile"--destination "registry.cn-hangzhou.aliyuncs.com/xhyimages/apiservice:${IMAGE_TAG_TO_INSTALL}"--registry-mirror "https://dbzucv6w.mirror.aliyuncs.com"rules:- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAGtags:- study-runnerdeploy_java_ci:stage: deployimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0script:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- kubectl version- IMAGE_TAG=$(echo "${CI_COMMIT_TIMESTAMP}" | sed 's/T/_/g; s/-//g; s/://g' | cut -c1-15)- IMAGE_TAG_TO_INSTALL=${CI_COMMIT_TAG:-$IMAGE_TAG}- echo $IMAGE_TAG_TO_INSTAL- sed -i "s#__POD_CONTAINERS_IMAGE__#registry.cn-hangzhou.aliyuncs.com/xhyimages/apiservice:${IMAGE_TAG_TO_INSTALL}#g" apiserver/deployjavaci.yaml- kubectl apply -f apiserver/deployjavaci.yaml || exit 1rules:- if: $CI_COMMIT_BRANCH == "main"tags:- study-runnerdeploy_java_test:stage: deployimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0when: manualscript:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- kubectl version- IMAGE_TAG=$(echo "${CI_COMMIT_TIMESTAMP}" | sed 's/T/_/g; s/-//g; s/://g' | cut -c1-15)- IMAGE_TAG_TO_INSTALL=${CI_COMMIT_TAG:-$IMAGE_TAG}- echo $IMAGE_TAG_TO_INSTAL- sed -i "s#__POD_CONTAINERS_IMAGE__#registry.cn-hangzhou.aliyuncs.com/xhyimages/apiservice:${IMAGE_TAG_TO_INSTALL}#g" apiserver/deployjavatest.yaml- kubectl apply -f apiserver/deployjavatest.yaml || exit 1rules:- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAGtags:- study-runnerdeploy_java_prod:stage: deployimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0when: manualscript:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- kubectl version- IMAGE_TAG=$(echo "${CI_COMMIT_TIMESTAMP}" | sed 's/T/_/g; s/-//g; s/://g' | cut -c1-15)- IMAGE_TAG_TO_INSTALL=${CI_COMMIT_TAG:-$IMAGE_TAG}- echo $IMAGE_TAG_TO_INSTAL- sed -i "s#__POD_CONTAINERS_IMAGE__#registry.cn-hangzhou.aliyuncs.com/xhyimages/apiservice:${IMAGE_TAG_TO_INSTALL}#g" apiserver/deployjavaprod.yaml- kubectl apply -f apiserver/deployjavaprod.yaml || exit 1rules:- if: $CI_COMMIT_TAGtags:- study-runnercheck_java_ci_pod:stage: checkimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0script:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- timeout 120 bash -c "until kubectl get pods -n gitlabci -l app=apiserver-ci --field-selector=status.phase=Running --no-headers | grep '1/1'; do sleep 3; done"rules:- if: $CI_COMMIT_BRANCH == "main"needs:- deploy_java_citags:- study-runnercheck_java_test_pod:stage: checkimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0script:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- timeout 120 bash -c "until kubectl get pods -n gitlabtest -l app=apiserver-test --field-selector=status.phase=Running --no-headers | grep '1/1'; do sleep 3; done"rules:- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAGneeds:- deploy_java_testtags:- study-runnercheck_java_prod_pod:stage: checkimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0script:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- timeout 120 bash -c "until kubectl get pods -n gitlabprod -l app=apiserver-prod --field-selector=status.phase=Running --no-headers | grep '1/1'; do sleep 3; done"rules:- if: $CI_COMMIT_TAGneeds:- deploy_java_prodtags:- study-runnertest:stage: testimage: python:3.13.3before_script:- mkdir -p ~/.ssh- chmod 700 ~/.ssh- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa- chmod 600 ~/.ssh/id_rsa- echo "Host ${GITLAB_HOST}" >> ~/.ssh/config- echo "    Port ${GITLAB_PORT}" >> ~/.ssh/config- echo "    User git" >> ~/.ssh/config- echo "    IdentityFile ~/.ssh/id_rsa" >> ~/.ssh/config- echo "    StrictHostKeyChecking no" >> ~/.ssh/config- ssh-keyscan -p ${GITLAB_PORT} ${GITLAB_HOST} >> ~/.ssh/known_hostsscript:- git clone -b main ${REPO_URL}- cd autotest- python -m pip install --no-cache-dir -r requirements.txt- mkdir -p tests/reports- cd tests && pytest -s --junitxml=reports/report.xml || echo "Pytest exited with $?"- pwd- ls -l .- ls -l reportsartifacts:reports:junit: autotest/tests/reports/report.xmlrules:- if: $CI_COMMIT_BRANCH == "main"tags:- study-runner

前端webui項目部署

前端webui項目鏡像構建

目錄有所調整。

[root@gitclient mycicd]# vim webui/Dockerfile
FROM uhub.service.ucloud.cn/imxhy/node:23.11.0MAINTAINER xhy@itzgr.comRUN npm install -g @vue/cliWORKDIR /opt/webui/COPY . ./RUN npm installENTRYPOINT ["npm","run","serve"]
創建webui項目部署文件

調整如下 ci 、 test 、 prod 部署文件。

  • ci 部署文件
[root@gitclient mycicd]# vim webui/deploywebuici.yaml
---
apiVersion: v1
kind: Namespace
metadata:name: gitlabci---
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-webui-cinamespace: gitlabci
spec:replicas: 2revisionHistoryLimit: 5selector:matchLabels:app: webui-cistrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 25%maxSurge: 25%template:metadata:labels:app: webui-cispec:containers:- name: webui-cienv:- name: TZvalue: Asia/Shanghaiimage: __POD_CONTAINERS_IMAGE__imagePullPolicy: IfNotPresentports:- containerPort: 8080protocol: TCPreadinessProbe:httpGet:path: /port: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10livenessProbe:httpGet:path: /port: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10---
apiVersion: v1
kind: Service
metadata:name: service-webui-cinamespace: gitlabci
spec:ports:- nodePort: 32111port: 8080protocol: TCPtargetPort: 8080selector:app: webui-cisessionAffinity: ClientIPtype: NodePort
  • test 部署文件
[root@gitclient mycicd]# vim webui/deploywebuitest.yaml
---
apiVersion: v1
kind: Namespace
metadata:name: gitlabtest---
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-webui-testnamespace: gitlabtest
spec:replicas: 2revisionHistoryLimit: 5selector:matchLabels:app: webui-teststrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 25%maxSurge: 25%template:metadata:labels:app: webui-testspec:containers:- name: webui-testenv:- name: TZvalue: Asia/Shanghaiimage: __POD_CONTAINERS_IMAGE__imagePullPolicy: IfNotPresentports:- containerPort: 8080protocol: TCPreadinessProbe:httpGet:path: /port: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10livenessProbe:httpGet:path: /port: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10---
apiVersion: v1
kind: Service
metadata:name: service-webui-testnamespace: gitlabtest
spec:ports:- nodePort: 32112port: 8080protocol: TCPtargetPort: 8080selector:app: webui-testsessionAffinity: ClientIPtype: NodePort
  • prod 部署文件
[root@gitclient mycicd]# vim webui/deploywebuiprod.yaml
---
apiVersion: v1
kind: Namespace
metadata:name: gitlabprod---
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-webui-prodnamespace: gitlabprod
spec:replicas: 2revisionHistoryLimit: 5selector:matchLabels:app: webui-prodstrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 25%maxSurge: 25%template:metadata:labels:app: webui-prodspec:containers:- name: webui-prodenv:- name: TZvalue: Asia/Shanghaiimage: __POD_CONTAINERS_IMAGE__imagePullPolicy: IfNotPresentports:- containerPort: 8080protocol: TCPreadinessProbe:httpGet:path: /port: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10livenessProbe:httpGet:path: /port: 8080scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10---
apiVersion: v1
kind: Service
metadata:name: service-webui-prodnamespace: gitlabprod
spec:ports:- nodePort: 32113port: 8080protocol: TCPtargetPort: 8080selector:app: webui-prodsessionAffinity: ClientIPtype: NodePort
創建完整流水線

創建如下流水線,并且將前端 webui 項目的構建階段全部整合到一起。
即對于前端 webui 項目,整合 build ----> deploy_webui_ci/deploy_webui_test ----> check_webui_ci_pod/check_webui_test_pod 全鏈路流程。

[root@gitclient mycicd]# vim webui/.gitlab-ci.yml
stages:- build- deploy- checkvariables:KUBECONFIG: "/.kube/config"PROJECT_DIR: "${CI_PROJECT_DIR}/webui"build_webui:stage: buildimage: uhub.service.ucloud.cn/imxhy/executor:v1.9.0-debugscript:- cd ${PROJECT_DIR}- IMAGE_TAG=$(echo "${CI_COMMIT_TIMESTAMP}" | sed 's/T/_/g; s/-//g; s/://g' | cut -c1-15)- IMAGE_TAG_TO_INSTALL=${CI_COMMIT_TAG:-$IMAGE_TAG}- echo $IMAGE_TAG_TO_INSTALL- mkdir -p /kaniko/.docker- echo "{\"auths\":{\"registry.cn-hangzhou.aliyuncs.com\":{\"username\":\"${ALIYUN_USER}\",\"password\":\"${ALIYUN_PASSWORD}\"}}}" > /kaniko/.docker/config.json- cat /kaniko/.docker/config.json- echo ${PROJECT_DIR}- echo {\"username\":\"${ALIYUN_USER}\",\"password\":\"${ALIYUN_PASSWORD}\"}- ls ${PROJECT_DIR}/Dockerfile- >/kaniko/executor--context "${PROJECT_DIR}"--dockerfile "${PROJECT_DIR}/Dockerfile"--destination "registry.cn-hangzhou.aliyuncs.com/xhyimages/webui:${IMAGE_TAG_TO_INSTALL}"--registry-mirror "https://dbzucv6w.mirror.aliyuncs.com"rules:- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAGtags:- study-runnerdeploy_webui_ci:stage: deployimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0script:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- kubectl version- IMAGE_TAG=$(echo "${CI_COMMIT_TIMESTAMP}" | sed 's/T/_/g; s/-//g; s/://g' | cut -c1-15)- IMAGE_TAG_TO_INSTALL=${CI_COMMIT_TAG:-$IMAGE_TAG}- sed -i "s#__POD_CONTAINERS_IMAGE__#registry.cn-hangzhou.aliyuncs.com/xhyimages/webui:${IMAGE_TAG_TO_INSTALL}#g" webui/deploywebuici.yaml- kubectl apply -f webui/deploywebuici.yaml || exit 1rules:- if: $CI_COMMIT_BRANCH == "main"tags:- study-runnerdeploy_webui_test:stage: deployimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0when: manualscript:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- kubectl version- IMAGE_TAG=$(echo "${CI_COMMIT_TIMESTAMP}" | sed 's/T/_/g; s/-//g; s/://g' | cut -c1-15)- IMAGE_TAG_TO_INSTALL=${CI_COMMIT_TAG:-$IMAGE_TAG}- sed -i "s#__POD_CONTAINERS_IMAGE__#registry.cn-hangzhou.aliyuncs.com/xhyimages/webui:${IMAGE_TAG_TO_INSTALL}#g" webui/deploywebuitest.yaml- kubectl apply -f webui/deploywebuitest.yaml || exit 1rules:- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAGtags:- study-runnerdeploy_webui_prod:stage: deployimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0when: manualscript:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- kubectl version- IMAGE_TAG=$(echo "${CI_COMMIT_TIMESTAMP}" | sed 's/T/_/g; s/-//g; s/://g' | cut -c1-15)- IMAGE_TAG_TO_INSTALL=${CI_COMMIT_TAG:-$IMAGE_TAG}- sed -i "s#__POD_CONTAINERS_IMAGE__#registry.cn-hangzhou.aliyuncs.com/xhyimages/webui:${IMAGE_TAG_TO_INSTALL}#g" webui/deploywebuiprod.yaml- kubectl apply -f webui/deploywebuiprod.yaml || exit 1rules:- if: $CI_COMMIT_TAGtags:- study-runnercheck_webui_ci_pod:stage: checkimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0script:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- timeout 120 bash -c "until kubectl get pods -n gitlabci -l app=webui-ci --field-selector=status.phase=Running --no-headers | grep '1/1'; do sleep 3; done"rules:- if: $CI_COMMIT_BRANCH == "main"needs:- deploy_webui_citags:- study-runnercheck_webui_test_pod:stage: checkimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0script:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- timeout 120 bash -c "until kubectl get pods -n gitlabtest -l app=webui-test --field-selector=status.phase=Running --no-headers | grep '1/1'; do sleep 3; done"rules:- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_TAGneeds:- deploy_webui_testtags:- study-runnercheck_webui_prod_pod:stage: checkimage: uhub.service.ucloud.cn/imxhy/kubectl:1.33.0script:- mkdir -p /.kube- echo $KUBE_CONFIG | base64 -d > $KUBECONFIG- timeout 120 bash -c "until kubectl get pods -n gitlabprod -l app=webui-prod --field-selector=status.phase=Running --no-headers | grep '1/1'; do sleep 3; done"rules:- if: $CI_COMMIT_TAGneeds:- deploy_webui_prodtags:- study-runner

構建父子類型流水線

父子類型流水線適用于將多個子項目放在一個項目代碼倉中的場景。
該場景中,流水線中存在后端 Java 、前端 webui 兩個項目的編譯、構建、發布以及集成在一起的測試和部署等。
因此可以使用父子類型的流水線,且配置是如果只修改了Java子項目,則只執行和Java子項目相關的流水線任務即可。

前端子項目的目錄為 webui,后端子項目的目錄為apiserver,組建父子類型的流水線,就是在項目的根目錄創建流水線發布文件.gitlab-ci.yml作為父流水線的配置,各子項目分別創建一個.gitlab-ci.yml作為子流水線的位置。

如上所致 java 后端和 webui 前端流水線均創建完成。

  • 父流水線
    子流水線不會自動觸發,需要項目根目錄下的.gitlab-ci.yml文件進行觸發。
    在父流水線中調用子流水線需要使用關鍵字 trigger 和 include 。
[root@gitclient mycicd]# vim .gitlab-ci.yml
stages:- triggers- pre-checkverify_files:stage: pre-checkscript:- ls -l apiserver/.gitlab-ci.yml- ls -l webui/.gitlab-ci.ymltrigger_apiserver:stage: triggerstrigger:include: apiserver/.gitlab-ci.ymlforward:pipeline_variables: truevariables:PARENT_TAG: $CI_COMMIT_TAGrules:- if: $CI_COMMIT_BRANCH == "main"changes:- apiserver/*- if: $CI_COMMIT_TAGchanges: []trigger_webui:stage: triggerstrigger:include: webui/.gitlab-ci.ymlforward:pipeline_variables: truevariables:PARENT_TAG: $CI_COMMIT_TAGrules:- if: $CI_COMMIT_BRANCH == "main"changes:- webui/*- if: $CI_COMMIT_TAGchanges: []

如上定義了一個節點, trigger ,然后 trigger 里定義了兩個任務,通過 include 關鍵字將子目錄下的 .gitlab-ci.yml 引用。
rules 和 changes 關鍵字是用來控制 job 觸發執行的,指定具體的目錄。
如上 trigger_back 的 job 指定了檢測目錄為 apiserver,即只有當 apiserver 目錄中的文件或代碼發生了變化,apiserver 目錄中的子流水線才會執行。

  • 提交流水線
    首次提交后,由于前后端都是第一次生成,因此會自動執行完所有任務。
[root@gitclient mycicd]# git add .
[root@gitclient mycicd]# git status [root@gitclient mycicd]# git commit -m "Deploy apiserver and webui cicd"
[root@gitclient mycicd]# git push origin main

查看流水線

查看提交流水線后的作業情況。

215

216
217

確認驗證

部署情況確認

查看部署在 Kubernetes 后的應用,

root@master01:~# kubectl -n gitlabci get pods -o wide
NAME                                   READY   STATUS    RESTARTS   AGE    IP             NODE       NOMINATED NODE   READINESS GATES
deploy-apiserver-ci-68655894c8-qzcwr   1/1     Running   0          117m   10.10.19.82    worker03   <none>           <none>
deploy-apiserver-ci-68655894c8-vrdwd   1/1     Running   0          117m   10.10.5.47     worker01   <none>           <none>
deploy-webui-ci-5cfb75dfcf-7zm8w       1/1     Running   0          111m   10.10.19.115   worker03   <none>           <none>
deploy-webui-ci-5cfb75dfcf-zncr9       1/1     Running   0          111m   10.10.5.35     worker01   <none>           <none>
root@master01:~# kubectl -n gitlabci get svc -o wide
NAME                   TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE    SELECTOR
service-apiserver-ci   NodePort   10.20.29.161   <none>        8080:32101/TCP   117m   app=apiserver-ci
service-webui-ci       NodePort   10.20.10.106   <none>        8080:32111/TCP   112m   app=webui-ci
root@master01:~# kubectl -n gitlabci get deployments.apps
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
deploy-apiserver-ci   2/2     2            2           117m
deploy-webui-ci       2/2     2            2           112m
驗證后端應用

瀏覽器直接訪問: http://172.24.8.180:32101/demo/hello 。

218

驗證前端應用

瀏覽器直接訪問: http://172.24.8.180:32111
219

Ddevops梳理

如上所示為一個包含前后端的完整流水線,其主要包括過程總結如下:

  1. 當后端研發人員提交代碼后,流水線會自動觸發。首先執行compile階段,主要包括unittest_java、compile_java和靜態代碼檢查sonarqube_check_java,這三個認為是并行執行的。而且只要compile階段執行完成,不論單元測試和靜態代碼檢查是否執行完成,都會執行第二個build鏡像構建階段。當build鏡像構建階段完成后,自動部署到CI環境,CI環境部署完成后,開始檢查CI環境中的Pod狀態是否正常。檢查完成后,開始自動執行自動化測試。當自動化測試執行完成后,根據測試結果及其他需求,計劃是否要部署到測試環境,測試環境的部署由手動執行。

  2. 部署到測試環境后,流水線執行如下,然后測試團隊可以對測試環境進行測試:

221

  1. 當測試團隊測試完成,并對測試結果進行bug修復完成后,可以通過tags部署線上生產環境。

222

  1. 打完tag后同樣會觸發新的流水線,通過打tag觸發的流水線有兩個選擇,即部署測試環境或部署生產環境,同時保留手動執行,即在通過CI環境同時修復bug后打tag,然后人為審核是否發版,然后手動執行。
    223

  2. 手動部署 test 環境,然后可以通知測試人員對test環境進行測試。
    224

  3. 測試團隊確認后,可以手動開始部署 prod 生產環境。
    225

226

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82346.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82346.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82346.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鴻蒙開發:dialog庫做了一些優化

前言 本文基于Api13 dialog庫是我去年5月份開發了一個便捷彈窗庫&#xff0c;主打一個使用簡單&#xff0c;一經推出&#xff0c;在dialog領域下載量穩居在前&#xff0c;可以說是非常受歡迎的&#xff1b;但是&#xff0c;之前的版本仍然有著可優化的空間&#xff0c;比如彈窗…

Windows 10 無法啟動或黑屏的修復指南(適用于更新失敗或磁盤故障)

Windows 10 無法啟動或黑屏的修復指南&#xff08;適用于更新失敗或磁盤故障&#xff09; 當 Windows 10 突然無法啟動&#xff08;黑屏、無限重啟、更新失敗后斷電等情況&#xff09;&#xff0c;很可能是由于啟動引導程序損壞或系統映像異常&#xff08;如系統磁盤出現壞道&…

MCP開發入門

MCP開發入門 官方文檔: https://modelcontextprotocol.io/introduction 入門教程: https://github.com/liaokongVFX/MCP-Chinese-Getting-Started-Guide 本文源代碼&#xff1a;https://github.com/youngqqcn/mcp-server-demo 什么是MCP&#xff1f; 模型上下文協議&#xff…

PX4開始之旅(二)通過自定義 MAVLink 消息與 QGroundControl (QGC) 通信

核心知識點&#xff1a;通過自定義 MAVLink 消息與 QGroundControl (QGC) 通信 1. 通俗易懂的解釋 想象一下&#xff0c;MAVLink 就像是無人機&#xff08;飛控&#xff09;和地面站&#xff08;QGroundControl&#xff09;之間約定好的一種“語言”。這種語言有很多標準的“…

AI視頻智能分析網關打造社區/工廠/校園/倉庫智慧消防實現精準化安全管控

一、背景 隨著社區、商業場所對消防安全要求日益提升&#xff0c;傳統消防系統已難以滿足智能化、精細化管理需求。智能分析網關融合物聯網與人工智能技術&#xff0c;具備強大的數據處理與分析能力&#xff0c;可全面升級消防系統。將其融入消防系統各層級&#xff0c;搭建智…

深度學習基礎--目標檢測常見算法簡介(R-CNN、Fast R-CNN、Faster R-CNN、Mask R-CNN、SSD、YOLO)

博主簡介&#xff1a;努力學習的22級本科生一枚 &#x1f31f;?&#xff1b;探索AI算法&#xff0c;C&#xff0c;go語言的世界&#xff1b;在迷茫中尋找光芒?&#x1f338;? 博客主頁&#xff1a;羊小豬~~-CSDN博客 內容簡介&#xff1a;常見目標檢測算法簡介?&#x1f…

傳輸層協議UDP和TCP

傳輸層協議UDP和TCP 1、UDP2、TCP2.1、TCP協議段格式2.2、確認應答(ACK)機制2.3、超時重傳機制2.4、連接管理機制2.5、理解CLOSE_WAIT狀態2.6、理解TIME_WAIT狀態2.7、流量控制2.8、滑動窗口2.9、擁塞控制2.10、延遲應答2.11、捎帶應答2.12、面向字節流2.13、粘包問題2.14、TCP…

PMIC電源管理模塊的PCB設計

目錄 PMU模塊簡介 PMU的PCB設計 PMU模塊簡介 PMIC&#xff08;電源管理集成電路&#xff09;是現代電子設備的核心模塊&#xff0c;負責高效協調多路電源的轉換、分配與監控。它通過集成DC-DC降壓/升壓、LDO線性穩壓、電池充電管理、功耗狀態切換等功能&#xff0c;替代傳統分…

Ubuntu 配置網絡接口端點(靜態 IP 地址)詳細教程

在 Ubuntu 系統中&#xff0c;配置網絡接口端點通常指的是為您的有線或無線網卡設置一個固定的 IP 地址、子網掩碼、網關以及 DNS 服務器。這對于服務器或者需要穩定網絡標識的設備來說非常重要。 使用 Netplan (Ubuntu 17.10 及更高版本的默認方式)使用 ifupdown (通過 /etc/…

淺聊大模型-有條件的文本生成

大家好我是木木&#xff0c;自從2022年11月30日OpenAI發布ChatGPT后&#xff0c;大模型迅速火熱起來&#xff0c;人工智能作為當下最火的行業之一&#xff0c;2025年春節期間DeepSeek R1模型大火。LLM中有很多的技術&#xff0c;今天我們聊聊大模型-有條件的文本生成。 什么是…

華為銀河麒麟 V10(ARM)系統軟件部署全攻略:Redis、RabbitMQ、MySQL 等集群搭建指南

一、Redis 集群部署&#xff08;主從 哨兵模式&#xff09; 1. 環境準備 系統&#xff1a;華為銀河麒麟 V10&#xff08;ARM64&#xff09;節點&#xff1a;3 臺服務器&#xff08;1 主 2 從 3 哨兵&#xff09; 2. 安裝包下載 bash # 華為鏡像站 wget https://update.c…

Mysql數據庫進階

一、Mysql組織架構 連接層 1.驗證用戶的身份,用戶名密碼是否匹配 2.提供兩種連接方式(TCP/IP連接、socket連接) 3.連接層提供了一個與sql層交互的線程 SQL層 1.接收連接層傳過來的SQL語句 2.驗證執行的SQL語法 3.驗證SQL的語義(DDL,DML,DQL,DCL) 4.解析器:解析SQL語句,生…

系統思考:短期困境與長期收益

最近在項目中&#xff0c;一直有學員會提到一個議題&#xff0c;如何平衡當前困境和長期收益&#xff1f; 我的思考是在商業和人生的路上&#xff0c;我們常常聽到“魚和熊掌不可兼得”的說法&#xff0c;似乎短期利益和長期目標注定是對立的。但事實上&#xff0c;魚與熊掌是…

Spring Web MVC快速入門

什么是Spring Web MVC Spring Web MVC 是基于 Servlet API 構建的原始 Web 框架&#xff0c;從?開始就包含在 Spring 框架中。它的正式名稱“Spring Web MVC”來?其源模塊的名稱(Spring-webmvc)&#xff0c;但它通常被稱為"Spring MVC". View(視圖) 指在應?程序…

DeepSeek基于注意力模型的可控圖像生成

DeepSeek大模型高性能核心技術與多模態融合開發 - 商品搜索 - 京東 圖像的加噪與模型訓練 在擴散模型的訓練過程中&#xff0c;首先需要對輸入的信號進行加噪處理&#xff0c;經典的加噪過程是在圖像進行向量化處理后在其中添加正態分布&#xff0c;而正態分布的值也是與時間…

第十六屆藍橋杯B組第二題

當時在考場的時候這一道題目 無論我是使用JAVA的大數&#xff08;BIGTHGER&#xff09;還是賽后 使用PY 都是沒有運行出來 今天也是突發奇想在B站上面搜一搜 看了才知道這也是需要一定的數學思維 通過轉換 設X來把運算式精簡化 避免運行超時 下面則是代碼 public class lanba…

HT71663同步升壓2.7V-13V輸入10A聚能芯半導體禾潤一級代理

在便攜式設備飛速發展的今天&#xff0c;電源轉換效率與產品尺寸始終是行業難以平衡的難題。但現在&#xff0c;HT71663 高功率全集成升壓轉換器強勢登場&#xff0c;一舉打破僵局&#xff0c;為便攜式系統帶來顛覆性的高效小尺寸解決方案&#xff01;? HT71663 的卓越性能&am…

Unity:輸入系統(Input System)與持續檢測鍵盤按鍵(Input.GetKey)

目錄 Unity 的兩套輸入系統&#xff1a; &#x1f50d; Input.GetKey 詳解 &#x1f3af; 對比&#xff1a;常用的輸入檢測方法 技術底層原理&#xff08;簡化版&#xff09; 示例&#xff1a;角色移動 為什么會被“新輸入系統”替代&#xff1f; Unity 的兩套輸入系統&…

港大今年開源了哪些SLAM算法?

過去的5個月&#xff0c;香港大學 MaRS 實驗室陸續開源了四套面向無人機的在線 SLAM 框架&#xff1a;**FAST-LIVO2 、Point-LIO&#xff08;grid-map 分支&#xff09; 、Voxel-SLAM 、Swarm-LIO2 **。這四套框架覆蓋了單機三傳感器融合、高帶寬高速機動、長時間多級地圖優化以…

【質量管理】TRIZ因果鏈分析:解碼質量問題的“多米諾效應“

為什么要使用因果鏈分析 沒有發現問題并不等于沒有問題。愛因斯坦曾說&#xff0c;如果我只有一個小時的時間來拯救世界&#xff0c;我將花45分鐘時間分析問題&#xff0c;10分鐘的時間來檢查問題&#xff0c;最后5分鐘的時間來解決問題。可見問題分析的重要性。 在質量管理實踐…