目录
- 一、简介
- 二、基础操作
- 第一步:登录Gitee,创建应用
- 第二步:创建Drone的docker-compose启动配置文件:docker-compose.yml,并启动容器
- 第三步:登录Drone管理页面
- 第四步:Gitee上新建仓库,创建SpingBoot项目并提交到仓库
- 第五步:配置文件 .drone.yml ,演示流水线操作
- 第六步:演示Spring Boot项目的自动化测试部署
- 三、问题汇总
- 参考
一、简介
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 -adrone-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 Repositorycommit
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_IP 和 TEST_SERVER_PASSWORD,分别是服务器的 ip 和 密码。为了防止信息泄露,我们需要配置到 Secret中。
在Drone主页中,选择对应项目的Settings下Secrets:New SECRET
编写 .drone.yml
流水线name: ssh,引入了appleboy/drone-ssh镜像,同时配置了刚刚设置的TEST_SERVER_IP 和 TEST_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还有一些功能未实际操作,在日后使用中不断学习。