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


提示:本系列筆記全部存在於 Github, 可以直接在 Github 查看全部筆記

Drone 管道機制

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

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

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

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 屬性替換默認鏡像,可以參考官方文檔

編譯代碼

執行完畢 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 # 執行編譯

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

緩存 node_modules

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

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

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

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

但是往往會有掛載數據這種情況,針對這種需求,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

  2. 使用數據卷必須開啟 Trusted 權限。 Trusted 權限需要管理員用戶設置

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

構建鏡像

代碼編譯完畢后,下一個操作就是制作鏡像並推送倉庫了。

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 訪問會很慢。

Secret 配置賬號密碼

剛才構建鏡像時在 .drone.yml 文件使用了明文賬號密碼,這樣肯定是不允許的,可以使用 Secret 配置這樣的敏感數據。

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 文件進行設置版本號

有一種解決方案,將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 # 鏡像名稱

deploy 階段

將鏡像推送到鏡像倉庫后,持續部署的第二階段就是在服務器更新部署。

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

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

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

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 數據並不推薦掛載到宿主機中,這樣版本管理會非常混亂
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 的鏡像即可


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM