Drone CI For Github —— 打造自己的CI/CD工作流(一)

fzpying發表於2020-10-01

這一篇文章是基於 Gitea+Drone CI+Vault 打造屬於自己的 CI/CD 工作流系列文章第一篇,我們先來學習一下 Drone 的部署和使用,我們以 Drone + Github 為例來進行部署。

Drone 是一種基於容器技術的持續交付系統。Drone 使用簡單的 YAML 配置檔案(docker-compose 的超集)來定義和執行 Docker 容器中的 Pipelines。

Drone 與流行的原始碼管理系統無縫整合,包括 GitHub,GitHub Enterprise,Bitbucket 等。


讓我們一起開始實踐 Drone 的部署和使用

準備工作

在這裡,我為 Drone Server 使用的域名是 drone.5io.cc

瞭解 Docker-compose

Compose 專案是 Docker 官方的開源專案,負責實現對 Docker 容器叢集的快速編排。

申請一個 Github OAuth Application

Drone CI For Github —— 打造自己的CI/CD工作流(一)

Github OAuth Application 是為了授權 Drone Server 讀取你的 Github 資訊。
記下生成的 Client IDClient Secret

編寫 docker-compose.yml

我們需要

  • drone-server(中央 Drone 伺服器)
  • drone-agent (接收來自中央 Drone 伺服器的指令以執行構建管道)
  • mysqldrone 預設的資料儲存是sqllite3,這裡我們使用 MySQL)
  • nginx (使用 nginx 來做對外的服務代理,不要讓 drone-server 直接對外提供服務)

參考:

version: "3.7"
services:
  nginx:
    image: nginx:alpine
    container_name: drone_nginx
    ports:
      - "80:80"
    restart: always
    networks:
      - dronenet
  mysql:
    image: mysql:5.7
    restart: always
    container_name: drone_mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root_password
      - MYSQL_DATABASE=drone
      - MYSQL_USER=drone
      - MYSQL_PASSWORD=drone_password
    networks:
      - dronenet
    volumes:
      - /path/to/conf/my.cnf:/etc/mysql/my.cnf:rw
      - /path/to/data:/var/lib/mysql/:rw
      - /path/to/logs:/var/log/mysql/:rw
  drone-server:
    image: drone/drone:1.0.0-rc.5 #不要用latest,latest並非穩定版本
    container_name: drone_server
    networks:
      - dronenet
    volumes:
      - ${DRONE_DATA}:/var/lib/drone/:rw
      - /var/run/docker.sock:/var/run/docker.sock:rw
    restart: always
    environment:
      - DRONE_DEBUG=true
      - DRONE_DATABASE_DATASOURCE=drone:drone_password@tcp(drone_mysql:3306)/drone?parseTime=true #mysql配置,要與上邊mysql容器中的配置一致
      - DRONE_DATABASE_DRIVER=mysql
      - DRONE_GITHUB_SERVER=https://github.com
      - DRONE_GITHUB_CLIENT_ID=${Your-Github-Client-Id} #Github Client ID
      - DRONE_GITHUB_CLIENT_SECRET=${Your-Github-Client-Secret} #Github Client Secret
      - DRONE_RUNNER_CAPACITY=2
      - DRONE_RPC_SECRET=YOU_KEY_ALQU2M0KdptXUdTPKcEw #RPC秘鑰
      - DRONE_SERVER_PROTO=http #這個配置決定了你啟用時倉庫中的webhook地址的proto
      - DRONE_SERVER_HOST=drone.5io.cc
      - DRONE_USER_CREATE=username:5io,admin:true #管理員賬號,一般是你github使用者名稱
  drone-agent:
    image: drone/agent:1.0.0-rc.5
    container_name: drone_agent
    restart: always
    networks:
      - dronenet
    depends_on:
      - drone-server #依賴drone_server,並在其後啟動
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:rw
    environment:
      - DRONE_RPC_SERVER=http://drone_server #drone用的http請求包,url一定要寫上協議才能支援
      - DRONE_RPC_SECRET=YOU_KEY_ALQU2M0KdptXUdTPKcEw #RPC秘鑰,要與drone_server中的一致
      - DRONE_DEBUG=true
networks:
  dronenet:

  # 以上為例項參考,請根據實際使用進行修正

執行服務

建立容器和網路

$ docker-compose up -d
Creating drone_mysql      ... done
Creating drone_server ... done
Creating drone_nginx      ... done
Creating drone_agent  ... done
$ docker-compose ps
      Name                   Command             State          Ports
----------------------------------------------------------------------------
drone_mysql        docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp
drone_nginx        nginx -g daemon off;          Up      0.0.0.0:80->80/tcp
drone_agent    /bin/drone-agent              Up
drone_server   /bin/drone-server             Up      443/tcp, 80/tcp

編寫 nginx 配置檔案

$ docker-compose exec nginx ash
# vim /etc/nginx/conf.d/drone.conf
server {
    listen       80;
    server_name drone.5io.cc;
    location / {
        proxy_pass http://drone_server;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
}
# nginx -s reload

訪問服務

先有一個 OAuth 驗證,然後會開始同步你所有的倉庫。

Drone CI For Github —— 打造自己的CI/CD工作流(一)

寫到這裡,Drone CI for Github 就已經搭建成功了,是不是很開心,是不是很滿足?結束了嗎?並沒有!

我們還要測試一下 Drone Server ,測試服務的可用性。

說幹就幹,開搞。

驗證服務

沒有經過實踐的專案不是可用的專案

建立空倉庫,並同步到 Drone 啟用

倉庫怎麼建立就不再贅述,在這裡,我建立一個名為 drone 的倉庫,並回到 Drone 同步倉庫

  1. 同步倉庫
    Drone CI For Github —— 打造自己的CI/CD工作流(一)
  2. 啟用倉庫

    啟用以後,檢查一下 GIthub 倉庫的 Webhooks

Drone CI For Github —— 打造自己的CI/CD工作流(一)
Drone CI For Github —— 打造自己的CI/CD工作流(一)

  1. 新增 Secrets

在這裡我建立了兩個 Secret
name: 5io.cc
word: Hello World!

Drone CI For Github —— 打造自己的CI/CD工作流(一)

編寫 .drone.yml

這裡由於伺服器配置是敏感資訊,我們需要用到Secret來儲存

事先建立好登陸部署伺服器所需要的 host username rsa port 以及要部署的路徑deploy_path

參考

---
kind: pipeline
name: drone

workspace:
  base: /app
  path: git/drone

steps:
  - name: build
    image: node:alpine
    volumes:
      - name: webroot
        path: /wwwroot
    commands:
      - /bin/sh bash.sh
    environment:
      host:
        from_secret: host
      port:
        from_secret: port
      abc: abctest
  - name: deploy
    image: appleboy/drone-scp
    when:
      status:
        - success
    settings:
      host:
        from_secret: host
      port:
        from_secret: port
      key:
        from_secret: rsa
      username:
        from_secret: username
      target:
        from_secret: deploy_path
      source: ./*

volumes:
  - name: webroot
    host:
      path: /opt
  - name: cache
    host:
      path: /tmp/cache

trigger:
  branch:
    - master
  event:
    - push

編寫 bash.sh 列印變數

推到倉庫,檢視效果

  1. push to repo
    git init
    git add .
    git commit -m 'init test'
    git remote add origin git@github.com:fynntang/drone.git
    git push -u origin master
  2. 檢視 Drone 的 ACTIVITY FEED

    如果成功就會如下圖所示

Drone CI For Github —— 打造自己的CI/CD工作流(一)

如果失敗,會有錯誤資訊

這裡是由於我用的 node 映象是 node:alpine ,沒有 bash

Drone CI For Github —— 打造自己的CI/CD工作流(一)

  1. 去伺服器檢查一下

    看到 bash.sh.drone.yml 都被上傳到這裡(只是測試,不是真的讓你這麼幹)

$ pwd
/home/www
$ ll -a
total 40
drwx------  4 www  www  4096 Feb 20 04:23 .
drwxr-xr-x. 4 root root 4096 Feb 20 03:55 ..
-rw-------  1 www  www    61 Feb 19 03:00 .bash_history
-rw-r--r--  1 www  www    18 Oct 30 13:07 .bash_logout
-rw-r--r--  1 www  www   193 Oct 30 13:07 .bash_profile
-rw-r--r--  1 www  www   231 Oct 30 13:07 .bashrc
-rw-r--r--  1 www  www    35 Feb 20 04:23 bash.sh
-rw-r--r--  1 www  www   812 Feb 20 04:23 .drone.yml
drwxr-xr-x  8 www  www  4096 Feb 20 04:23 .git
drwxr-xr-x  2 www  www  4096 Feb 19 02:40 .ssh

總結

Drone CI for Github 的部署到此就真的結束了,一路走來,踩了不少坑,Drone 的文件你慢慢看了以後就會發現有多爛,爛到心累想哭,許多在 Demo 中出現的變數在參考手冊中找不到,完全不知道什麼含義,只能靠瞎猜和摸索。

總結犯過的錯誤和坑

  • yaml 格式的檔案字尾是 yml (我智障)
  • drone-server 一定要設定一個管理員
  • drone-server 中的變數 DRONE_SERVER_PROTODRONE_SERVER_HOST 決定了你倉庫中 webhook 的地址,如果你的域名做了 http to https ,而且你的DRONE_SERVER_PROTOhttp,將會產生 301 重定向,methodpost 轉成 get,會發生error 405
  • drone 是用 GO 語言開發的,drone 使用的http 包,不支援沒寫協議的 url,例如 drone.5io.cc 不能被識別,要寫成 http(s)://drone.5io.cc
  • 建議測試階段開啟 debug,方便部署和除錯

系列文章

不說了,我去調整心態了並生產 BUG 了。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章