基於Drone實現CI/CD【0到1架構系列】

老猿新码發表於2024-07-29

CI/CD是持續性整合和持續性部署,簡單來講就是自動化構建和自動化部署。目前有很多整合方案,也有很多組裝方案,只要能實現自動化構建出製品,再自動部署到生產環境就行。

目前很多原始碼都整合了CI/CD功能,drone也是目前比較流行的一個方案,簡單易用,高效能。

前提條件

已經使用Gitea部署作用原始碼管理,使用gitea搭建原始碼管理 。

已經使用Harbor部署私庫,harbor 搭建和部署。

已經使用Portainer部署,portainer安裝,配置,使用。

準備工作

拉取我們接下來CI/CD工作有可能會用到的docker映象,後面會繼續解釋這些映象的作用。

#自動構建
docker pull drone/drone
docker pull drone/drone-runner-docker

#自動部署
docker pull drone/drone-runner-ssh
docker pull docker
docker pull plugins/docker
docker pull curlimages/curl

自動構建

drone是服務中心或者理解成任務中心,Git的webhook會通知到這裡。

drone-runner-docker相當於實際參於構建工作的作業容器,drone-runner-docker定時與drone通訊獲取構建任務,然後按規定的流程執行相應工作。這個流程的設計由.drone.yml配置檔案決定,所以編寫.drone.yml也是主要核心。

步驟一,設定Gitea的OAuth2登陸,因為drone採用OAuth2登陸方案。

登陸Gitea -> 右上角 -> 管理後臺 -> 管理設定 -> 整合 -> 應用。建立應用,重定向 URI地址填寫你部署的dron域名,例如:htts://drone.xxxx.com/login

步驟二,啟動容器,可以單個容器啟動,這裡使用docker-compose進行管理。

version: "3"
 
services:
  drone-server:
    image: drone:latest
    container_name: drone
    environment:
      - DRONE_GITEA_SERVER=https://gitea.xxxx.com   #你部署的原始碼地址
      - DRONE_GITEA_CLIENT_ID=dadda5f7-a951-4e8a-a2de-ebf737a5bef5 #Oauth2登陸,客戶端Id
      - DRONE_GITEA_CLIENT_SECRET=******************************** #Oauth2登陸,客戶端金鑰
      - DRONE_RPC_SECRET=aaaaaaaaaaaaaaaaaaa #與drone-runner通訊的憑據,隨便填寫
      - DRONE_SERVER_HOST=drone.xxxxx.com #繫結你的drone域名,用IP也行
      - DRONE_SERVER_PROTO=https #http,https 都可以
      - DRONE_TLS_CERT=/SSL/SSL.crt  #HTTPS證書
      - DRONE_TLS_KEY=/SSL/SSL.key   #HTTPS證書
      - DRONE_USER_CREATE=username:giteauser,admin:true #建立賬號,這裡需要填寫你的gitea賬號,預設管理員
      - DRONE_USER_FILTER=giteauser  #限制指定賬號登陸
    restart: always
    volumes:
      - /SSL:/SSL #掛載證書
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "443:443"

  drone-runner:
    image: 	drone-runner-docker:latest
    container_name: drone-runner
    environment:
      - DRONE_RPC_PROTO=https
      - DRONE_RPC_HOST=drone.xxxxx.com:443  #drone的域名或IP
      - DRONE_RPC_SECRET=aaaaaaaaaaaaaaaaaaa #drone通訊的憑據,填寫上面的憑據
      - DRONE_RUNNER_CAPACITY=2 #工作執行緒數
      - DRONE_RUNNER_NAME=my-runner
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock  #掛載docker.sock,必需
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro

啟動容器之後,訪問drone域名就可以看到登陸頁面,點選“CONTINUE”,就會跳轉Gitea登陸,登陸就會授權成功返回drone介面。

步驟三,設定webhook。

進入drone介面之後,點選右上角的"SYNC"按鈕,就會把Gitea專案同步過來,點選專案 -> Settings -> ACTIVATE REPOSITORY ,就自動在gitea相應的專案上面新增webhook。

檢視Gitea的webhook。

在drone介面,設定專案的“Trusted”,這點非常重要,否則在後續構建中儘管掛載了docker.sock,仍然會提示如下錯誤,如果沒有這個選項,是由於啟動drone容器沒有填寫DRONE_USER_CREATE的原因。

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
exit status 1

步驟四,至此自動構建就算搭建成功,接下來就是編寫.drone.yml檔案,需要將/var/run/docker.sock掛載進去,drone-runner實際上使用母機的docker在構建制品,也就是說構建成功之後映象在母機上透過docker images就能查詢出來。

下面示例使用Dockerfile檔案進行構建,plugins/docker:latest映象是預先設定好,具有基於dockerfile構建和推送功能的映象。

kind: pipeline
type: docker
name: default

steps:
  - name: 構建&推送  #管道名稱
    image: plugins/docker:latest
    volumes:
      - name: dockersock
        path: /var/run/docker.sock
    settings:
      registry: harbor.xxxxx.com #你部署的docker私庫地址
      repo: harbor.xxxxx.com/project/web
      tags: latest
      dockerfile: ./Dockerfile
      pull_image: false #構建的時候是否強制拉取最新映象
      username: abc
      password: 123

volumes: #掛載
- name: dockersock
  host:
    path: /var/run/docker.sock

也可以使用docker映象,自行編寫命令進行構建。

kind: pipeline
type: docker
name: default

steps:
  - name: 構建&推送  #管道名稱
    image: docker:latest
    volumes:
      - name: dockersock
        path: /var/run/docker.sock
    commands:
      - docker build -t web:latest .
      - docker image tag web:latest harbor.xxxxx.com/project/web:latest
      - docker push web:latest harbor.xxxxx.com/project/web:latest

volumes: #掛載
- name: dockersock
  host:
    path: /var/run/docker.sock

步驟五,至此自動構建和推送到私庫,基本就搭建完成。每次打包製品之後映象都不會主動刪除,所以我們可以增加多一個流程來刪除剩餘的映象。

kind: pipeline
type: docker
name: default

steps:
  - name: 清理映象  #管道名稱
    image: docker:latest
    volumes:
      - name: dockersock
        path: /var/run/docker.sock
    commands:
      - docker images --filter=reference='harbor.xxxxx.com/project/web:*' --format '{{.ID}}' | xargs -I {} docker rmi -f {}

volumes: #掛載
- name: dockersock
  host:
    path: /var/run/docker.sock

自部部署

方式一,SSH遠端登陸,拉取映象,重新部署。

kind: pipeline
type: docker
name: default

steps:
  - name: SSH部署  #管道名稱
    image: drone/drone-runner-ssh:latest
    settings:
      host: 192.168.3.78
      username: root
      password: 123
      port: 22
      script: #部署執行動的命令
        - echo ====開始部署=======
        - docker pull harbor.xxxxx.com/project/web:latest
        - docker stop web
        - docker rm web
        - docker run -d --name web -p 80:8080  harbor.xxxxx.com/project/web:latest
        - echo ====部署成功======

方式二,透過Portainer的webhook進行更新。

進入portainer管理介面,進入容器詳情頁,開啟容器的webhook,複製通地址。

kind: pipeline
type: docker
name: default

steps:
  - name: Portainer部署 #管道名稱
    image: curlimages/curl:latest
    commands:
      - curl -X POST "https://portainer.xxxx.com/api/webhooks/983DB2D1-34B8-4527-087B-08D76FE58AE5"

部署完成通知

部署完成之後,開發者可以透過drone管理介面檢視進度,或者透過webhook通知推送成功訊息到微信,簡訊,郵件,釘釘等。

kind: pipeline
type: docker
name: default

steps:
  - name: 部署完成通知 #管道名稱
    image: curlimages/curl:latest
    commands:
      - curl -X POST "通知的webhook地址"

一個完整的示例如下:

kind: pipeline
type: docker
name: default

steps:
  - name: 構建&推送  #管道名稱
    image: plugins/docker:latest
    volumes:
      - name: dockersock
        path: /var/run/docker.sock
    settings:
      registry: harbor.xxxxx.com #你部署的docker私庫地址
      repo: harbor.xxxxx.com/project/web
      tags: latest
      dockerfile: ./Dockerfile
      pull_image: false #構建的時候是否強制拉取最新映象
      username: abc
      password: 123

  - name: 清理映象  #管道名稱
    image: docker:latest
    volumes:
      - name: dockersock
        path: /var/run/docker.sock
    commands:
      - docker images --filter=reference='harbor.xxxxx.com/project/web:*' --format '{{.ID}}' | xargs -I {} docker rmi -f {}

  - name: Portainer部署 #管道名稱
    image: curlimages/curl:latest
    commands:
      - curl -X POST "https://portainer.xxxx.com/api/webhooks/983DB2D1-34B8-4527-087B-08D76FE58AE5"

  - name: 部署完成通知 #管道名稱
    image: curlimages/curl:latest
    commands:
      - curl -X POST "通知的webhook地址"

volumes: #掛載點,共用
- name: dockersock
  host:
    path: /var/run/docker.sock

執行效果:

更多系列文章

構建高效能,可伸縮,高可用,安全,自動化,可溯源,整體式應用構架體系

相關文章