DevOps系列文章 之GitLabCI模板库的流水线

目录结构,jobs目录用于存放作业模板。templates目录用于存放流水线模板。这次使用​​default-pipeline.yml​​作为所有作业的基础模板。

作业模板

作业分为Build、test、codeanalysis、artifactory、deploy部分,在每个作业中配置了rules功能开关,由变量控制最终作业的运行。

jobs/build.yml  构建作业模板

包含两个作业模板,分别是普通的构建模板(maven/npm/gradle)和docker 镜像构建模板。

## build相关作业

.build:
  stage: build
  script: 
    - |
      ${BUILD_SHELL}
  variables:
    GIT_CHECKOUT: "true"
  rules:
    - if: " $RUN_PIPELINE_BUILD == 'no' "
      when: never
    - when: always


## 构建镜像
.build-docker:
  stage: buildimage
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWD  $CI_REGISTRY
    - docker build -t ${IMAGE_NAME} -f ${DOCKER_FILE_PATH} .
    - docker push ${IMAGE_NAME} 
    - docker rmi ${IMAGE_NAME} 
  rules:
    - if: " $RUN_BUILD_IMAGE == 'no' "
      when: never
    - when: always

jobs/test.yml  测试作业模板

主要用于运行项目单元测试,例如maven、gradle、npm单元测试。

#单元测试
.test:
  stage: test
  script:
    - $TEST_SHELL
  artifacts:
    reports:
      junit: ${JUNIT_REPORT_PATH}
  rules:
    - if: " $RUN_PIPELINE_TEST == 'no' "
      when: never
    - when: always
jobs/codeanalysis.yml 代码扫描模板

包含两个作业模板,分别为扫描作业和获取扫描结果。这里面将扫描参数进行了分类,通用的项目参数、特殊的合并请求参数、自定义的项目参数。

##代码扫描
##
##
##

.code_analysis:
  variables:
    GLOBAL_PROJECT_ARGS: "-Dsonar.projectKey=${CI_PROJECT_NAME} 
                          -Dsonar.projectName=${CI_PROJECT_NAME} 
                          -Dsonar.projectVersion=${CI_COMMIT_REF_NAME} 
                          -Dsonar.projectDescription=${CI_PROJECT_TITLE}"
    GLOBAL_SERVER_ARGS:  "-Dsonar.ws.timeout=30 
                          -Dsonar.links.homepage=${CI_PROJECT_URL} 
                          -Dsonar.host.url=${SONAR_SERVER_URL} 
                          -Dsonar.login=${SONAR_SERVER_LOGIN}
                          -Dsonar.sourceEncoding=UTF-8 "
    GLOBAL_MR_ARGS: " -Dsonar.pullrequest.key=${CI_MERGE_REQUEST_IID} 
                      -Dsonar.pullrequest.branch=${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} 
                      -Dsonar.pullrequest.base=${CI_MERGE_REQUEST_TARGET_BRANCH_NAME} 
                      -Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME} 
                      -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA} 
                      -Dsonar.gitlab.project_id=${CI_PROJECT_PATH} 
                      -Dsonar.pullrequest.gitlab.repositorySlug=${CI_PROJECT_ID} "
    MULTI_BRANCH_ARGS: "-Dsonar.branch.name=${CI_COMMIT_REF_NAME}"
  stage: code_analysis
  script:
    - echo ${GLOBAL_PROJECT_ARGS} ${GLOBAL_SERVER_ARGS} ${SONAR_SCAN_ARGS} ${GLOBAL_MR_ARGS}
    #sonar-scanner $GLOBAL_PROJECT_ARGS $GLOBAL_SERVER_ARGS $SCAN_JAVA_ARGS
    - |
        if [ $CI_PIPELINE_SOURCE == 'merge_request_event' ] 
        
        then
           echo "sonar-scanner ${GLOBAL_PROJECT_ARGS} ${GLOBAL_SERVER_ARGS} ${SONAR_SCAN_ARGS} " 
           sonar-scanner ${GLOBAL_PROJECT_ARGS} ${GLOBAL_SERVER_ARGS} ${SONAR_SCAN_ARGS} 
        else 
           echo "sonar-scanner ${GLOBAL_PROJECT_ARGS} ${GLOBAL_SERVER_ARGS} ${SONAR_SCAN_ARGS} ${MULTI_BRANCH_ARGS}"
           sonar-scanner ${GLOBAL_PROJECT_ARGS} ${GLOBAL_SERVER_ARGS} ${SONAR_SCAN_ARGS}  ${MULTI_BRANCH_ARGS}
        fi 
  rules:
    - if: " $RUN_CODE_ANALYSIS == 'no' "
      when: never
    - when: always


#### 获取代码扫描结果
.get_analysis_result:
  stage: get_analysis_result
  script:
    - |
        SONAR_REPORT_URL=$(grep "ceTaskUrl" .scannerwork/report-task.txt  | awk -F = '{OFS="=";print $2,$3}')
        echo ${SONAR_REPORT_URL}
        
        
        for i in {1..10}
        do
          curl -k -u "${SONAR_SERVER_LOGIN}":"" ${SONAR_REPORT_URL}  -o sonar_result.txt -s
          grep '"status":"SUCCESS"' sonar_result.txt  && SONAR_SCAN_RESULT='SUCCESS'
        
          if [ ${SONAR_SCAN_RESULT} == 'SUCCESS' ]
            then
              echo "${SONAR_SCAN_RESULT}"
              SONAR_SCAN_RESULT=SUCCESS

              curl -k -u "${SONAR_SERVER_LOGIN}":"" "${SONAR_SERVER_URL}/api/qualitygates/project_status?projectKey=$CI_PROJECT_NAME&branch=$CI_COMMIT_REF_NAME" -o result.txt  -s
              echo "result info ---->>>>>"
              cat result.txt
              result=`cat result.txt | awk -F ':' '{print $3}' | awk -F '"' '{print$2}'`
              
              echo $result

              if [ $result == 'ERROR' ]                 
                then 
                  echo "${result}"
                  exit 122
                  break;
              else
                  echo "success!"
                  break;
              fi
            
          else
            SONAR_SCAN_RESULT='ERROR'
            echo "第$i次获取结果信息,不是成功状态,睡眠10秒!"
            cat sonar_result.txt
            sleep 10
          fi
        done
        
  rules:
    - if: " $RUN_CODE_ANALYSIS == 'no' "
      when: never
    - when: always
jobs/artifactory.yml 制品管理作业

包含两个作业,制品上传与下载。使用artifactory制品库接口。

## 制品库相关
##

.deploy-artifact:
  stage: deploy-artifact
  script:
    - echo "curl -u${ARTIFACT_USER}:${ARTIFACT_PASSWD} -T ${ARTIFACT_PATH} $ARTIFACTORY_URL/$ARTIFACTORY_NAME/$TARGET_FILE_PATH/$TARGET_ARTIFACT_NAME"
    - curl -u${ARTIFACT_USER}:${ARTIFACT_PASSWD} -T ${ARTIFACT_PATH} "$ARTIFACTORY_URL/$ARTIFACTORY_NAME/$TARGET_FILE_PATH/$TARGET_ARTIFACT_NAME"
  rules:
    - if: " $RUN_DEPLOY_ARTIFACTS == 'no' "
      when: never
    - when: always


.down-artifact:
  stage: down-artifact
  script:
    - curl -u${ARTIFACT_USER}:${ARTIFACT_PASSWD} -O "$ARTIFACTORY_URL/$ARTIFACTORY_NAME/$TARGET_FILE_PATH/$TARGET_ARTIFACT_NAME"
    - ls
jobs/deploy.yml  发布作业模板

发布基于k8s的发布和回滚配置。

## 应用发布


## 使用kubectl镜像发布
.deploy_k8s:
  stage: deploy
  script:
    - echo $KUBE_TOKEN
    - kubectl config set-cluster my-cluster --server=${KUBE_URL} --certificate-authority="${KUBE_CA_PEM_FILE}"
    - kubectl config set-credentials admin --token=${KUBE_TOKEN}
    - ls -a 
    - sed -i "s#__namespace__#${NAMESPACE}#g" ${DEPLOY_FILE}
    - sed -i "s#__appname__#${APP_NAME}#g" ${DEPLOY_FILE}
    - sed -i "s#__containerport__#${CONTAINER_PORT}#g" ${DEPLOY_FILE} 
    - sed -i "s#__nodeport__#${NODE_PORT}#g" ${DEPLOY_FILE} 
    - sed -i "s#__imagename__#${IMAGE_NAME}#g" ${DEPLOY_FILE} 
    - sed -i "s#__CI_ENVIRONMENT_SLUG__#${CI_ENVIRONMENT_SLUG}#g" ${DEPLOY_FILE}
    - sed -i "s#__CI_PROJECT_PATH_SLUG__#${CI_PROJECT_PATH_SLUG}#g" ${DEPLOY_FILE}
    - sed -i "s#__ingressdomain__#${ENV_URL}#g" ${DEPLOY_FILE}
    - cat ${DEPLOY_FILE}
    - "kubectl create secret docker-registry ${APP_NAME} \
            --docker-server=${CI_REGISTRY} \
            --docker-username=$CI_REGISTRY_USER \
            --docker-password=${CI_REGISTRY_PASSWD} \
            --docker-email=test@test.com -n ${NAMESPACE} || echo 'secrets already exists'"
    - kubectl apply -f ${DEPLOY_FILE}
  rules:
    - if: " $RUN_DEPLOY_K8S == 'no'"
      when: never
    - when: manual
  environment:
    name: "${ENV_NAME}"
    url: "http://${ENV_NAME}.${CI_PROJECT_NAMESPACE}.${CI_PROJECT_NAME}.devops.com"

  


## 回滚
.rollout_k8s:
  stage: deploy
  script:
    - rm -rf $HOME/.kube
    - kubectl config set-cluster my-cluster --server=${KUBE_URL} --certificate-authority="${KUBE_CA_PEM_FILE}"
    - kubectl config set-credentials admin --token=${KUBE_TOKEN}
    - kubectl rollout history deployment ${APP_NAME} -n ${NAMESPACE}
    - kubectl rollout undo deployment ${APP_NAME} -n ${NAMESPACE}
  rules:
    - if: " $RUN_DEPLOY_K8S == 'no' "
      when: never
    - when: manual
  environment:
    name: "${ENV_NAME}"
    action: stop

default流水线模板

templates/default-pipeline.yml 模板分成个部分

  • include导入作业模板
  • variables 定义全局变量
  • workflow 定义流水线控制
  • jobs 构建与发布作业

include导入作业模板

include:
  - project: 'cidevops/cidevops-newci-service'
    ref: master
    file: 'jobs/build.yml'
  - project: 'cidevops/cidevops-newci-service'
    ref: master
    file: 'jobs/test.yml'
  - project: 'cidevops/cidevops-newci-service'
    ref: master
    file: 'jobs/codeanalysis.yml'
  - project: 'cidevops/cidevops-newci-service'
    ref: master
    file: 'jobs/deploy.yml'
  - project: 'cidevops/cidevops-newci-service'
    ref: master
    file: 'jobs/artifactory.yml'

variables 定义全局变量

variables:
  ## 全局配置
  GIT_CLONE_PATH: ${CI_BUILDS_DIR}/builds/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}/${CI_PIPELINE_ID}    
  GIT_CHECKOUT: "false"
  CACHE_DIR: ""

  ## 作业控制
  RUN_PIPELINE_BUILD: ""     #是否运行构建 yes/no 
  RUN_PIPELINE_TEST: ""      #是否运行测试 yes/no 
  RUN_CODE_ANALYSIS: ""      #是否代码扫描 yes/no 
  RUN_BUILD_IMAGE: ""        #是否生成镜像 yes/no
  RUN_DEPLOY_ARTIFACTS: ""   #是否上传制品 yes/no
  RUN_DEPLOY_K8S: ""         #是否发布K8S yes/no

  ## 依赖容器镜像
  BUILD_IMAGE: ""
  CURL_IMAGE: "curlimages/curl:7.70.0"
  SONAR_IMAGE: "sonarsource/sonar-scanner-cli:latest"
  KUBECTL_IMAGE: "lucj/kubectl:1.17.2"
  
  
  ## 构建测试参数
  MAVEN_OPTS: ""                #maven构建参数 
  GRADLE_OPTS: ""               #gradle构建参数
  BUILD_SHELL: ''               #构建命令

  ## 单元测试参数
  TEST_SHELL : 'mvn test  --settings=./settings.xml '       #测试命令
  JUNIT_REPORT_PATH: 'target/surefire-reports/TEST-*.xml'   #单元测试报告

  ## 代码扫描
  SONAR_SOURCE_DIR : "src"                                          #项目源码目录
  SONAR_SERVER_URL: "http://192.168.1.200:30090"                    #SonarQube服务器信息
  SONAR_SERVER_LOGIN: "ee2bcb37deeb6dfe3a07fe08fb529559b00c1b7b"    #Sonar Token最好在项目中定义。
  SONAR_SCAN_ARGS: "-Dsonar.sources=${SONAR_SOURCE_DIR}"            #项目扫描参数

  ## 构建镜像
  CI_REGISTRY: 'registry.cn-beijing.aliyuncs.com'               #镜像仓库地址              
  CI_REGISTRY_USER: 'xxxxxx'                               #仓库用户信息
  #CI_REGISTRY_PASSWD: 'xxxxxxxx.'                              #仓库用户密码
  IMAGE_NAME: "${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}"     #镜像名称
  DOCKER_FILE_PATH: "./Dockerfile"                              #Dockerfile位置

  ## 上传制品库(artifactory)
  ARTIFACTORY_URL: "http://192.168.1.200:30082/artifactory"     #制品库地址
  ARTIFACTORY_NAME: "${CI_PROJECT_NAMESPACE}"                   #制品库名称
  ARTIFACT_PACKAGE: "jar"                                       #制品类型
  ARTIFACT_PATH: "target/*.${ARTIFACT_PACKAGE}"                 #制品位置
  TARGET_FILE_PATH: "${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}/${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}"   #目标制品位置(目录结构)
  TARGET_ARTIFACT_NAME: "${CI_PROJECT_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}.${ARTIFACT_PACKAGE}"   #目标制品名称

  ## 部署应用k8s
  APP_NAME: "$CI_PROJECT_NAME"                #应用名称 <--> deploymentName
  CONTAINER_PORT: "8081"                      #服务端口 <--> servicesPort
  NAMESPACE: "$CI_PROJECT_NAME-$CI_PROJECT_ID-$CI_ENVIRONMENT_SLUG"             #名称空间
  ENV_URL: "${ENV_NAME}.${CI_PROJECT_NAMESPACE}.${CI_PROJECT_NAME}.devops.com"  #IngressHosts

流水线设置

## 流水线控制
workflow:
  rules:
    - if: "$CI_MERGE_REQUEST_ID"          #过滤合并请求
      when: never
    - if: "$CI_PIPELINE_SOURCE == 'web'"    #允许在web页面发布
    - if: "$CI_COMMIT_REF_NAME =~ /^RELEASE-*/ || $CI_COMMIT_REF_NAME =~ /master/ "  #过滤版本分支和主干分支提交代码触发
      when: never
    - if: "$CI_COMMIT_BEFORE_SHA == '0000000000000000000000000000000000000000'"     #过滤分支创建请求
      when: never
    ### 默认策略
    - when: always


## 运行阶段  
stages:
  - build
  - test
  - parallel01
  - get_analysis_result
  - deploy-artifact
  - deploy-feature
  - rollout-feature
  - deploy-uat
  - rollout-uat
  - deploy-stag
  - rollout-stag
  - deploy-prod
  - rollout-prod

cache:
  paths:
    - ${CACHE_DIR}
    
before_script:
  - export

构建作业配置

################# Jobs Configure #####################
## 构建作业
build:
  image: ${BUILD_IMAGE}
  extends: .build

## 测试作业
test:
  image: ${BUILD_IMAGE}
  extends: .test
  before_script:
    - ls 
    - ls ${CACHE_DIR}

## 代码扫描
code_analysis:
  stage: parallel01
  image: ${SONAR_IMAGE}
  extends: .code_analysis

## 获取构建结果
get_analysis_result:
  image: ${CURL_IMAGE}
  extends: .get_analysis_result
  needs:
    - code_analysis


## 构建镜像
build_image:
  image: docker:latest
  services:
    - name: docker:dind
  stage: parallel01
  extends: .build-docker


## 上传制品
deploy_artifact:
  image: ${CURL_IMAGE}
  stage: deploy-artifact
  extends: .deploy-artifact

## 下载制品  
#down_artifact:  
#  image: ${CURL_IMAGE}
#  stage: down_artifact
#  extends: .down-artifact

发布部署作业配置

发布部署作业配置

#################Deploy Feature Jobs Configure #####################
## feature发布应用
deploy_feature:
  variables:
    DEPLOY_FILE: 'deployment.yaml'
    ENV_NAME: 'feature'
  stage: deploy-feature
  image: ${KUBECTL_IMAGE}
  extends: .deploy_k8s
  environment:
    on_stop: "rollout_feature"
  rules:
    - if: $RUN_DEPLOY_K8S == 'no'
      when: never
    - if: $CI_COMMIT_REF_NAME =~ /^RELEASE-*/ || $CI_COMMIT_REF_NAME =~ /master/ || $CI_COMMIT_TAG
      when: never
    - when: manual
    
## 应用回滚
rollout_feature:
  variables:
    DEPLOY_FILE: 'deployment.yaml'
    ENV_NAME: 'feature'
  stage: rollout-feature
  image: ${KUBECTL_IMAGE}
  extends: .rollout_k8s
  needs:
    - deploy_feature
  rules:
    - if: $RUN_DEPLOY_K8S == 'no'
      when: never
    - if: $CI_COMMIT_REF_NAME =~ /^RELEASE-*/ || $CI_COMMIT_REF_NAME =~ /master/ || $CI_COMMIT_TAG
      when: never
    - when: on_failure


#################Deploy UAT Jobs Configure #####################
## UAT
deploy_uat:
  variables:
    DEPLOY_FILE: 'config/deployment-uat.yaml'
    ENV_NAME: 'uat'
  stage: deploy-uat
  image: ${KUBECTL_IMAGE}
  extends: .deploy_k8s
  environment:
    on_stop: "rollout_uat"
  rules:
    - if: $RUN_DEPLOY_K8S == 'no'
      when: never
    - if: $CI_COMMIT_REF_NAME =~ /^RELEASE-*/ || $CI_COMMIT_REF_NAME =~ /master/ || $CI_COMMIT_TAG
      when: manual
    - when: never

## UAT应用回滚
rollout_uat:
  variables:
    DEPLOY_FILE: 'config/deployment-uat.yaml'
    ENV_NAME: 'uat'
  stage: rollout-uat
  image: ${KUBECTL_IMAGE}
  extends: .rollout_k8s
  needs:
    - deploy_uat
  rules:
    - if: $RUN_DEPLOY_K8S == 'no'
      when: never
    - if: $CI_COMMIT_REF_NAME =~ /^RELEASE-*/ || $CI_COMMIT_REF_NAME =~ /master/ || $CI_COMMIT_TAG
      when: on_failure
    - when: never

#################Deploy STAG Jobs Configure #####################
## STAG
deploy_stag:
  variables:
    DEPLOY_FILE: 'config/deployment-stag.yaml'
    ENV_NAME: 'stag'
  stage: deploy-stag
  image: ${KUBECTL_IMAGE}
  extends: .deploy_k8s
  environment:
    on_stop: "rollout_stag"
  needs:
    - deploy_uat
  rules:
    - if: $RUN_DEPLOY_K8S == 'no'
      when: never
    - if: $CI_COMMIT_REF_NAME =~ /^RELEASE-*/ || $CI_COMMIT_REF_NAME =~ /master/ || $CI_COMMIT_TAG
      when: manual
    - when: never

## STAG应用回滚
rollout_stag:
  variables:
    DEPLOY_FILE: 'config/deployment-stag.yaml'
    ENV_NAME: 'stag'
  stage: rollout-stag
  image: ${KUBECTL_IMAGE}
  extends: .rollout_k8s
  needs:
    - deploy_stag
  rules:
    - if: $RUN_DEPLOY_K8S == 'no'
      when: never
    - if: $CI_COMMIT_REF_NAME =~ /^RELEASE-*/ || $CI_COMMIT_REF_NAME =~ /master/ || $CI_COMMIT_TAG
      when: on_failure
    - when: never

#################Deploy PROD Jobs Configure #####################
## PROD
deploy_prod:
  variables:
    DEPLOY_FILE: 'config/deployment-prod.yaml'
    ENV_NAME: 'prod'
  stage: deploy-prod
  image: ${KUBECTL_IMAGE}
  extends: .deploy_k8s
  environment:
    on_stop: "rollout_prod"
  needs:
    - deploy_stag
  rules:
    - if: $RUN_DEPLOY_K8S == 'no'
      when: never
    - if: $CI_COMMIT_REF_NAME =~ /^RELEASE-*/ || $CI_COMMIT_REF_NAME =~ /master/ || $CI_COMMIT_TAG
      when: manual
    - when: never

## PROD应用回滚
rollout_prod:
  variables:
    DEPLOY_FILE: 'config/deployment-prod.yaml'
    ENV_NAME: 'prod'
  stage: rollout-prod
  image: ${KUBECTL_IMAGE}
  extends: .rollout_k8s
  needs:
    - deploy_prod
  rules:
    - if: $RUN_DEPLOY_K8S == 'no'
      when: never
    - if: $CI_COMMIT_REF_NAME =~ /^RELEASE-*/ || $CI_COMMIT_REF_NAME =~ /master/ || $CI_COMMIT_TAG
      when: on_failure
    - when: never

JAVA项目交付流水线

导入作业模板

include:
  - project: 'cidevops/cidevops-newci-service'
    ref: master
    file: 'templates/default-pipeline.yml'

配置项目参数

variables:
  ## 全局配置
  GIT_CLONE_PATH: ${CI_BUILDS_DIR}/builds/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}/${CI_PIPELINE_ID}    
  GIT_CHECKOUT: "false"
  CACHE_DIR: "target/"

  ## 作业控制
  RUN_PIPELINE_BUILD:   "yes"     #是否运行构建 yes/no 
  RUN_PIPELINE_TEST:    "yes"      #是否运行测试 yes/no 
  RUN_CODE_ANALYSIS:    "yes"     #是否代码扫描 yes/no 
  RUN_BUILD_IMAGE:      "yes"     #是否生成镜像 yes/no
  RUN_DEPLOY_ARTIFACTS: "no"      #是否上传制品 yes/no
  RUN_DEPLOY_K8S:       "yes"     #是否发布K8S yes/no

  ## 依赖容器镜像
  BUILD_IMAGE: "maven:3.6.3-jdk-8"
  CURL_IMAGE: "curlimages/curl:7.70.0"
  SONAR_IMAGE: "sonarsource/sonar-scanner-cli:latest"
  KUBECTL_IMAGE: "lucj/kubectl:1.17.2"
  
  
  ## 构建测试参数
  MAVEN_OPTS: "-Dmaven.repo.local=/home/gitlab-runner/ci-build-cache/maven "  #maven构建参数
  BUILD_SHELL: 'mvn clean package  -DskipTests  --settings=./settings.xml '   #构建命令
  #GRADLE_OPTS: ""               #gradle构建参数

  ## 单元测试参数
  TEST_SHELL : 'mvn test  --settings=./settings.xml   '       #测试命令
  JUNIT_REPORT_PATH: 'target/surefire-reports/TEST-*.xml'   #单元测试报告

  ## 代码扫描
  SONAR_SOURCE_DIR : "src"                                          #项目源码目录
  SONAR_SERVER_URL: "http://192.168.1.200:30090"                    #SonarQube服务器信息
  SONAR_SERVER_LOGIN: "ee2bcb37deeb6dfe3a07fe08fb529559b00c1b7b"    #Sonar Token最好在项目中定义。
  SONAR_SCAN_ARGS: "-Dsonar.sources=${SONAR_SOURCE_DIR} 
                   -Dsonar.java.binaries=target/classes 
                   -Dsonar.java.test.binaries=target/test-classes 
                   -Dsonar.java.surefire.report=target/surefire-reports "                                     #项目扫描参数

  ## 构建镜像
  CI_REGISTRY: 'registry.cn-beijing.aliyuncs.com'               #镜像仓库地址              
  CI_REGISTRY_USER: 'xxxxxx'                               #仓库用户信息
  #CI_REGISTRY_PASSWD: 'xxxxxxxx.'                              #仓库用户密码
  IMAGE_NAME: "${CI_REGISTRY}/${CI_PROJECT_PATH}:${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}"     #镜像名称
  DOCKER_FILE_PATH: "./Dockerfile"                              #Dockerfile位置

  ## 上传制品库(artifactory)
  #ARTIFACTORY_URL: "http://192.168.1.200:30082/artifactory"     #制品库地址
  #ARTIFACTORY_NAME: "${CI_PROJECT_NAMESPACE}"                   #制品库名称
  #ARTIFACT_PACKAGE: "jar"                                       #制品类型
  #ARTIFACT_PATH: "target/*.${ARTIFACT_PACKAGE}"                 #制品位置
  #TARGET_FILE_PATH: "${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}/${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}"   #目标制品位置(目录结构)
  #TARGET_ARTIFACT_NAME: "${CI_PROJECT_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}.${ARTIFACT_PACKAGE}"   #目标制品名称

  ## 部署应用k8s
  APP_NAME: "$CI_PROJECT_NAME"                #应用名称 <-->deploymentName
  CONTAINER_PORT: "8081"                      #服务端口 <--> servicesPort
  NAMESPACE: "$CI_PROJECT_NAME-$CI_PROJECT_ID-$CI_ENVIRONMENT_SLUG"             #名称空间
  ENV_URL: "${ENV_NAME}.${CI_PROJECT_NAMESPACE}.${CI_PROJECT_NAME}.devops.com"  #IngressHosts

指定CI文件

 

a59a8cb028a9eac2913566bed3fced2c3e0639.png

运行流水线测试

91008c234ab30211cc849111019987306cd4f6.png

docker镜像仓库

b7ec32543579c2bea671731a5b6aacfb65123c.png

部署环境演示

 

627e9a4447f6395689f2395ce5205a551b6848.png

Kubernetes集群中应用状态

模板案例

variables:
  REPOSITORY: "xxxx/xxxxxx"
stages:
   - deploy

build:
  stage: deploy
  only:
    - master
  script:
    - docker build -t $REPOSITORY:prod .
    - docker tag $REPOSITORY:prod "私有镜像库地址"/$REPOSITORY:prod
    - docker push "私有镜像库地址"/$REPOSITORY:prod
  tags:
    - lable

test:
  stage: deploy
  only:
    - test
  script:
    - docker build -t $REPOSITORY:testing .
    - docker tag $REPOSITORY:testing "私有镜像库地址"/$REPOSITORY:testing
    - docker push "私有镜像库地址"/$REPOSITORY:testing
  tags:
    - lable

dev:
  stage: deploy
  only:
    - dev
  script:
    - docker build -t $REPOSITORY:dev .
    - docker tag $REPOSITORY:dev "私有镜像库地址"/$REPOSITORY:dev
    - docker push "私有镜像库地址"/$REPOSITORY:dev
  tags:
    - lable

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/46606.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【广州华锐互动】AR智慧机房设备巡检系统

AR智慧机房设备巡检系统是一种新型的机房巡检方式&#xff0c;它通过使用增强现实技术将机房设备、环境等信息实时呈现在用户面前&#xff0c;让巡检人员可以更加高效地完成巡检任务。 首先&#xff0c;AR智慧机房设备巡检系统具有极高的智能化程度。该系统可以根据用户设定的…

java代码审计6之ssrf

文章目录 1、java支持的网络请求协议&#xff1a;2、Java 中能发起⽹络请求的类2.1、仅⽀持 HTTP/HTTPS 协议的类2.2、⽀持 sun.net.www.protocol 所有协议的类2.3、审计关键词 3、靶场3.1、漏洞代码13.2、ftp协议读取技巧3.3、无回显之探测内网3.4、无回显之探测文件 之前的文…

区间预测 | MATLAB实现基于QRF随机森林分位数回归多变量时间序列区间预测模型

区间预测 | MATLAB实现基于QRF随机森林分位数回归多变量时间序列区间预测模型 目录 区间预测 | MATLAB实现基于QRF随机森林分位数回归多变量时间序列区间预测模型效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现基于QRF随机森林分位数回归多变量时间序列区间…

Android 耗时分析(adb shell/Studio CPU Profiler/插桩Trace API)

1.adb logcat 查看冷启动时间和Activity显示时间&#xff1a; 过滤Displayed关键字&#xff0c;可看到Activity的显示时间 那上面display后面的是时间是指包含哪些过程的时间呢&#xff1f; 模拟在Application中沉睡1秒操作&#xff0c;冷启动情况下&#xff1a; 从上可知&…

SpringBoot 集成 Elasticsearch

一、版本 spring-boot版本&#xff1a;2.3.7.RELEASEElasticsearch7.8.0版本说明详见 二、Elasticsearch 下载和安装 Elasticsearch 下载 kibana下载 ik分词器下载 配置IK分词器 2.1 解压&#xff0c;在elasticsearch-7.8.0\plugins 路径下新建ik目录 2.2 将ik分词器解压放…

pytest---环境切换(base-url)

前言 前面小编介绍了如何通过pytest的插件来实现自动化测试的环境的切换&#xff0c;当时使用的方法是通过钩子函数进行获取命令行参数值&#xff0c;然后通过提前配置好的参数进行切换测试环境地址&#xff0c;今天小编再次介绍一种方法&#xff0c;通过pytest的插件&#xff…

2023年深圳杯数学建模B题电子资源版权保护问题

2023年深圳杯数学建模 B题 电子资源版权保护问题 原题再现&#xff1a; 版权又称著作权&#xff0c;包括发表权、署名权、修改权、保护作品完整权、复制权、发行权、出租权、展览权、表演权、放映权、广播权、信息网络传播权、摄制权、改编权、翻译权、汇编权及应当由著作权人…

安全学习DAY06_抓包技术-HTTPHTTPS

抓包技术-HTTP&HTTPS HTTP&HTTPS抓包针对Web&APP&小程序&PC应用等 本节目的&#xff1a; 掌握几种抓包工具证书安装操作掌握几种HTTP&HTTPS抓包工具的使用学会Web&#xff0c;APP&#xff0c;小程序&#xff0c;PC应用等抓包了解本节课抓包是针对哪些…

【100天精通python】Day17:常见异常类型与解决,异常处理语句

目录 一 python 的常见异常类型与解决 二 常用的异常处理语句 1 try...except语句 2 try...except...else语句 3 try...except...finally语句 4 使用raise语句抛出异常 5 自定义异常类型 6 异常链处理 在 Python中&#xff0c;异常是在程序运行时发生的错误或意外情…

华为eNSP:路由引入

一、拓扑图 二、路由器的配置 1、配置路由器的IP AR1&#xff1a; [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 1.1.1.1 24 [Huawei-GigabitEthernet0/0/0]qu AR2&#xff1a; [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 1.1.1.2 24 [Huaw…

【Lua学习笔记】Lua进阶——函数和闭包

文章目录 函数函数嵌套闭包Closures可变函数函数重载 函数 函数嵌套 function A()print("这里是函数A")return function ()print("返回函数不要起名")end end B A() B()输出&#xff1a; 这里是函数A 返回函数不要起名使用函数嵌套的用法&#xff0c;我…

power dns recursor 4.5以后版本的奇葩问题

问题 最近升级了 pdns-recursor 从 4.1.X 升级至 4.8.x 出现下面问题 效果为 nslookup 可以返回 ip 地址 dig 无法返回对应 ip 地址 ad dns 服务器转发过来的解析都不响应 tcp 抓包如下 当使用 nslookup 请求时 addition rrs 请求为 0 当使用 dig 请求时 addition rrs 请求为 1…

Java虚拟机——Java内存模型

"Java内存模型"来屏蔽各种硬件和操作系统的内存访问差异&#xff0c;以实现让Java程序在各种平台下都能达到一致的内存访问效果。主要目的&#xff1a;定义程序中各种变量的访问规则&#xff0c;即关注在虚拟机中把变量值存储到内存和从内存中取出变量值这样的底层细…

用 Node.js 手写 WebSocket 协议

目录 引言 从 http 到 websocekt 的切换 Sec-WebSocket-Key 与 Sec-WebSocket-Accept 全新的二进制协议 自己实现一个 websocket 服务器 按照协议格式解析收到的Buffer 取出opcode 取出MASK与payload长度 根据mask key读取数据 根据类型处理数据 frame 帧 数据的发…

使用Python搭建代理服务器- 爬虫代理服务器详细指南

搭建一个Python爬虫代理服务器可以让你更方便地管理和使用代理IP。下面是一个详细的教程来帮助你搭建一个简单的Python爬虫代理服务器&#xff1a; 1. 首先&#xff0c;确保你已经安装了Python。你可以在官方网站(https://www.python.org/)下载并安装最新版本的Python。 2. 安…

一.MySQL的主从复制

目录 一.MySQL的主从复制 1.2主从复制的工作过程和原理 1.2.1主从复制工作过程为两日志和三线程 ​编辑 1.2.2主从复制的工作原理 1.3主从复制延迟的原因 1.4主从复制的架构 1.5.MySQL四种同步方式 1.5.1异步复制(Async Replication) 1.5.2 同步复制&#xff08;Sync Re…

新功能 – Cloud WAN:托管 WAN 服务

我很高兴地宣布&#xff0c;我们推出了 Amazon Cloud WAN&#xff0c;这是一项新的网络服务&#xff0c;它可以轻松构建和运营连接您的数据中心和分支机构以及多个 Amazon 区域中的多个 VPC 的广域网&#xff08;WAN&#xff09;。 亚马逊云科技开发者社区为开发者们提供全球的…

Linux centos7.x系统 下没有ens33 网卡的解决方案

一、背景 安装完windows11 Centos7.9 版本的双系统之后 , 启动Centos7.9时发现没有网卡信息 , 只有ifcfg-lo网卡的信息 , 这个时候就证明没有网卡信息&#xff0c;或者网卡驱动不匹配(我这里是没有网卡)&#xff0c;所以我们要重新安装 , 安装步骤如下 : 二、安装步骤 1.查…

使用分布式HTTP代理爬虫实现数据抓取与分析的案例研究

在当今信息爆炸的时代&#xff0c;数据已经成为企业决策和发展的核心资源。然而&#xff0c;要获取大规模的数据并进行有效的分析是一项艰巨的任务。为了解决这一难题&#xff0c;我们进行了一项案例研究&#xff0c;通过使用分布式HTTP代理爬虫&#xff0c;实现数据抓取与分析…

C++多线程编程(第二章 多线程通信和同步)

1、多线程状态 1.1线程状态说明 初始化&#xff08;Init&#xff09;:该线程正在被创建&#xff1b; 就绪&#xff08;Ready&#xff09;:该线程在就绪列表中&#xff0c;等待CPU调度&#xff1b; 运行&#xff08;Running&#xff09;:该线程正在运行&#xff1b; 阻塞&…