Gitlab CI/CD 应用
项目下创建.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 时自动执行,更方便测试人员发包。