CI/CD 持續整合部署實踐

RightCapital發表於2020-03-23

持續整合與持續部署 (CI/CD) 是 DevOps 的主要核心,如實施得當,能極大地提高程式碼質量,加快開發速度,幫助團隊更高效地開發。

在這篇文章中,我們會分享 RightCapital 在這方面的最佳實踐,團隊文化,希望能對你有所啟發。

此文主要介紹我們後端專案的 CI/CD,用到的技術棧大概如下:

  • PHP
  • GitLab CI
  • Kubernetes
  • Helm + Helmfile + Helm Secret

持續整合 Continuous Integration

什麼是 CI

開發者每次通過 push 或者 merge 導致的程式碼變更,會觸發一系列的自動化工具執行程式碼檢測。這些檢測會幫助我們發現程式碼中的錯誤和可能的隱患,讓問題在極早期暴露出來,而不用等到程式碼部署到 production 環境等使用者反饋才意識到問題。

我們的 CI Pipeline

我來簡單介紹一下我們在 CI 中具體做了些什麼?

  • Prepare 階段:做一系列初始化工作,比如安裝專案依賴
  • Lint 階段:程式碼風格的檢查
    • PHP CS Fixer:確保所有人的程式碼風格一致
    • Yaml Lint:確保專案中的 yaml 檔案格式正確,且風格一致
  • Test 階段:測試
    • PHPUnit:執行的單元測試和整合測試
    • PHPStan:程式碼靜態分析檢查,比如查詢未定義變數,型別錯誤使用等問題
  • Post 階段:收尾工作
    • Sentry:將程式碼 commits 和 Sentry 關聯起來,在 Sentry 收集到報錯之後能快速定位到程式碼變更和提交人
    • Trigger Deploy:會觸發部署的 pipeline,我們在下一章節細說

由於我們公司循序使用 GitFlow,所有程式碼變更皆產生自 feature, bugfix, hotfix 分支,且我們禁止了 develop, release, master 分支上的直接程式碼變更,所有變更皆需通過 PR 的方式才能被 merge 到這幾個主幹分支;而如果某個 PR 的任何一個檢查中失敗了,都是不允許被 merge。也就是說,我們通過以上 CI 流程,確定了我們能接受的程式碼質量底線。

什麼是持續部署 Continuous Deployment

當持續整合完成之後,及時的進行自動部署,以確保每個時刻我們的程式碼都是可交付的。

  • Pre-deploy 階段:做一些準備工作,比如下載 CI Pipline 的一些 artifacts
  • Publish:
    • Quay Cloud:build docker 映象,並推送到 quey.io 上(quay.io 是一個企業級的 Docker Registry)
    • TS Schema Generator:這是我們內部的一個工具,會分析我們的 PHP 程式碼中 model,自動提取 API schema 並生成給前端用的 TypeScript 程式碼,並打包釋出。裡面包含了我們 API model 的屬性名詞、型別等源資訊。
  • Deploy:
    • 這一步我們會將程式碼部署自動部署到分支對應的環境,並執行一系列的操作
      • 比如 master 部署到 production 環境,release 分支部署到 staging 和 uat 環境,develop 分支部署到 development 環境
      • 這裡一系列操作包括:
        • 使用 helm + helmfile 將我們前面打包好的 docker 映象部署的 K8S
        • 使用 helm secret 將我們的 env 部署到 K8S 成 secrets,我們在之前的《使用 SOPS 管理 Secret》中有介紹
        • 自動執行 migration,我們會在程式自動部署後,自動備份資料庫,然後執行 migration 執行資料庫變更
        • 快取清理等工作……

程式碼任何時刻皆是可交付的,而這對於一個在高效持續改進產品的團隊來說非常重要。而使用自動的方式規範了流程,避免了人工失誤的可能,在任何資料庫變更之前我們都會先自動先備份資料庫,確保了資料安全。

Review Branch

這是什麼?這是我們非常自豪的一套最佳開發環境部署實踐,來看一下這些場景:

  • 由於我們的功能都在 feature 分支上開發,而 feature 分支在沒有通過 CI 和程式碼評審之前是無法被 merge 到 develop 分支的,也就是說程式碼無法部署到 development 環境,可在開發期間經常有前後端聯調的需求那我們怎麼解決?
  • 在程式碼 review 過程中,雖然 CI 通過了,可評審員有時還希望將程式碼執行起來,手動測試一下,如何才能方便高效?

解決方案:我們可以為每個 branch 自動部署一個臨時的環境用於測試和聯調,這個環境在 PR 被 merge 後即被自動銷燬。然後我們在前端頁面底部做了一個 DevBar,可以看到當前有哪些環境和分支,且能隨時切換 API 到任意環境開始測試,還能看到當前環境的 commit 相關的一些資訊。

如果前後端需要聯調怎麼辦? 後端只需要告訴前端一個資訊,分支名是什麼,Done!程式碼評審測試測試怎麼辦? 在前端選擇當前分支名的環境即可開始測試。

這套方案極大的簡化了我們的開發環境管理成本,而且讓其他流程運轉也都更高效了。

這套方案的實現基於了以下技術,我們後續會有文章細說實現:

1. GitLab CI Review Apps
2. K8S + helm
3. Cert manager

結語

也許有人會質疑這套流程過於苛刻,以至於影響開發效率。對於沒有任何制約的程式碼推送,我們的流程自然會慢,而這正是我們希望發生的事情。

因為我們堅持程式碼質量重於開發速度,並且依靠流程的高度自動化,也能保持足夠的高效,魚和熊掌是可以兼得的。如果你也認可我們的理念,不妨投個簡歷加入我們。

這篇文章是一個我們 CI/CD 的一個總覽,如果對我們的具體實現感興趣,請關注訂閱我們的賬號/公眾號獲取後續更新。

本文作者:NauxLiu, DevOps Manager, RightCapital

本作品採用《CC 協議》,轉載必須註明作者和本文連結

歡迎關注我們的微信公眾號「RightCapital」

相關文章