天天看點

玩轉 Drone CI

前言

使用 drone CI 已有小半年,在将原有項目的 CI 系統從 jenkins 向 drone 遷移的時候,也陸陸續續遇到了一些問題。在這段時間,也完成了使用官方插件到插件定制的轉變,使得 drone CI 流程更貼合我們 devops 開發流程。通過這篇文章總結一下目前我們對 drone 進行的一些定制化開發以及使用技巧,由于 drone 官方的文檔不是很詳細,是以也希望通過這種方法來和其他使用 drone 的使用者分享和交流使用經驗。

并行建構

在預設情況下,drone 會按照步驟執行,但是有時會遇到前後端在同一個 repo 的情況,這時使用并行建構就可以省去很多的建構時間。

建構流程:

在下面的示例裡會展示一個如下流程:repo 中包含一個由 Java 寫的服務以及一個 vue 前端項目,maven 建構和 npm 建構同時進行,maven 建構成功後會鏡像 docker 鏡像建構并上傳鏡像倉庫,docker 建構成功後會鏡像 k8s 部署,部署成功後會進行 vue 項目前端釋出,在 k8s 部署成功并且前端釋出成功後,進行釘釘建構成功同時,否則進行釘釘建構失敗通知。

前端建構 ————————————          前端釋出
                    \      /        \
                     \    /       釘釘通知
                      \  /          /
後端建構 —— 鏡像建構 —— k8s部署 ——————
           

.drone.yml

配置
kind: "pipeline"
name: "default"
steps:
  - name: "Maven編譯"
    image: "guoxudongdocker/drone-maven"
    commands:
      - "mvn clean install"
    depends_on: [ "clone" ]
  - name: "建構鏡像"
    image: "guoxudongdocker/drone-docker"
    settings:
      username:
        from_secret: "docker_user"
      password:
        from_secret: "docker_pass"
      dockerfile: "Dockerfile"
      repo: "registry-vpc.cn-shanghai.aliyuncs.com/guoxudong/test"
      registry: "registry-vpc.cn-shanghai.aliyuncs.com"
      tags: "${DRONE_BUILD_NUMBER}"
    depends_on: [ "Maven編譯" ]
  - name: "Kubernetes 部署"
    image: "guoxudongdocker/kubectl"
    settings:
      config: "deploy/overlays/uat"
      timeout: 300
      check: false
    depends_on: [ "建構鏡像" ]
  - name: "前端建構"
    image: "guoxudongdocker/node-drone"
    commands:
      - "npm install"
      - "npm run build"
    depends_on: [ "clone" ]
  - name: "前端上傳"
    image: "guoxudongdocker/node-drone"
    commands:
      - "do something"
    depends_on: [ "前端建構","Kubernetes 部署" ]
  - name: "釘釘通知"
    image: "guoxudongdocker/drone-dingtalk"
    settings:
      token:
        from_secret: "dingding"
      type: "markdown"
      message_color: true
      message_pic: true
      sha_link: true
    depends_on: [ "前端上傳","Kubernetes 部署" ]
    when:
      status:
        - "failure"
        - "success"           

多子項目建構

在使用 drone 中遇到的最大問題就是,我們有很多項目都是在一個 repo 中有很多子項目,而每個子項目都是 k8s 中的一個服務,這時一個

.drone.yml

檔案很難把所有的服務都囊括。而又不想每個子項目拉一個分支管理,目前的模式就很不合适。

插件開發

針對這個問題,我們對 drone 進行了定制化開發,會在每次送出代碼後,對新送出的代碼和老代碼進行比較,篩選出做了修改的子項目,然後對有修改的子項目盡心 CI ,其餘的子項目則不進行釋出。

而以上的方式僅适用于測試環境的快速疊代,生産環境則采用 tag 的模式,針對不同的子項目,打不同字首的 tag ,比如子項目為 test1 ,則打

test1-v0.0.1

的 tag,就會對該子項目進行生産釋出。

建構效果

  • 有修改的子項目
  • 無修改的子項目

Kubernetes 釋出狀态檢查

之前的 Kubernetes 釋出隻是将服務釋出到 Kubernetes 叢集,并不管服務是否正常啟動。針對這個問題以及我們的 Kubernetes 應用管理模式,我們開發了 drone 的 Kubernetes 釋出插件,該插件包括

kubectl

kustomize

kubedog

,來完善我們的 Kubernetes 釋出 step 。

.drone.yml
steps:
- name: Kubernetes 部署
  image: guoxudongdocker/kubectl
  volumes:
  - name: kube
    path: /root/.kube
  settings:
    check: false                 # 該參數為是否開啟子子產品檢查
    config: deploy/overlays/uat  # 這裡使用 kustomize ,詳細使用方法請見 https://github.com/kubernetes-sigs/kustomize
    timeout: 300                 # kubedog 的檢測逾時
    name: {your-deployment-name} # 如果開啟子子產品檢查則需要填入子子產品名稱

...

volumes:
- name: kube
  host:
    path: /tmp/cache/.kube  # kubeconfig 挂載位置

trigger:
  branch:
  - master  # 觸發 CI 的分支           

使用該插件會如果為測試建構,則會自動設定 docker 鏡像 tag 為

DRONE_BUILD_NUMBER

;如果為生産建構(git tag),則叫自動設定 docker 鏡像 tag 為

DRONE_TAG

,然後通過

kubectl apply -k .

進行部署,同時使用

kubedog

進行部署狀态檢查,如果服務正常啟動則該 step 通過,如果逾時或者部署報錯則該 step 失敗。

結語

根據我們目前的開發模式,對 drone 插件進行了全方位的開發。由于 dockerhub 的鏡像拉取經常逾時,則将鏡像推送到了我們自己的鏡像倉庫;對釘釘通知也進行了優化;同時也根據我們目前的開發語言進行了插件的開發,提供了基于 Java 、Python 以及 Node.js 的 drone 插件,基本可以滿足我們現在的 CI 需求,但随着 drone 的深入使用,越來越多的問題将會暴露出來。後續将會不斷解決遇到的問題,持續優化。