私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

莫問今朝乄發表於2022-02-23
提示:本系列筆記全部存在於 Github, 可以直接在 Github 檢視全部筆記

Drone 管道機制

Drone 中引入了 管道(Pipeline) 機制。管道(Pipeline)相當於一個流程,管道(Pipeline)中可以執行多個 步驟(step)

步驟(step) 就是使用 外掛(Plugin) 配置的操作。

Runner(執行器) 相同的是,管道(Pipeline) 也支援多種型別,用於適配不同執行環境。當然某些型別可以使用容器化代替統一管理。

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

Drone 也是使用 YAML 語法作配置檔案,在配置檔案可以同時配置多個 管道(Pipeline)

預設情況下多個 管道(Pipeline) 是並行執行,這也是 Drone 的強大功能之一:分散式管道系統

kind: pipeline # 定義一個管道
type: docker # 定義管道的型別
name: test # 定義管道的名稱
steps: # 定義管道的執行步驟
  - name: test # 步驟名稱
    image: node:latest # 當前Docker步驟使用的映象
    commands: # 當前步驟執行的命令
      - echo 測試drone執行2

在上一篇中配置的測試管道(Pipeline)。此管道(Pipeline)使用了 docker 型別。

管道(Pipeline) 中定義了一個步驟(step), 使用了 Node 映象。容器內執行了列印命令

整個自動化部署就是配置 步驟(step) 進行執行。

可以簡單的理解為, .drone.yml 配置檔案相當於一個 .sh 檔案,部署操作配置在這個檔案中,交給 Drone 引擎執行。

下面就一步步編寫部署 Web 專案。

部署 Web 專案

Build 階段

上一篇中簡單的介紹,可以將整個部署流程劃分為兩個階段:

  1. 拉取程式碼 ---> 編譯專案 ---> 打包映象 ---> 推送映象倉庫
  2. 使用 SSH 連線伺服器 ---> 拉取最新映象 ---> 停止和移除舊容器 ---> 啟動新容器。

可以以這樣流程劃分構建管道(Pipeline)。一個階段為一個 管道(Pipeline)

第一階段叫做 build

kind: pipeline # 定義一個管道
type: docker # 定義管道的型別
name: build # 定義管道的名稱

clone 程式碼

預設情況下,管道(Pipeline)執行的第一個步驟(step)拉取程式碼(clone)

這是 Drone 提供的一個預設 步驟(step)

.drone.yml 檔案可以使用 clone 屬性對此步驟(step) 設定。

預設的 clone 步驟(step)只支援設定 disable、和 depth

如果需要使用到其它引數,可以將預設的 clone 步驟(step)禁用,自定義拉取程式碼 步驟(step)

kind: pipeline # 定義一個管道
type: docker # 定義管道型別
name: build # 定義管道名稱

clone:
  disable: false # 啟用程式碼拉取

預設情況下, 拉取程式碼使用的是 drone/git 映象。

部署 Drone 時可以使用 environment 屬性替換預設映象,可以參考官方文件

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

編譯程式碼

執行完畢 clone 步驟(step) 後就可以進行程式碼編譯了。

程式碼編譯可以直接使用 Node 映象執行 package.json 命令。

定義 build-project 步驟(step),執行程式碼編譯。

在此 步驟(step) 中使用了 depends_on 屬性,這個屬性表示當前步驟(step)需要依賴指定步驟執行,也就是需要在指定步驟執行完畢後才開始執行此步驟(step)

PS: 步驟(step) 之間是可以併發執行的。

kind: pipeline # 定義一個管道
type: docker # 定義管道型別
name: build # 定義管道名稱

clone:
  disable: false # 啟用程式碼拉取

steps:
  - name: build-project # 步驟名稱
    image: node:16.13.2 # 使用映象
    depends_on: [clone] # 依賴的步驟,
    commands: #執行命令
      - npm config set registry https://registry.npm.taobao.org # 切換淘寶映象
      - npm install # 安裝node_modules包
      - npm run build # 執行編譯
私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

PS: 如果是伺服器中沒有 node:16.13.2 映象,首先會拉取映象,時間會更慢一些。

快取 node_modules

如果多測試幾次程式碼編譯步驟,會發現一個問題:每次程式碼編譯執行時間都比較長,在我伺服器執行時間大約 1 分鐘左右。

可以使用 Gitea 測試推送 Webhook,進行重複測試。

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

查詢具體執行資訊,會發現其中大部分時間都浪費在了 npm install 命令。

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

這是因為每一個步驟都是在一個程式內執行的,每一次執行都是一個新程式,

但是往往會有掛載資料這種情況,針對這種需求,Drone 也提供了 Volume 機制。允許將容器內檔案掛載到宿主機中。

PS: Drone 中程式碼目錄在所有 步驟(step) 中共享,

Drone 中提供了兩種 Volume

  1. Host Volume:資料掛載到主機上,資料永久存在
  2. Temporary Volume:資料掛載臨時卷中用於步驟(step)間共享。管道(Pipeline) 執行完畢會清除資料卷

具體兩者,可以參考官方文件

掛載資料卷分為兩步

  1. 宣告資料卷
  2. 使用資料卷
kind: pipeline # 定義一個管道
type: docker # 定義管道型別
name: test # 定義管道名稱

volumes: # 宣告資料卷
  - name: node_modules # 資料卷名稱
    host: # Host Volume
      path: /volumes/drone/volumes/web/node_modules # 宿主機目錄    #絕對路徑

clone:
  disable: false # 啟用程式碼拉取

steps:
  - name: build-project # 步驟名稱
    image: node:16.13.2 # 使用映象
    depends_on: [clone] # 依賴的步驟,
    volumes: # 掛載資料卷
      - name: node_modules # 資料卷名稱
        path: /drone/src/node_modules # 容器內目錄 絕對路徑
    commands: # 執行命令
      - pwd # 檢視當前目錄
      - npm config set registry https://registry.npm.taobao.org # 切換淘寶映象
      - npm install # 安裝node_modules包
      - npm run build # 執行編譯

注意:

  1. 資料卷中路徑(path),必須為 絕對路徑,不可以使用 相對路徑

    我使用 pwd 命令查詢了當前目錄為 /drone/src

    也就是 node_modules 的目錄為 /drone/src/node_modules

    私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)
  2. 使用資料卷必須開啟 Trusted 許可權。 Trusted 許可權需要管理員使用者設定

    私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

第一次構建會在宿主機中掛載 node_modules 資料,之後再構建就可以省去了 npm install 執行時間,大大提高了構建速度

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

構建映象

程式碼編譯完畢後,下一個操作就是製作映象並推送倉庫了。

Drone 社群中提供了 plugins/docker 映象外掛用於構建映象並將映象直接推送到映象倉庫。

kind: pipeline          # 定義一個管道
type: docker            # 定義管道型別
name: build              # 定義管道名稱

  - name: build-image     # 步驟名稱
    image: plugins/docker # 使用映象
    depends_on: [build-project] # 依賴步驟
    settings:             # 當前設定
      username: XXXXXX # 賬號名稱
      password: XXXXXX # 賬號密碼
      dockerfile: deploy/Dockerfile # Dockerfile地址, 注意是相對地址
      repo: yxs970707/deploy-web-demo # 映象名稱
      tags:             # 映象標籤
        - latest
        - 1.0.2

settings 屬性是配置賬號、密碼、映象名稱等操作的屬性,這是 Drone 提供的屬性。 settings 屬性會傳給容器 environment 屬性。

plugins/docker 其它 settings 可以查詢官方文件

在上述配置中使用了兩個 Tag,加上了 latest 這個預設 Tag

PS: 注意,Dockerfile 地址使用了相對路徑

PS: Docker Hub 訪問會很慢。

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

Secret 配置賬號密碼

剛才構建映象時在 .drone.yml 檔案使用了明文賬號密碼,這樣肯定是不允許的,可以使用 Secret 配置這樣的敏感資料。

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)
kind: pipeline          # 定義一個管道
type: docker            # 定義管道型別
name: build              # 定義管道名稱

  - name: build-image     # 步驟名稱
    image: plugins/docker # 使用映象
    depends_on: [build-project] # 依賴步驟
    settings:             # 當前設定
      username:           # 賬號名稱
        from_secret: docker_username
      password:           # 賬號密碼
        from_secret: docker_password
      dockerfile: deploy/Dockerfile # Dockerfile地址, 注意是相對地址
      repo: yxs970707/deploy-web-demo # 映象名稱
      tags:             # 映象標籤
        - latest
        - 1.0.2

使用Secret時,需要使用 from_secret 屬性設定。

根據 package.json 生成 Tags

打包映象時設定的映象版本號,是直接設定的固定數值,這樣每次更新都要重新設定新版本號,也是一個繁瑣的操作。

Drone 中可以使用變數設定, 並且內建了許多變數,例如: DRONE_TAG。但是個人感覺這些變數並不太好用。

我想要的效果是根據 package.json 檔案 version 屬性 設定映象版本。這樣管理起來比較方便。

後查詢文件發現 plugins/docker 映象支援讀取專案根目錄下 .tags 檔案進行設定版本號

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

有一種解決方案,將package.json 檔案 version 屬性寫入到 .tags 檔案。

https://discourse.drone.io/t/using-custom-generated-tags-for-docker-images/1918/2

雖然感覺社群內會有這樣功能的映象外掛,

但是查詢起來浪費時間,於是自己寫了一個簡單的外掛:https://github.com/yanzhangshuai/drone-web-tags

使用起來也很簡單,並且同時支援設定其它 Tags

steps:
  - name: build-project # 步驟名稱
    image: node:16.13.2 # 使用映象
    depends_on: [clone] # 依賴的步驟,
    volumes: # 掛載資料卷
      - name: node_modules # 資料卷名稱
        path: /drone/src/node_modules # 容器內目錄
    commands: # 執行命令
      - npm config set registry https://registry.npm.taobao.org # 切換淘寶映象
      - npm install # 安裝node_modules包
      - npm run build # 執行編譯

  - name: build-tags
    image: yxs970707/drone-web-tags # 使用映象
    depends_on: [clone] # 依賴的步驟,
    settings:
      tags:
        - latest # 設定其它tags, latest

  - name: build-image # 步驟名稱
    image: plugins/docker # 使用映象
    depends_on: [build-tags, build-project] # 依賴步驟
    settings: # 當前設定
      username: # 賬號名稱
        from_secret: docker_username
      password: # 賬號密碼
        from_secret: docker_password
      dockerfile: deploy/Dockerfile # Dockerfile地址, 注意是相對地址
      repo: yxs970707/deploy-web-demo # 映象名稱
私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

deploy 階段

將映象推送到映象倉庫後,持續部署的第二階段就是在伺服器更新部署。

第二階段雖然細分了許多操作,但關鍵是遠端連線伺服器。所以為了簡單直接將這些操作都配置到一個 步驟(step)

第二階段 管道(Pipeline) 名字為 deploy

注意:管道(Pipeline) 之間需要使用 --- 相隔開

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

deploy 管道(Pipeline)需要在 build 管道(Pipeline)執行完畢後才執行。

並且 deploy 管道(Pipeline) 可以禁用程式碼拉取

kind: pipeline
type: docker
name: deploy

depends_on: # 依賴build管道
  - build

clone:
  disable: true # 禁用拉取

SSH 連線並部署

之前說過,Drone 提供了多種 Runner(執行器)管道(Pipeline) 型別, 但某些型別可以使用容器化統一化管理。

Drone 社群中提供了 SSH 連線映象外掛, appleboy/drone-ssh

配置此步驟前,需要先改動 之前 web 專案的 Docker Compose 檔案

  • 配置中使用了具體 Tag 映象。不過伺服器部署時並不需要清楚當前是什麼版本服務,直接部署 最新版本(latest) 就行。
  • 取消對 html 目錄的掛載。 html 資料並不推薦掛載到宿主機中,這樣版本管理會非常混亂
私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)
kind: pipeline
type: docker
name: deploy

depends_on: # 依賴build管道
  - build

clone:
  disable: true # 禁用拉取、

steps:
   - name: deploy-project
    image: appleboy/drone-ssh
    settings:
      host:
        from_secret: server_host
      user:
        from_secret: server_username
      password:
        from_secret: server_password
      port: 22
      command_timeout: 2m
      script:
        - echo ====開始部署=======
        - docker pull yxs970707/deploy-web-demo:latest
        - docker-compose -p web down
        - docker volume rm web-nginx
        - docker-compose -f /yml/docker-compose/web.yml -p web up -d
        - docker rmi $(docker images | grep deploy-web-demo | grep none | awk  '{print $3}')
        - echo ====部署成功=======

伺服器部署步驟一共 5 個命令

  1. 拉取新映象
  2. 解除安裝舊容器
  3. 刪除 Volume
  4. 啟動新容器
  5. 刪除舊映象

第三個命令可以在 Docker Compose 使用外部 Volume ,這樣就不需要刪除 Volume 了。

最後一個命令是刪除舊的映象,當成功拉取新的 latest 映象,舊映象 Tag 會變成 none,所以刪除標籤為 none 的映象即可

私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下) 私有化輕量級持續整合部署方案--05-持續部署服務-Drone(下)

相關文章