使用Drone搭建持续集成系统(CI/CD)

 提示:转载请注明原文链接

 本文链接:https://360us.net/article/75.html

使用Drone搭建持续集成系统

  • 持续集成:自动化的测试、编译打包并且自动部署到开发或者测试环境
  • 持续交付:自动化的测试、编译打包生产环境的包,但是不做自动化的生产环境部署,需要手动来做
  • 持续部署:和持续交付的区别就是生产环境的部署也是自动化的。

Drone持续集成系统主要有两部分组成:

  • Drone服务器:这个是用来管理的一个UI界面
  • runner:这个是用来执行构建动作的服务

仓库以国内的Gitee为例子。Drone版本是2。

1、创建仓库访问应用

在自己的Gitee后台创建一个可以访问自己仓库的应用,位置在个人设置-数据管理-第三方应用

gitee_oauth

Gihub和Gitlab也是类似的,创建一个OAuth的应用,方便可以通过这个密钥访问我们的仓库。

create

created

Homepage URL:填写部署Drone的地址,可以是域名也可以是ip

callback URL:认证登陆地址,上面的地址加上/login{{HomePage}}/login

2、创建共享密钥

密钥的用途是Drone服务器和runner之间的通信认证

$ openssl rand -hex 16
bea26a2221fd8090ea38720fc445eca6

3、运行Drone服务器和runner服务

这里用docker-compose来部署。

runner有很多种,docker,k8s,ssh等等,这里我们用docker的形式。

docker:是在docker里面执行pipelines。

k8s:在pod里面执行pipelines。

ssh:通过ssh连接到远程服务器执行pipelines。

exec:直接在主机上执行pipelines。

docker-compose.yml:

version: "3.8"
services:
    drone-server:
        image: drone/drone:2
        container_name: drone-server
        ports:
            - "80:80"
        environment:
            #下面两个是第一步里面的应用id和密钥
            DRONE_GITEE_CLIENT_ID: 65f5c8dee10fd350ae435f1b9c5bce8ff005c71675999ce3b4f24a25626769a3
            DRONE_GITEE_CLIENT_SECRET: 97a08c26b937c4d0d102d232d866f75484d765ac190f4e592e9dfc1b392c3197
            #第二步生成的密钥
            DRONE_RPC_SECRET: 22d01e955af7455295d57c222a793a32
            #服务器地址,在hosts增加一个记录127.0.0.1   drone.com
            #gitee用本地ip激活不了仓库,用一个假域名欺骗一下,这里的域名需要和第一步申请应用里面填写的一样
            DRONE_SERVER_HOST: drone.com #127.0.0.1
            #访问协议,http或者https
            DRONE_SERVER_PROTO: http

    drone-runner:
        image: drone/drone-runner-docker:1
        container_name: drone-runner
        ports:
            - "3000:3000"
        #这个必须有,runner需要连接主机的docker进程
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
        environment:
            #这里是上面drone-server的访问地址,runner通过这个地址和drone-server通信
            #填一个在docker里面能够访问的地址
            DRONE_RPC_HOST: 192.168.55.100
            DRONE_RPC_PROTO: http
            #第二步生成的密钥
            DRONE_RPC_SECRET: 22d01e955af7455295d57c222a793a32

启动和验证:

$ sudo docker-compose up -d

$ sudo docker-compose ps
    Name               Command            State                     Ports                  
-------------------------------------------------------------------------------------------
drone-runner   /bin/drone-runner-docker   Up      0.0.0.0:3000->3000/tcp,:::3000->3000/tcp 
drone-server   /bin/drone-server          Up      443/tcp, 0.0.0.0:80->80/tcp,:::80->80/tcp

$ sudo docker logs drone-server
{"acme":false,"host":"127.0.0.1","level":"info","msg":"starting the http server","port":":80","proto":"http","time":"2022-03-28T15:20:56Z","url":"http://127.0.0.1"}
{"interval":"30m0s","level":"info","msg":"starting the cron scheduler","time":"2022-03-28T15:20:56Z"}
{"interval":"24h0m0s","level":"info","msg":"starting the zombie build reaper","time":"2022-03-28T15:20:56Z"}

#出现successfully pinged the remote server就没问题了
$ sudo docker logs drone-runner
time="2022-03-28T15:20:56Z" level=info msg="starting the server" addr=":3000"
time="2022-03-28T15:20:56Z" level=error msg="cannot ping the remote server" error="Post \"http://192.168.55.100/rpc/v2/ping\": read tcp 172.25.0.2:56074->192.168.55.100:80: read: connection reset by peer"
time="2022-03-28T15:20:57Z" level=info msg="successfully pinged the remote server"
time="2022-03-28T15:20:57Z" level=info msg="polling the remote server" arch=amd64 capacity=2 endpoint="http://192.168.55.100" kind=pipeline os=linux type=docker

运行起来后,浏览器输入http://127.0.0.1就可以访问到了。

image

点击CONTINUE按钮会跳转到gitee的授权页面,授权完之后会跳回来,注册一下。

注册完进去就可以看见我们gitee上面所有的仓库了。

选一个仓库进去,点击激活按钮activate,激活成功后,会在gitee仓库里面添加一个WebHooks,可以到gitee去看看。

webhook

repo_setting

上图setting里面的Secrets可以设置一些敏感的参数,比如密码,密钥那些。

设置好之后可以在pipeline里面用from_secret语法使用。

比如:

steps:
- name: build
  image: node
  environment:
    USERNAME:
      from_secret: username
    PASSWORD:
      from_secret: password
  commands:
  - npm install
  - npm test

- name: publish
  image: plugins/npm
  settings:
    username:
      from_secret: username
    password:
      from_secret: password

4、Docker Pipelines

这一步是配置构建流水线了。

在git仓库根目录添加一个文件.drone.yml,在这里面定义流水线步骤。

kind: pipeline
type: docker #pipeline类型
#pipeline的名字
name: default

#steps是执行构建的步骤,多个step是顺序执行的,任何一个step执行失败,就会终止整个过程
steps:
- name: greeting #step的名字
  image: alpine #
  #docker容器入口(entrypoint)执行的命令,任何一个命令返回非0值,step就会失败
  commands:
  - echo hello
  - echo 

- name: test
  image: golang
  commands:
  - go test
  - go build

完成后提交到仓库,gitee会通过上面注册的webhook发送同志给Drone执行构建。

因为我们是在本地测试的,注册的webhook地址是假的,gitee肯定是通知失败的。

可以点NEW BUILD按钮来手动触发一个构建。

也可以用Cron Job来主动来去定时触发,看上图Drone UI仓库设置的Cron Jobs设置,在里面添加就行。

有预定义一些固定的时间节点,我新建了一个@hourly的任务,这个是每个小时执行一次。

在一个配置文件里面可以设置多个pipeline,他们会在不同的runner并行执行。

kind: pipeline
type: docker
name: backend

steps:
- name: build
  image: golang
  commands:
  - go build
  - go test

---  #这个做为分隔符
kind: pipeline
type: docker
name: frontend

steps:
- name: build
  image: node
  commands:
  - npm install
  - npm test

通过在commands的命令我们可以执行对应用的测试和编译工作,编译完成之后还需要部署到机器上面去运行。

最后的部署运行需要用插件或者自己写脚步实现之后放到pipeline里面去执行。

5、Pipeline常用配置

type: docker为例子

trigger

kind: pipeline
type: docker
name: default

steps:
- name: build
  image: golang
  commands:
  - go build
  - go test

#trigger用来限定pipeline的执行
#限定分支,分支发送pull时触发
trigger:
  branch:
  - master

#多个分支
trigger:
  branch:
    include:
    - master
    - feature/*

#包含语法,等同上面的例子    
trigger:
  branch:
    include:
    - master
    - feature/*

#排除语法    
trigger:
  branch:
    exclude:
    - master
    - feature/*

#通配符匹配
trigger:
  ref:
  - refs/heads/master
  - refs/heads/**
  - refs/pull/*/head

#组合,master分支发生push事件时才触发执行pipeline
trigger:
  branch:
  - master
  event:
  - push

#事件触发器,也一样有上面的include语法和exclude语法
trigger:
  event:
  - cron
  - custom
  - push
  - pull_request
  - tag
  - promote
  - rollback

Steps

Steps是定义的一系列的shell命令,会在git仓库的根目录执行,git仓库的根目录就是执行pipeline的工作目录。

执行pipeline的时候,会创建一个临时卷(完毕之后会删除),每一个step的更改都会持久化到这个卷里面,所有的step之间都是共享的。

例子:

kind: pipeline
type: docker
name: default

steps:
- name: backend
  image: golang
  commands:
  - go build
  - go test

- name: frontend
  image: node
  commands:
  - npm install
  - npm test

commands

构建执行的shell命令,这些命令会覆盖掉docker的entrypoint。

commands也可以写在一个shell脚步文件里面,指定执行这个文件:

#!/bin/sh
set -e #任何语句执行出错时结束程序
set -x #把执行的内容输出来,用来在显示运行结果之前先输出执行的那条命令

go build
go test

environment

在steps范围里面定义环境变量

steps:
- name: backend
  image: golang
  environment:
    GOOS: linux
    GOARCH: amd64
  commands:
  - go build
  - go test

Plugins

Plugins是封装了一些命令的docker容器,可以在流水线共享和重用。

例如发送Slack通知的插件。

- name: notify
  image: plugins/slack
  settings:
    webhook: https://hooks.slack.com/services/...

条件

when设置块可以在运行时限制执行的条件。

steps:
- name: backend
  image: golang
  commands:
  - go build
  - go test
  when:
    branch:
    - master

上面限制了backend这个setp在分支master时才执行。

还有可以使用其他条件,如event, reference, status

Failure

failure属性定制单个step失败的处理方式。

steps:
- name: backend
  image: golang
  failure: ignore
  commands:
  - go build
  - go test

Detach

detach属性让step在后台执行,开始一个step后在后台执行,立即执行下一个step,默认是按顺序执行。

steps:
- name: backend
  image: golang
  detach: true
  commands:
  - go build
  - go test
  - go run main.go -http=:3000

特权模式

privileged在特权模式下运行容器,相当于docker run --privileged

设置了这个属性,容器的root将有权限访问主机的目录。

steps:
- name: backend
  image: golang
  privileged: true
  commands:
  - go build
  - go test
  - go run main.go -http=:3000

Services

Services支持启动单独的服务容器,比如进行一个单元测试的时候依赖一个redis 服务器,那么可以在构建时启动一个redis容器。

kind: pipeline
type: docker
name: default

services:
- name: cache
  image: redis

服务容器可以用容器名称访问,比如上面这个:tcp://cache:6379,可以这样连接redis。

在step里面用detach参数也可以启动服务容器。

kind: pipeline
name: default

steps:
- name: cache
  image: redis
  detach: true  ####

- name: ping
  image: redis
  commands:
  - redis-cli -h cache ping

本文链接:https://360us.net/article/75.html