diff --git a/docs/ci-cd/integration/README.md b/docs/ci-cd/integration/README.md index 3eac3b7..4821678 100644 --- a/docs/ci-cd/integration/README.md +++ b/docs/ci-cd/integration/README.md @@ -1,51 +1,54 @@ # 集成 -Security Cloud 采用前后端分离试开发,后端为Spring Cloud 体系架构,前端现有React,后期会继续更新Vue3.0版本前端页面 +Security Cloud 采用前后端分离试开发,后端为Spring Cloud 体系架构,前端现有React,后期会继续更新Vue3.0版本前端页面 ## gitea + drone 集成 -在安装drone的时候可知,drone需要获取到gitea的oauth2的授权,这样drone就可以通过携带秘钥信息去请求到gitea当前用户下的所有仓库了 +在安装drone的时候可知,drone需要获取到gitea的oauth2的授权,这样drone就可以通过携带秘钥信息去请求到gitea当前用户下的所有仓库了 -当gitea中的仓库有request的时候,gitea会发送一个Web沟子请求到drone +当gitea中的仓库有request的时候,gitea会发送一个Web沟子请求到drone ![webhook.png](./webhook.png) -请求内容中就会包括到当前提交的相关信息,drone就可以拿到这些信息获取到gitea仓库中的最新代码 +请求内容中就会包括到当前提交的相关信息,drone就可以拿到这些信息获取到gitea仓库中的最新代码 ## drone + k8s(rancher) -drone触发k8s是非常简单的,需要准备一个带有kubectl命令行工具的docker镜像,当drone的steps运行到了这一步了之后,只需要使用命令行工具运行: +drone触发k8s是非常简单的,需要准备一个带有kubectl命令行工具的docker镜像,当drone的steps运行到了这一步了之后,只需要使用命令行工具运行: ```shell kubectl apply -f deployment.yml -n dev --kubeconfig=/app/config/kubectl_conf.yml ``` -其中 kubectl_conf.yml 则是k8s的连接配置文件,deployment.yml文件则是需要构建内容的配置文件 +其中 kubectl_conf.yml 则是k8s的连接配置文件,deployment.yml文件则是需要构建内容的配置文件 -当命令成功运行后,即可在k8s中看到新构建的内容,但是现在看来drone只是触发了k8s的构建,但是k8s构建所需要的docker镜像现在还未知,在docker中有一种叫做docker镜像仓库的存在,我们制作好的docker镜像就可以推送到镜像仓库中,并将仓库中对应的docker pull路径放到deployment.yml文件中,可以由k8s pull下来。 +当命令成功运行后,即可在k8s中看到新构建的内容,但是现在看来drone只是触发了k8s的构建,但是k8s构建所需要的docker镜像现在还未知,在docker中有一种叫做docker镜像仓库的存在,我们制作好的docker镜像就可以推送到镜像仓库中,并将仓库中对应的docker pull路径放到deployment.yml文件中,可以由k8s pull下来。 ## Harbor Harbor是一个docker的镜像仓库,他可以独立部署,在drone和k8s中当做粘合剂,当drone中构建好了对应docker镜像后,将docker镜像推送到harbor,然后将pull 的路径又放到k8s的deployment.yml文件中,这样全链路就打通了。 +为了方便区分每一次drone提交的docker镜像都是不同的,并且在k8s的机制中,如果你的pull 地址完全相同,k8s认为你没有对镜像进行更新,所以需要一个随机的变量,那么在gitea中存在一个值叫做commit id,这个值是每一次提交的唯一标识符,所以也可以作为区分镜像版本的变量。 + + ## 前端 -在前端项目中,有这 +在前端项目中,有这 ``` .drone.yml -- drone ci/cd管道配置命令 deployment.yml -- k8s部署文件 default.conf -- Nginx的映射配置文件 Dockerfile -- 将前端的打包内容构建docker镜像的文件 - docker.sh -- 进行docker打包,并且按照约定格式推送到Harbor仓库 + docker.sh -- 进行docker打包,并且按照约定格式推送到Harbor仓库 .dockerignore -- docker的ignore文件 ``` -## .drone.yml文件内容详情 +### .drone.yml文件内容详情 ```yaml kind: pipeline # drone配置文件类型 pipeline管道 -type: docker # 使用对应steps对应的类型,drone是基于docker容器进行每一个步骤的 +type: docker # 使用对应steps对应的类型,drone是基于docker容器进行每一个步骤的 name: security-react # 本次构建任务的名称 steps: - name: build-package-react # 当前steps的名称 - image: node:16.18.0 # 需要使用到的镜像,与react项目中packjson中配置的node版本一致 + image: node:16.18.0 # 需要使用到的镜像,与react项目中packjson中配置的node版本一致 volumes: # 将容器内容部的地址映射到宿主机上 - - name: cache # node构建是的缓存,防止多次下载,提高build速度 + - name: cache # node构建是的缓存,防止多次下载,提高build速度 path: /drone/src/node_modules - - name: build # 内容挂在,将打包的好产物放到当前目录下,方便后续steps的时候 + - name: build # 内容挂在,将打包的好产物放到当前目录下,方便后续steps的时候 path: /app/build commands: # 容器中需要执行的命令 - export CI=false @@ -60,7 +63,7 @@ steps: - export NODE_MODULES_PATH=`pwd`/node_modules # 构建与缓存目录之间的关联 # - npm config set registry https://registry.npm.taobao.org # 可以开启淘宝npm的镜像加速 # - set NODE_OPTIONS=--openssl-legacy-provider - - npm install # 下载依赖,虽然已经进行了依赖的缓存,但是一旦有新的依赖加入,缓存中没有则无法构建,所以还需要install一下 + - npm install # 下载依赖,虽然已经进行了依赖的缓存,但是一旦有新的依赖加入,缓存中没有则无法构建,所以还需要install一下 - npm run build # 开始构建产物 - mkdir -p /app/build/react # 创建存放产物的映射目录 - cp -r build /app/build/react # 将打包好之后的内容放入的对应的目录中 @@ -92,15 +95,15 @@ steps: - sed -i 's/$REGISTRY_NAMESPACE/'"$REGISTRY_NAMESPACE"'/' deployment.yml - sed -i 's/$DRONE_REPO_NAME/'"$DRONE_REPO_NAME"'/' deployment.yml - sed -i 's/$DRONE_COMMIT/'"$DRONE_COMMIT"'/' deployment.yml - # docker登录,不能在脚本中登录,并且不能使用docker login -u -p + # docker登录,不能在脚本中登录,并且不能使用docker login -u -p - echo $DOCKER_PASSWORD | docker login $REGISTRY --username $DOCKER_USERNAME --password-stdin - chmod +x docker.sh - sh docker.sh # 运行docker打包脚本 - # 执行完脚本删除本次制作的docker镜像,避免多次后当前runner空间不足 + # 执行完脚本删除本次制作的docker镜像,避免多次后当前runner空间不足 - docker rmi -f $(docker images | grep $DRONE_REPO_NAME | awk '{print $3}') - name: drone-rancher # rancher运行 - image: registry.cn-hangzhou.aliyuncs.com/claywang/kubectl #阿里云的kubectl镜像,里面包含kubectl命令行工具 + image: registry.cn-hangzhou.aliyuncs.com/claywang/kubectl #阿里云的kubectl镜像,里面包含kubectl命令行工具 volumes: # 将容器内目录挂载到宿主机 - name: build path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 @@ -110,7 +113,7 @@ steps: - cd /app/build/react/ # 将deployment中定义的变量替换为drone中的内置变量 - cat deployment.yml - # 通过kubectl指令运行deployment.yml,并指定授权文件kubectl_conf.yml + # 通过kubectl指令运行deployment.yml,并指定授权文件kubectl_conf.yml - kubectl apply -f deployment.yml -n dev --kubeconfig=/app/config/kubectl_conf.yml @@ -132,6 +135,165 @@ volumes: path: /var/run/docker.sock ``` +## 后端 +后端采用的为maven聚合工程,情况要比前端负责一些,下面是后端聚合工程的模块划分: +```lua +security-cloud +├── auth -- 授权服务模块 +├── gateway -- 网关服务模块 +└── common -- 系统公共模块 + ├── common-core -- 公共工具类核心包 + ├── common-mybatis -- mybatis 扩展封装 + ├── common-security -- 安全工具类 + ├── common-swagger -- 接口文档 + ├── common-feign -- feign 扩展封装 + └── common-log -- 系统日志记录 +└── upms -- 通用用户权限管理模块 + └── upms-api -- 通用用户权限管理系统公共api模块 + └── upms-biz -- 通用用户权限管理系统业务处理模块[4000] +└── visual -- 图形化管理模块 + └── monitor -- 服务监控 + └── codegen -- 图形化代码生成 +``` + +现阶段需要进行ci/cd构建的模块有 auth(授权服务模块) ,umps-biz(通用用户权限管理系统业务处理模块) ,gateway(网关服务模块);在这样的前提下,后端就不能同前端一样,一个.drone.yml文件只是服务于单独的一个镜像构建打包了,在后端的情况下则需要通过其他方式来区分每一个模块,并对每一个模块进行从打包构建到发布的全部流程;所以ci/cd配置难度将加大。 + +在整个ci/cd活动中唯一能够区分他们并且能够伴随到整个ci/cd流程的只有分支名称,所以通过分支名称作为他们的发布名称,比如auth(授权服务模块)的发布名称就叫做auth,同时项目的jar包名称,以及后续的docker镜像名称,还有k8s的发布名称都需要统一; + +在drone中用于储存分支名称的变量为$DRONE_COMMIT_BRANCH 需要了解其他drone变量则可以前往 [Drone内置变量](https://blog.odliken.cn/2022/08/06/drone%e5%86%85%e7%bd%ae%e5%8f%98%e9%87%8f/) + +在编写ci/cd的过程中,则使用该变量贯穿整个ci/cd的流程,配合commit id实现区分不同的版本。 + +并且在获取分支的时候,直接cd $DRONE_COMMIT_BRANCH即可进入到对应模块下,然后找到target下$DRONE_COMMIT_BRANCH.jar,就可以将这个jar包放到构建的缓存路径下,进行下一步的操作了。 + +## 模块下的模块构建方式 +上方的结构图中出现了umps-biz模块,这个模块是在umps下方,他的分支名应该是什么呢? + +当前模块的分支名当然是umps-biz,但是cd $DRONE_COMMIT_BRANCH的时候,真正的运行命令则是 cd umps-biz,在项目路径中没有当前的路径,所以这是我们需要使用到drone的when 关键词区分分支名称,分支为umps-biz的时候,我们需要将cd $DRONE_COMMIT_BRANCH 改为cd umps/当前模块的分支名当然是umps-biz,但是cd $DRONE_COMMIT_BRANCH的时候,真正的运行命令则是 cd umps-biz,在项目路径中没有当前的路径,所以这是我们需要使用到drone的when 关键词区分分支名称,分支为umps-biz的时候,我们需要将cd $DRONE_COMMIT_BRANCH 改为$DRONE_COMMIT_BRANCH,这样就可以继续完成下面的steps了 + +## .drone.yml文件详细 +```yaml +kind: pipeline +type: docker +name: security-cloud +steps: + - name: build-jar # 流水线名称 + image: maven:3.8.5-openjdk-8 # 定义创建容器的Docker镜像,maven:3.8.5-openjdk-8用于对java进行打包使用 + volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置 + - name: maven-cache + path: /root/.m2 # 将maven下载依赖的目录挂载出来,防止重复下载 + - name: maven-build + path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 + commands: # 定义在Docker容器中执行的shell命令 + - rm -rf /app/build/* + - mvn clean package -DskipTests=true # 应用打包命 + - cp start.sh /app/build/ # java包的启动脚本 + - cp Dockerfile /app/build/ # docker镜像打包时的文件 + - cp deployment.yml /app/build/ # k8s部署文件 + - cp .dockerignore /app/build/ # docker镜像打包时过滤文件 + - cp docker.sh /app/build/ # docker 镜像打包脚本 + - cd $DRONE_COMMIT_BRANCH + - cp target/$DRONE_COMMIT_BRANCH.jar /app/build/$DRONE_COMMIT_BRANCH.jar # 将打包后的内容复制到挂载目录下 + when: + branch: + - gateway + - auth + + - name: build-jar-umps-biz # 流水线名称 + image: maven:3.8.5-openjdk-8 # 定义创建容器的Docker镜像,maven:3.8.5-openjdk-8用于对java进行打包使用 + volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置 + - name: maven-cache + path: /root/.m2 # 将maven下载依赖的目录挂载出来,防止重复下载 + - name: maven-build + path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 + commands: # 定义在Docker容器中执行的shell命令 + - rm -rf /app/build/* + - mvn clean package -DskipTests=true # 应用打包命 + - cp start.sh /app/build/ # java包的启动脚本 + - cp Dockerfile /app/build/ # docker镜像打包时的文件 + - cp deployment.yml /app/build/ # k8s部署文件 + - cp .dockerignore /app/build/ # docker镜像打包时过滤文件 + - cp docker.sh /app/build/ # docker 镜像打包脚本 + - cd umps/$DRONE_COMMIT_BRANCH + - cp target/$DRONE_COMMIT_BRANCH.jar /app/build/$DRONE_COMMIT_BRANCH.jar # 将打包后的内容复制到挂载目录下 + when: + branch: + - umps-biz + + + + - name: build-docker # 制作docker镜像 + image: docker # 使用官方docker镜像 + volumes: # 将容器内目录挂载到宿主机 + - name: maven-build + path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 + - name: docker + path: /var/run/docker.sock # 挂载宿主机的docker + environment: # 获取到密文的docker用户名和密码 + DOCKER_USERNAME: + from_secret: docker_username + DOCKER_PASSWORD: + from_secret: docker_password + REGISTRY: + from_secret: registry + REGISTRY_NAMESPACE: + from_secret: registry_namespace + commands: # 定义在Docker容器中执行的shell命令 + - cd /app/build + - sed -i 's/$REGISTRY/'"$REGISTRY"'/' deployment.yml + - sed -i 's/$REGISTRY_NAMESPACE/'"$REGISTRY_NAMESPACE"'/' deployment.yml + - sed -i 's/$DRONE_COMMIT_BRANCH/'"$DRONE_COMMIT_BRANCH"'/' start.sh + - sed -i 's/$DRONE_COMMIT_BRANCH/'"$DRONE_COMMIT_BRANCH"'/' Dockerfile + - sed -i 's/$DRONE_COMMIT_BRANCH/'"$DRONE_COMMIT_BRANCH"'/' .dockerignore + - sed -i 's/$DRONE_COMMIT_BRANCH/'"$DRONE_COMMIT_BRANCH"'/' deployment.yml + - sed -i 's/$DRONE_COMMIT/'"$DRONE_COMMIT"'/' deployment.yml + # docker登录,不能在脚本中登录,并且不能使用docker login -u -p + - cat Dockerfile + - echo $DOCKER_PASSWORD | docker login $REGISTRY --username $DOCKER_USERNAME --password-stdin + - chmod +x docker.sh + - sh docker.sh + # 执行完脚本删除本次制作的docker镜像,避免多次后当前runner空间不足 + - docker rmi -f $(docker images | grep $DRONE_COMMIT_BRANCH | awk '{print $3}') + + + - name: drone-rancher # rancher运行 + image: registry.cn-hangzhou.aliyuncs.com/claywang/kubectl #阿里云的kubectl镜像,里面包含kubectl命令行工具 + volumes: # 将容器内目录挂载到宿主机 + - name: maven-build + path: /app/build # 将应用打包好的Jar和执行脚本挂载出来 + - name: config + path: /app/config # 将kubectl 配置文件挂载出来 + commands: # 定义在Docker容器中执行的shell命令 + - cd /app/build + # 通过kubectl指令运行deployment.yml,并指定授权文件kubectl_conf.yml + # - kubectl apply -f deployment.yml -n $DRONE_COMMIT_BRANCH --kubeconfig=/app/config/kubectl_conf.yml + - kubectl apply -f deployment.yml -n dev --kubeconfig=/app/config/kubectl_conf.yml + + + +volumes: # 定义流水线挂载目录,用于共享数据 + - name: maven-build # maven打包后的文件 + host: + path: /home/data/maven/build # 从宿主机中挂载的目录 + - name: config # k8s对接的配置文件 + host: + path: /.kube/config + - name: maven-cache # maven的缓存文件 + host: + path: /home/data/maven/cache + - name: docker # 宿主机中的docker + host: + path: /var/run/docker.sock +# 定义触发条件 +trigger: + branch: + - gateway + - auth + - umps-biz + event: + - push +``` +