项目下创建.gitlab-ci.yml文件
.gitlab-ci.yml
stages:
  - build
  - deploy

image: alpine/git  # 使用 Alpine 带 Git 镜像,避免安装额外的 Git1

variables:
  ARTICLES:
    description: "选择部署模块"
    value: "voyage-gateway"
    options:
      - "voyage-trip"
      - "voyage-open"
      - "mate-uaa"
      - "mate-platform/mate-system"
      - "mate-platform/mate-component"
      - "voyage-gateway"
  PACKAGE_ENV: "-Ptest"
  # ARTICLES: "voyage-trip mate-uaa mate-platform/mate-system mate-platform/mate-component voyage-gateway"
  # ARTICLES: $DEPLOY_MODULE
  IMAGE_TAG_PREFIX: "$CI_REGISTRY_IMAGE"
  K8S_NAMESPACE: "cvtest"
  K8S_API_SERVER: "https://172.22.8.21:6443"
  K8S_TOKEN: "$TEST_K8S_DEPLOY_TOKEN"
  module: $ARTICLES

# maven
mvn_build:
  # before_script:
  #   - echo '172.21.24.84 nexus.dev.scntsc.com' >> /etc/hosts
  image: maven:3.6.3-openjdk-11
  interruptible: true #允许被中断,防止同时多次提交,多个任务同时执行
  resource_group: mvn_build # 同一时间只会有一个
  stage: build
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
    # - if: '$CI_COMMIT_BRANCH == "test" && ($CI_PIPELINE_SOURCE == "merge_request_event" || $CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "web")'  # 允许合并请求和手动触发
  # before_script:
  #   - cat $GLOBAL_NGINX_CA > /usr/local/share/ca-certificates/nnn-nginx-ca.crt # 证书信任
  #   - update-ca-certificates
  script:
    - echo "构建变更模块的 Docker 镜像..."
    - |
      echo "编译 $module..."
      mvn clean package -DskipTests $PACKAGE_ENV -pl $module -am --settings ${CI_PROJECT_DIR}/deploy/ci_settings.xml
  artifacts:
    paths:
      - ./*/target/*.jar
      - ./mate-platform/*/target/*.jar
    exclude:
      - "./*/target/original-*.jar"
      - "./*/target/*-sources.jar"
      - "./*/target/*-javadoc.jar"
      - "./mate-platform/*/target/original-*.jar"
      - "./mate-platform/*/target/*-sources.jar"
      - "./mate-platform/*/target/*-javadoc.jar"
    expire_in: 10m  # 保持 30 分钟,确保后续任务访问

# docker
docker_build:
  stage: build
  image:
    name: registry.dev.scntsc.com/public-repository/public/kaniko-project/executor:v1.9.0-debug
    entrypoint: [""]
  interruptible: true
  resource_group: docker_build # 同一时间只会有一个
  needs: ["mvn_build"]  # 依赖 detect_changes 任务,确保它先执行
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
  script:
    - |
      /kaniko/executor \
      --context "${CI_PROJECT_DIR}/${module}/target" \
      --dockerfile "${CI_PROJECT_DIR}/deploy/${module}/Dockerfile" \
      --destination "${CI_REGISTRY_IMAGE}/${module}:${CI_COMMIT_SHORT_SHA}-1.0" \
      --destination "${CI_REGISTRY_IMAGE}/${module}:latest" \
      --skip-tls-verify

deploy_job:
  stage: deploy
  image: registry.dev.scntsc.com/public-repository/public/curl-jq:latest
  interruptible: true
  resource_group: deploy_job # 同一时间只会有一个
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
  needs:
    - docker_build
  script:
    - echo $K8S_TOKEN
    - module_k=$(echo $module | tr '/' '-')
    - echo $module_k test
    - |
      DEPLOYMENT_NAME="$module_k"
      NEW_IMAGE="${CI_REGISTRY_IMAGE}/${module}:${CI_COMMIT_SHORT_SHA}-1.0"

      echo "更新 $DEPLOYMENT_NAME 的镜像为 $NEW_IMAGE"

      echo "获取现有 Deployment 并修改 image""$K8S_API_SERVER/apis/apps/v1/namespaces/$K8S_NAMESPACE/deployments/$DEPLOYMENT_NAME"
      curl -X GET "$K8S_API_SERVER/apis/apps/v1/namespaces/$K8S_NAMESPACE/deployments/$DEPLOYMENT_NAME" \
        -H "Authorization: Bearer $K8S_TOKEN" -k \
        | jq --arg NEW_IMAGE "$NEW_IMAGE" '.spec.template.spec.containers[0].image = $NEW_IMAGE' \
        > updated-deployment.json

      echo "使用 PATCH 更新 Deployment""$K8S_API_SERVER/apis/apps/v1/namespaces/$K8S_NAMESPACE/deployments/$DEPLOYMENT_NAME"
      curl -X PATCH "$K8S_API_SERVER/apis/apps/v1/namespaces/$K8S_NAMESPACE/deployments/$DEPLOYMENT_NAME" \
        -H "Authorization: Bearer $K8S_TOKEN" \
        -H "Content-Type: application/strategic-merge-patch+json" \
        --data-binary @updated-deployment.json -k

      # echo "验证 $DEPLOYMENT_NAME 是否可用..."
      # until curl -X GET "$K8S_API_SERVER/apis/apps/v1/namespaces/$K8S_NAMESPACE/deployments/$DEPLOYMENT_NAME/status" \
      #   -H "Authorization: Bearer $K8S_TOKEN" -k | grep -q '"availableReplicas":1'; do
      #   echo "等待 $DEPLOYMENT_NAME 启动完成..."
      #   sleep 5
      # done
总结:
  1.用 rules 控制脚本执行的时机
  2.根据流程分为 maven 打包,docker 打包并推送,通知 K8s 部署
  3.通过变量指定打包发布的模块,实现按模块服务部署
  4.按当前分支调整文件中打包的环境,实现各环境自动化部署

PS:
  1.如果默认镜像不合用,可以自建镜像上传到仓库使用,比如如果想合并 maven,docker打包,减少文件传输时间与磁盘占用,可以建一个拥有两者的环境的镜像。
  2.单服务项目可以不必按模块服务部署,rules 直接改为指定分支 merge_request_event 时自动执行,更方便测试人员发包。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注