​ 在写一个后端的时候,前端的同学需要将接口部署上去。后端还在不断的迭代,因此需要反复编译部署十分麻烦,因此决定将这一套自动化。记录了在使用drone过程中踩的一系列坑。

选型

  • jenkins:war包, 需要java环境,比较吃内存,生态比较完善。
  • drone: go实现,可docker直接运行,文档不够详细。

由于之前Jenkins的不好体验,因此这次选择drone。

drone基本概念

drone由server和runner构成。两者通过rpc交互。

server端为web管理服务,可直接通过docker运行。

runner实际执行工作流的部分。

一个Go程序借助gitee的cicd demo

  1. 所需物料:gitee账号,配置好docker和go编译环境的linux

  2. 配置gitee

    ​ gitee设置–>第三方应用–>创建第三方应用

    应用主页 :linux主机ip,例如: http://xxx.xxx.xxx.xxx(此处使用http而非https,和后续一致)

    应用回调地址 :应用主页地址 + “/login”.例如:http://xxx.xxx.xxx.xxx/login

     **权限** :选择projects,pr,hook必选。
    
  3. 创建一个secret并记录。可使用以下命令:

    $ openssl rand -hex 16

  4. 在gitee中创建好的应用中读取并记录 Client IDClient Secret 以备下步使用

  5. 运行server,此处使用docker方式

# !!!注意替换环境变量
# DRONE_GITEE_CLIENT_ID和DRONE_GITEE_CLIENT_SECRET对应第三步获得的。
# DRONE_RPC_SECRET runner和server交互的secret。任意值,推荐使用第二步生成的值
# DRONE_SERVER_HOST 填写本机公网ip即可
# DRONE_SERVER_PROTO选择 http 以和第一步对应
# DRONE_USER_CREATE需创建超级管理员账号时请添加此环境变量,否则不需要。(trusted仓库时需要,此demo中不需要

docker run \
  --volume=/var/lib/drone:/data \
  --env=DRONE_GITEE_CLIENT_ID=f7018cd1a520c9e6f7eca37b97761de20 \
  --env=DRONE_GITEE_CLIENT_SECRET=8a6bfd074b3c7befe72d5f9647ed02c \
  --env=DRONE_RPC_SECRET=super-duper-secret \
  --env=DRONE_SERVER_HOST=drone.domain.com \
  --env=DRONE_SERVER_PROTO=http \
  --env=DRONE_USER_CREATE=username:hades0,admin:true \
  --publish=80:80 \
  --publish=443:443 \
  --restart=always \
  --detach=true \
  --name=drone \
  drone/drone:2
  1. 运行runner,此处选择Exec Runner即在宿主机上直接执行。

设置配置文件:

# /etc/drone-runner-exec/config
DRONE_RPC_PROTO=http  # 与以上一致
DRONE_RPC_HOST=宿主机ip  #与第四步一致
DRONE_RPC_SECRET=rpc交互secret  #与第四步一致
DRONE_LOG_FILE=/var/log/drone-runner-exec/log.txt  #日志文件路径

创建日志文件对应的目录:

mkdir -p /var/log/drone-runner-exec/

  1. 在web server中配置仓库

在浏览器中访问宿主机IP即可打开server端。

  • 登录gitee
  • 登录账号,如用户名和第四步中的管理员账号相同则为管理员
  • 配置仓库,选择对应仓库并激活。
  1. 在项目中配置工作流( 即*.drone.yml* 文件)

drone会在设置好的触发条件下自动依据项目根目录下的工作流配置文件(默认即.drone.yml文件)完成对应工作流。

此demo完成了一个后端程序的自动部署

#  .drone.yml
kind: pipeline
type: exec
name: pe-backend

platform:
  os: linux
  arch: amd64
# drone会自动按顺序完成以下多个步骤
steps: 
# 首先需要停止原有的后端服务
- name: clean
  commands:
  - bash clean.sh
# 编译新版本
- name: build
  commands:
  - source /etc/profile
  - go build -o pe
  - cp ./pe /root/drone_build_dir/
  - cp ./conf.yaml /root/drone_build_dir/
  environment:
    GOOS: linux
    GOARCH: amd64
    GOPROXY: https://goproxy.cn,direct
# 重新启动新服务
- name: start
  commands:
  - cd /root/drone_build_dir
  - nohup ./pe >> nohup.out 2>&1 &
  - echo "service has started"
  - exit 0
# 触发时机
trigger:
  event:
  - push
# clean.sh,需放置在项目根目录下
#! /bin/bash
#编译后的后端程序进程名字(一般为mod文件中的名字)
PROC_NAME=pe 
# 取得进程对应的pid
ProcNumber=`ps -ef |grep -w $PROC_NAME|grep -v grep|wc -l`
# 进程如果存在在结束掉
if [ $ProcNumber -le 0 ];then
   echo "pe is not run"
else
   echo "pe is  running.."
   kill -9 $(pidof pe)
fi
# 进入相关drone目录下并删除旧项目程序及其配置文件
cd /root/drone_build_dir
rm -f ./pe ./conf.yaml 
# 备份原有日志文件
mv ./nohup.out ./nohup.out_back
echo "clean ok"

这一切完成之后,当你每次向对应仓库中commit新代码时,drone就可以自动完成新版本的构建和运行了。

drone运行原理:

当向仓库提交新代码时,gitee会向drone server监听的url发送请求以触发工作流。server端通过rpc控制runner完成工作流。

tips:

drone server的配置文件默认在**/var/lib/drone** 路径下,以sqllite方式保存。彻底清除相关配置时请删除此文件。

参考: https://docs.drone.io/