1. 程式人生 > 其它 >Drone-比Jenkins更輕量化的持續整合部署工具

Drone-比Jenkins更輕量化的持續整合部署工具

Drone 簡介

Drone 是一個基於Docker容器技術的可擴充套件的持續整合引擎,由GO語言編寫,可用於自動化測試與構建,甚至釋出。每個構建都在一個臨時的Docker容器中執行,使開發人員能夠完全控制其構建環境並保證隔。相對於常見的Jenkins,選中 Drone的原因在於它非常簡潔,不像Jenkins那樣複雜,同時它擁有可以滿足基本需求的能力,並且提供了許多實用的外掛,如GitHubEmail微信釘釘等。

Drone 官方地址:https://www.drone.io/

Drone 開源地址:https://github.com/harness/drone

由於本人是在公司內部伺服器部署的,所以都是使用的HTTP

部署。HTTPS部署詳見另一位大佬的文章:https://www.cnblogs.com/yan7/p/15881087.html

Drone 版本 2.9.1

Gitea 版本 1.17.6

Docker 版本 20.10.12

Harbor 版本 1.10.10

倉庫專案 .NET5

Drone CI-Gitea

Drone官方文件 中支援的Git倉庫有很多種:

本文示例也選用相對Gitlab更輕量化的Gitea,演示Gitea版本為:1.17.6,Gitea部署不是本文重點,請移步其他文章。

建立OAuth2金鑰

登入Gitea後,點選右上角頭像選擇設定(如果沒設定選項,需要管理員許可權

):

然後選擇 應用,在最下面建立OAuth2應用,填寫名稱和重定向URI:

點選建立後,會跳轉到這個頁面,記住 客戶端ID客戶端金鑰,後面部署Drone會用到,客戶端金鑰在退出本頁面時候就會顯示為*,所以尤其需要記住 客戶端金鑰,然後點選儲存。

Docker-Compose部署

Drone 資料儲存預設使用 sqlite 資料庫。並且提供支援 postgresMySql

官方文件中強烈建議使用 postgres 而非 mysql。 某些操作在 mysql 未得到優化。 https://docs.drone.io/server/storage/database/

PS: 支援 postgres9.6 及更高版本 、 mysql:5.6 及更高版本

DockerCompose.yml

# 在執行DockerCompose前,需要建立網路 docker network create drone
version: '3.9'
# 建立自定義網路
networks:
  drone:
    name: drone
    driver: bridge
services:
  # Drone的資料庫服務
  db:
    # 拉取的映象名稱和版本號
    image: postgres:latest
    # 容器名稱
    container_name: drone_db
    # 該容器隨Docker啟動而啟動
    restart: always
    # 加入到drone網路
    networks:
      - drone 
    # 埠對映,左邊宿主機埠:右邊容器內部埠
    ports:
      - '7931:5432'
    environment:
      - POSTGRES_USER=drone # PGSQL預設使用者
      - POSTGRES_PASSWORD=drone # PGSQL預設密碼
      - POSTGRES_DB=drone # PGSQL預設資料庫
    volumes:
      # 資料永續性掛載宿主機 左邊宿主機路徑:右邊容器內路徑
      - /volumes/drone/db:/var/lib/postgresql/data
  # Drone Server 服務
  server:
    image: drone/drone:2.9.1 # 目前drone最新版本為 2.9.1
    container_name: drone_server
    # 該容器隨Docker啟動而啟動
    restart: always
    # 加入到drone網路
    networks:
      - drone 
    # 埠對映,左邊宿主機埠:右邊容器內部埠
    ports:
      - '7929:80'
    environment:
      - DRONE_SERVER_PROTO=http # 訪問協議,建立webHooks和重定向 
      - DRONE_SERVER_HOST=192.168.2.7:7929 # 主機名稱,建立webHooks和重定向
      # 與 drone runner 通訊的金鑰 可以在 伺服器(Linux) 中使用 openssl 生成金鑰 
      - DRONE_RPC_SECRET=e1ad8a7f3dbc68ca9c21bcc949335009 
      # 設定管理員賬戶,username和Gitea賬戶名稱需要一致
      - DRONE_USER_CREATE=username:young,admin:true 
      - DRONE_DATABASE_DRIVER=postgres # 資料庫型別
      - DRONE_DATABASE_DATASOURCE=postgres://drone:drone@db/drone?sslmode=disable # 資料庫連線
      - DRONE_GIT_ALWAYS_AUTH=true # 使用 oauth 身份驗證資訊拉取程式碼
      - DRONE_GITEA_SERVER=http://192.168.2.7:3000 # gitea伺服器地址
      - DRONE_GITEA_CLIENT_ID=2c921d85-e40e-41f8-90e0-c77c383786b5 # gitea 客戶端 id 剛才建立的OAuth2的客戶端Id
      - DRONE_GITEA_CLIENT_SECRET=ZVZoRWK6jR5mqgAIm6sB5VX6C2LPK1sYKv4hQWyTdULu # gitea 客戶端 金鑰 剛才建立的OAuth2的客戶端金鑰
      - DRONE_GITEA_SKIP_VERIFY=false # 禁用 gitea 連結時 tls 驗證

    volumes:
     # 資料永續性掛載宿主機 左邊宿主機路徑:右邊容器內路徑
      - /volumes/drone/server:/data
      - /var/run/docker.sock:/var/run/docker.sock
     # 依賴的容器
    depends_on:
      - db
  # Drone Docker Runner
  runner:
    image: drone/drone-runner-docker:1.8.0 # 目前drone-runner-docker最新版本為 1.8.0
    container_name: drone_runner
    restart: always
    networks:
      - drone # 加入到drone網路
    ports:
      - '7930:3000'
    environment:
      # 名稱
      - DRONE_RUNNER_NAME=docker-runner
      - DRONE_RUNNER_CAPACITY=10 # 限制runner可執行的併發管道數量 預設為2
      - DRONE_RPC_PROTO=http # 訪問drone server 協議
      - DRONE_RPC_HOST=server # 訪問drone server 伺服器地址
      # 與 drone server 通訊的金鑰, 需與上面Server的 DRONE_RPC_SECRET 值相同
      - DRONE_RPC_SECRET=e1ad8a7f3dbc68ca9c21bcc949335009 
      - DRONE_UI_USERNAME=admin # Drone Runner 的 UI 使用者賬號
      - DRONE_UI_PASSWORD=qwe123 # Drone Runner 的 UI 使用者密碼
    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock'
    depends_on:
      - server

將上述儲存,檔名為:drone-docker-compose.yml

docker-compose 執行命令:

docker-compose -f drone-docker-compose.yml up -d 
# -f dockerfile檔名,不使用-f引數時,預設就為 docker-compose.yml
# -d 後臺啟動並執行容器

如果未報錯,那麼docker就啟動成功了,使用Portainer檢視容器狀態:

顯示都為running狀態。

部署成功後啟用儲存庫

部署成功後,訪問7929埠的頁面:

點選Continue會自動跳轉到Gitea的授權頁面:

如果你瀏覽器沒有登陸Gitea,會先讓你登陸:

登陸且授權後,就會跳轉到Drone的頁面了,只需要授權一次即可,往後我們登入了Gitea就直接進入Drone了。

進入Drone會看到未啟用的倉庫,選擇需要啟用的倉庫,然後我們點選啟用它:

啟用成功後,回到Gitea檢視被啟用的倉庫,就會看到倉庫已經自動的配置好了WebHook(Web鉤子):

點選鉤子,進去找到測試推送,點選測試推送,如果出現如下綠色,那鉤子就沒問題了:

踩坑小Tips:

如果是紅色,且HTTP相應內容包含context deadline exceeded (Client.Timeout exceeded while awaiting headers),請檢查你的倉庫根目錄是否存在Drone的.drone.yml配置檔案,我就是這個配置檔案放錯了地方卡了我大半天。。。

到這裡我們的Drone就安裝完畢了,啟用倉庫後,我們向倉庫推送一個commit,Gitea就會發送訊息通知Drone去自動構建了!

配置Drone的自動構建

Drone支援不同環境的不同管道配置,這裡我使用Docker Pipelines管道配置簡單來說就是Drone的每一步操作都在一個臨時的Drone的容器中進行,容器操作完會自動銷燬,容器之間會共享當前的工作目錄。

本人這裡使用了私有映象倉庫 Harbor Harbor的搭建文章點選此處。

Drone 配置檔案 .drone.yml 如下:

kind: pipeline # 預設為 pipeline
type: docker 
name: deployment # 構建檔名稱

steps: # 陣列結構,流水線化的構建步驟
# 步驟1 構建
- name: build  # 因為drone支援同時書寫多個構建任務,所以需要為本任務起個名字
  pull: if-not-exists # 如果映象不存在則拉取,免去每次都要重新下載
  image: mcr.microsoft.com/dotnet/sdk:5.0 #	本步驟執行在哪個docker映象中,該映象必須存在於 docker hub 中,可在 https://hub.docker.com/_/microsoft-dotnet-sdk 檢視對應版本號
  commands:  # 構建過程中,將會依次執行的命令,如果命令退出碼非0,將會終止構建本次構建
  - dotnet restore # 專案重建
  - dotnet build -c Release # 專案生成構建
  - echo ========專案生成成功======== # 輸出
# 步驟2 將映象推送到 Harbor
- name: publish 2 harbor
  pull: if-not-exists # 如果映象不存在則拉取,免去每次都要重新下載
  image: plugins/docker
  settings: 
    dockerfile: Demo/Dockerfile  # Dockerfile 在專案中的位置
    tags: latest # 生成映象後的Tag標籤
    insecure: true	# 是否不安全
    registry: 192.168.2.7:8088	# 私有映象倉庫地址
    repo: 192.168.2.7:8088/zhjs/drone-ci-demo   # 倉庫地址/Harbor專案名稱/自定義映象名稱
    username: 
     # 從drone倉庫配置中祕密空間讀取使用者名稱
      from_secret: docker_username
    password: 
    # 從drone倉庫配置中祕密空間讀取密碼
      from_secret: docker_password
# 步驟3 使用ssh訪問主機,拉去映象並執行部署
- name: deploy
  pull: if-not-exists # 如果映象不存在則拉取,免去每次都要重新下載
  image: appleboy/drone-ssh 
  settings:
   # 需要部署的主機地址
    host: 192.168.2.7
   # 主機ssh埠
    port: 22
    # 主機登陸使用者名稱
    username: root
    password: 
    # 從drone倉庫配置中祕密空間讀取密碼
      from_secret: ssh_pwd
    script: 
      - echo =========暫停並刪除舊容器========
      - docker stop drone-ci-demo-1 && docker rm drone-ci-demo-1
      - docker stop drone-ci-demo-2 && docker rm drone-ci-demo-2
      - echo =========刪除舊映象=============
      - docker rmi 192.168.2.7:8088/zhjs/drone-ci-demo:latest 
      - echo ========從harbor拉取最新映象========
      - docker pull 192.168.2.7:8088/zhjs/drone-ci-demo:latest 
      - echo ===============執行映象==========
      - docker run --name drone-ci-demo-1 -p 5555:80 -d 192.168.2.7:8088/zhjs/drone-ci-demo:latest
      - docker run --name drone-ci-demo-2 -p 5556:80 -d 192.168.2.7:8088/zhjs/drone-ci-demo:latest
      - echo ========部署成功========
  # 步驟4 部署完成,郵件通知
- name: notify
  pull: if-not-exists # 如果映象不存在則拉取,免去每次都要重新下載
  image: drillster/drone-email  
  settings:
    recipients_only: true # 只發送給指定郵件收件人,不預設傳送給流水線建立人
    host: smtp.qq.com      #SMTP伺服器 例如 smtp.qq.com  
    port: 465   #SMTP服務埠  例如QQ郵箱埠465
    subject: "Drone Build Complete!"  # 郵件主題內容
    username:   #郵箱使用者名稱
      from_secret: qqmail_username
    password:   #郵箱密碼
      from_secret: qqmail_pwd
    from: 
      from_secret: qqmail_username
    recipients:   #收件人 
      from_secret: email_recipients  #  格式:xxxx,xxxx
  when:    #執行條件 
    status: 
    - success
    - changed
    - failure 

檔案編寫完成後,把程式碼git push到倉庫中,Gitea會通知Drone進行部署,Drone找到.drone.yml配置檔案,就會按照配置檔案中的步驟進行構建了,部署期間可以在Drone中檢視到每一步的部署情況

首次部署的速度可能略慢,最終部署成功圖:

總結:對於小團隊來說,總體是完全可以接受的,自動部署一旦配置好了,所有的編譯/測試/打包/部署的工作就交給Drone去完成了,而我們只需要專注於我們的程式碼編寫就行了!