【Tools】Drone + Gitee:以SpringBoot项目为例,实现自动化软件构建和测试,CI/CD 持续集成/持续部署

一、简介

CI/CD 持续集成/持续部署,自动化部署是应用开发阶段频繁向客户交付应用的方法,熟悉的集成工具有Jenkins、Github Actions、Gitee Go等,感兴趣的都可以去了解学习,本文讲述的是另一集成工具Drone 。相对于常见的Jenkins,Drone更加简洁,不像Jenkins那样复杂,同时它拥有可以满足基本需求的能力,并且提供了许多实用的插件。

Drone 是一个基于Docker容器技术的可扩展的持续集成引擎,由GO语言编写,它是一款更轻量级的持续集成工具!通过使用简单的配置文件,用户将代码推送到Git仓库中,即可自动化完成编译、测试和发布。

Drone与多个源代码管理系统无缝集成,包括GitHub, GitHubEnterprise, Bitbucket和GitLab;
Drone本机支持多种操作系统和架构,包括Linux x64、ARM、ARM64和Windows x64。
Drone可以与Docker容器中运行的任何语言、数据库或服务一起工作。从数千个公共Docker映像中进行选择或提供您自己的映像。

官网
Git地址

二、基础操作

针对不同代码管理平台,官方提供了基础的安装指南。此处以Gitee为例,进行操作演示。

第一步:登录Gitee,创建应用

登录Gitee,在选择设置——第三方应用在这里插入图片描述
点击创建应用
在这里插入图片描述
填写基础信息:

  • 应用主页:服务器地址 + 端口号
  • 应用回调地址:服务器地址 + 端口号/login
  • 权限选择:对应勾选四个在这里插入图片描述

点击创建应用,生成Client ID、Client Secret
在这里插入图片描述
随机生成RPC密钥 ,可以使用 openssl 命令生成,用于后面的配置文件,提供 drone-server和 drone-runner通信使用。
在这里插入图片描述

第二步:创建Drone的docker-compose启动配置文件:docker-compose.yml,并启动容器

编写Drone的docker启动文件docker-compose.yml,并修改以下的内容

  • ports
  • DRONE_GITEE_CLIENT_ID
  • DRONE_GITEE_CLIENT_SECRET
  • DRONE_SERVER_HOST
  • DRONE_USER_CREATE
  • DRONE_RPC_HOST
  • DRONE_RPC_SECRET
version: '3'
networks:
  lf:
    external: false
services:
  # 容器名称
  drone-server:
    container_name: drone
    # 构建所使用的镜像
    image: drone/drone
    # 映射容器内80端口到宿主机的10000端口,若修改的话,那么对应上面Gitee创建应用时也需要进行修改
    ports:
      - 10000:80
    # 映射容器内/data目录到宿主机的目录
    volumes:
      - /usr/local/bin/drone:/data
    # 容器随docker自动启动
    restart: always
    privileged: true
    networks:
      - lf
    environment:
      # Gitee 服务器地址,如果github就把GITEE改成GITHUB,https://gitee.com改成https://github.com
      - DRONE_GITEE_SERVER=https://gitee.com
      # Gitee OAuth2客户端ID
      # - DRONE_GITEA_CLI(上面的Client ID值)
      -DRONE_GITEE_CLIENT_ID=a7bad537638df3f3fb6b21f0f58df5c38dfdff0d5272c4096f7504a28dc8ee61 
      # Gitee OAuth2客户端密钥(上面的Client Secret值)
      - DRONE_GITEE_CLIENT_SECRET=ee51f7b62bc4c905197f5aa936eda3b46b39b0e8307e163814698fed39b64be3
      # drone的共享密钥(上面生成的rpc密钥)
      - DRONE_RPC_SECRET=f6ffe9e4a7999551c9cd933c638e95e5
      # drone的主机名(改成自己的域名或ip+端口(注意是droe的))
      - DRONE_SERVER_HOST=111.231.143.100:10000
      # 外部协议方案根据你的域名判断是http还是https(ip加端口是http)
      - DRONE_SERVER_PROTO=http
      - DRONE_GIT_ALWAYS_AUTH=false
      # 创建管理员账户,这里对应为gitee的用户名(也就是登录的账号,不是昵称)(填错了会导致自动化部署失败)
      - DRONE_USER_CREATE=username:lingfei93,admin:true

  docker-runner:
    container_name: drone-runner
    image: drone/drone-runner-docker
    restart: always
    privileged: true
    networks:
      - lf
    depends_on:
      - drone-server
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /sync/drone/agent/drone.key:/root/drone.key
    environment:
      # 用于连接到Drone服务器的协议。该值必须是http或https。(同上)
      - DRONE_RPC_PROTO=http
      # 用于连接到Drone服务器的主机名(同上)
      - DRONE_RPC_HOST=111.231.143.100:10000
      # Drone服务器进行身份验证的共享密钥,和上面设置一样(上面生成的RPC密钥)
      - DRONE_RPC_SECRET=f6ffe9e4a7999551c9cd933c638e95e5
      # 限制运行程序可以执行的并发管道数
      - DRONE_RUNNER_CAPACITY=2 
      - DRONE_RUNNER_NAME=docker-runner # docker runner 名称
      - DRONE_DEBUG=true # 调试相关,部署的时候建议先打开
      - DRONE_LOGS_DEBUG=true # 调试相关,部署的时候建议先打开
      - DRONE_LOGS_TRACE=true # 调试相关,部署的时候建议先打开
      - TZ=Asia/Shanghai

将 docker-compose.yml 文件拷贝到服务器上,运行命令:
docker-compose -f docker-compose.yml up -d
查看刚刚运行的容器
docker ps -a在这里插入图片描述
drone-server:它是一个守护进程应用并且拥有Web管理界面。它通过Webhook对接Git Server。解析Git Repository根目录下的.drone.yml文件,并以轮询的形态查找需要执行的Pipelines,路由并管理Runners。
drone-runner:Drone Pipeline处理执行器,一个单独的守护进程,会轮询 Server,获取需要执行的流水线任务,之后执行。Drone拥有多种类型的Runner(docker、k8s、exe、ssh等等)。

第三步:登录Drone管理页面

登录,输入上面配置访问URL,点击 Continue在这里插入图片描述
跳转到 Gitee 的 OAuth 授权页面,点击 同意授权
在这里插入图片描述
授权成功后,跳转到 Drone 的主页,在这里能够看到 Gitee 上全部的项目
在这里插入图片描述

第四步:Gitee上新建仓库,创建SpingBoot项目并提交到仓库

在Gitee上创建一个仓库
在这里插入图片描述
使用IDEA 创建Maven项目
在这里插入图片描述

项目依赖配置 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>TestDrone</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>

        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

创建启动类App
在这里插入图片描述
项目接口:8088
在这里插入图片描述

创建演示接口:/drone
在这里插入图片描述
测试接口
在这里插入图片描述
提交项目到仓库

可以使用命令行提交,此处使用了IDEA操作:
Create Git Repository
在这里插入图片描述
commit
在这里插入图片描述
push,设置远程仓库URL
在这里插入图片描述
推送成功后即可看到代码成功推送到 Gitee 上了

在Drone主页,选择刚刚提交的项目

Drone主页同步之后,Drone主页中的仓库列表便会显示刚刚推送的项目,点击该项目之后,展示如下页面。(此处可能存在bug,可在下面的问题汇总中查看)
在这里插入图片描述

第五步:配置文件 .drone.yml ,演示流水线操作

在项目根目录创建 .drone.yml ,并提交到仓库 commit push
在这里插入图片描述

.drone.yml :

kind: pipeline  # kind 属性定义了对象的种类。此示例定义了一个管道对象。
type: docker    # type 属性定义管道的类型。此示例定义了一个 Docker 管道,其中每个管道步骤都在 Docker 容器内执行。
name: default   # name 属性定义了管道的名称。您可以为您的项目定义一个或多个管道

steps: # 步骤部分定义了一系列串行执行的管道步骤。如果管道中的任何步骤失败,管道将立即退出
  - name: greeting # name 属性定义管道步骤的名称
    image: alpine # image 属性定义了一个执行 shell 命令的 Docker 镜像。您可以使用来自任何 DockerHub 中的任何 Docker镜像。
    commands: # commands 属性将在 Docker 容器内执行的 shell 命令列表定义为容器入口点。如果任何命令返回非零退出代码,则管道步骤将失败。
      - echo hello
      - echo world

Drone主页,选择对应项目,点击激活操作:
在这里插入图片描述
Project Settings处选项,如下图:
在这里插入图片描述
Builds操作:
在这里插入图片描述
点击Create,创建完成后,项目就会进行流水线构建:
在这里插入图片描述
构建记录,点击记录详情页,可以看到打印出来的 hello world:
在这里插入图片描述

更多流水线操作演示1:

例如,我们可以将两个步骤串连起来,第一个步骤输出 hello world、第一个输出 bonjour monde

.drone.yml :

kind: pipeline
type: docker
name: greeting

steps:
  - name: en
    image: alpine
    commands:
      - echo hello world

  - name: fr
    image: alpine
    commands:
      - echo bonjour monde

提交推送代码后,就可以看到流水线已经正常输出内容:
在这里插入图片描述

更多流水线操作演示2:

同时,我们也可以定义多个管道,串联的去执行

.drone.yml :

kind: pipeline
type: docker
name: en

steps:
  - name: greeting
    image: alpine
    commands:
      - echo hello world

---
kind: pipeline
type: docker
name: fr

steps:
  - name: greeting
    image: alpine
    commands:
      - echo bonjour monde

提交推送代码后,就可以看到流水线已经正常输出内容:
在这里插入图片描述

同时,通过增加 trigger 可以设置管道触发的方式,例如,push:代码提交后触发,pull_request:代码PR后触发

kind: pipeline
type: docker
name: en

steps:
- name: greeting
  image: alpine
  commands:
  - echo hello world

trigger:
  event:
  - push
  - pull_request 
  - tag
  - promote
  - rollback

第六步:演示Spring Boot项目的自动化测试部署

编辑 .drone.yml 文件,编写流水线代码:

kind: pipeline # 定义对象类型,还有secret和signature两种类型
type: docker # 定义流水线类型,还有kubernetes、exec、ssh等类型
name: test_drone # 定义流水线名称

steps: # 定义流水线执行步骤,这些步骤将顺序执行
  - name: build-package # 流水线名称
    image: maven:3.8.5-openjdk-8 # 定义创建容器的Docker镜像
    volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置
      - name: maven-build
        path: /root/testDrone # 将应用打包好的Jar和执行脚本挂载出来
    commands:
      - $MAVEN_HOME/bin/mvn -v
      - $MAVEN_HOME/bin/mvn clean package -DskipTests=true
      # 将打包后的jar包,拷贝到 /root/testDrone 目录
      - cp target/*.jar  /root/testDrone


volumes: # 定义流水线挂载目录,用于共享数据
  - name: maven-build
    host:
      path: /root/testDrone   #jar包目录可以修改从宿主机中挂载的目录

提交推送代码后,就可以看到流水线已经正常输出内容:
在这里插入图片描述
执行成功后,我们打开自己的服务器,在 /root/testDrone 目录,就可以看到刚刚打包后的 jar 包
在这里插入图片描述
如果你服务器有 java 环境,可以直接用下面的命令启动:
java -jar TestDrone-1.0-SNAPSHOT.jar

继续编辑 .drone.yml 文件

首先在项目的根目录,创建项目的 Dockerfile 文件,Dockerfile的主要作用是用来构建镜像, 存放位置如下所示,主要拉取了带着 jdk8 环境的镜像,然后设置启动参数。

在这里插入图片描述
Dockerfile:

FROM registry.cn-shenzhen.aliyuncs.com/mogu-zh/jdk:8-mogu-alpine
ENV LANG C.UTF-8
ENV TZ Asia/Shanghai
VOLUME /tmp
ADD TestDrone-1.0-SNAPSHOT.jar TestDrone-1.0-SNAPSHOT.jar
ENTRYPOINT ["java","-Xms256m","-Xmx256m","-jar","/TestDrone-1.0-SNAPSHOT.jar"]

继续编写 .drone.yml 文件,这里除了需要拷贝 jar 文件外,还需要把刚刚写的 Dockerfile 文件也拷贝到宿主机上。

同时,需要引入 appleboy/drone-ssh 镜像,用来远程 SSH 连接服务器。

这里有两个变量:TEST_SERVER_IPTEST_SERVER_PASSWORD,分别是服务器的 ip 和 密码。为了防止信息泄露,我们需要配置到 Secret中。

在Drone主页中,选择对应项目的Settings下Secrets:New SECRET
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
编写 .drone.yml

流水线name: ssh,引入了appleboy/drone-ssh镜像,同时配置了刚刚设置的TEST_SERVER_IPTEST_SERVER_PASSWORD两个变量

kind: pipeline # 定义对象类型,还有secret和signature两种类型
type: docker # 定义流水线类型,还有kubernetes、exec、ssh等类型
name: test_drone # 定义流水线名称

steps: # 定义流水线执行步骤,这些步骤将顺序执行
  - name: build-package # 流水线名称
    image: maven:3.8.5-openjdk-8 # 定义创建容器的Docker镜像
    volumes: # 将容器内目录挂载到宿主机,仓库需要开启Trusted设置
      - name: maven-build
        path: /root/testDrone # 将应用打包好的Jar和执行脚本挂载出来
    commands:
      - $MAVEN_HOME/bin/mvn -v
      - $MAVEN_HOME/bin/mvn clean package -DskipTests=true
      # 将打包后的jar包,拷贝到 /root/testDrone 目录
      - cp target/*.jar  /root/testDrone
      # 将Dockerfile拷贝到挂载目录
      - cp Dockerfile /root/testDrone

  - name: ssh
    image: appleboy/drone-ssh
    settings:
      # 你服务器ip地址
      host:
        from_secret: TEST_SERVER_IP
      # 服务器账号
      username: root
      # 密码登入写法
      password:
        from_secret: TEST_SERVER_PASSWORD
      port: 22
      script:
        - cd /root/testDrone
        - ls
        # 使用Dockerfile创建镜像
        - docker build  -t test-drone:latest .
        # 根据name删除容器 防止端口冲突
        - docker rm -f testdrone 
        # 注意接口映射设置
        - docker run --name testdrone -p 8080:8088 -d test-drone:latest

volumes: # 定义流水线挂载目录,用于共享数据
  - name: maven-build
    host:
      path: /root/testDrone   #jar包目录可以修改从宿主机中挂载的目录

核心操作:在 jar 打包完成后,会通过 ssh 进入到我们服务器中,通过 Dockerfile 构建我们的 test-drone 镜像,同时使用 docker run 启动镜像,完成最简单的一个流水线工作。
在这里插入图片描述

提交推送代码后,就可以看到流水线已经正常输出内容,以下是流水线运行成功的截图:
在这里插入图片描述

docker images 命令,即可查看到制作完成的镜像了:
在这里插入图片描述
docker ps -a ,可以看到目前 test-drone 容器正在运行。
docker logs -f 容器ID ,可以看到 test-drone 容器,Spring启动的日志。
在这里插入图片描述

访问接口:请求成功
在这里插入图片描述

测试修改接口并提交代码

我们测试一下:修改接口输出为 HelloWorld!,提交推送代码后,Drone便会自动打包部署:
在这里插入图片描述
在这里插入图片描述
运行成功:
在这里插入图片描述
访问成功:
在这里插入图片描述

PS:Drone 还提供了很多插件,可以打开 https://plugins.drone.io/ 进行学习

三、问题汇总

1.在执行.drone.yml配置文件中的 mvn 命令时,服务器报错:

ls: cannot access '/usr/bin/mvn': Operation not permitted

在这里插入图片描述

此处目前解决方式是:服务器centOS安装maven后,修改完 /etc/profile 配置文件,添加 MAVEN_HOME 参数后(可查看CentOS安装maven教程),在.drone.yml配置文件中,使用 $MAVEN_HOME/bin/mvn 代替 mvn(可见上.drone.yml配置文件)。

2.在Drone主页,选择需要构建流水线的项目时,进入后会出现404:
在这里插入图片描述

此处我修改了一下仓库的名称、路径
在这里插入图片描述
在Drone主页,同步代码后,再次点击后可以了:
在这里插入图片描述

3.Drone 主页,Repository设置项Settings中的Project settings是不显示的:即页面上,下图中红框中的内容是没有的:
在这里插入图片描述

  • Drone Server启动时,配置文件**.drone.yml**指定了DRONE_USER_CREATE参数,用来设置管理员帐号,只有用管理员帐号打开Drone Web界面才可以看到和设置此处。
  • 管理员帐号登录的也可以在主页下方设置权限:
    在这里插入图片描述

4.使用volumes挂host path时报错:

Linter: untrusted repositories cannot mount host volumes

需要给项目开通权限。
打开Drone web –> repository –> Settings –>Project settings 勾选
在这里插入图片描述

5.配置文件.drone.yml文件必须存放在Git仓库 项目的根目录。文件名是可配置的,默认是文件名是.drone.yml。

可以能过Drone Web管理界面修改yml的文件名
在这里插入图片描述

6.提交代码时如何让Drone跳过本次提交,不执行pipeline?

提交代码时通过备注增加[CI SKIP]跳过如:

git commit –m “first commit [CI SKIP]

下图是使用IDEA进行了 [CI SKIP] 的测试:
在这里插入图片描述
push成功后,Drone跳过了本次提交,未执行pipeline。

7.Drone动构建和发布,有时需要好几分钟,而且经常经过长时间的等待后还会发布失败,严重影响到工作效率。

可参考使用缓存插件优化构建速度,待实际操作。

参考

再见了Jenkins,一款更轻量级的持续集成工具!

Drone 的简单学习就到这了,当然Drone还有一些功能未实际操作,在日后使用中不断学习。

猜你喜欢

转载自blog.csdn.net/weixin_42029283/article/details/128658518