Artifact
Artifact:
- 保留Job執行後所得的artifact(成品)並在Pipeline結束後提供到GitLab UI
- 並且也可以在不同Jobs間傳遞artifact
但是考慮到目前有以下這段寫法:
每次執行到run_unit_tests這個Job都會跑一堆npm安裝
而這個安裝是會去網路上下載必要套件
就猶如Maven的dependency一樣
考量到假若又有另一個Job比如名稱叫run_code_analysis
並假設裡面也要執行npm安裝後才能做一些測試
那麼這個Job內就又要真的重做下載安裝的動作
也就是都在做很重複的下載動作,並且載相同的東西,卻無法重複利用
尤其是這些第三方套件library
並且浪費大量的時間( →slow down CICD pipeline)
所以前面學到的 →Artifact則解決了不同Jobs間這類重複下載的問題
Artifact透過Runner把檔案交給GitLab Server在轉交給下一個Runner方式
但是若是不同次執行的Pipelines間也有這樣的需求!?
甚至現在像是dependency的檔案數量極為龐大
很難像Artifact轉傳方式處理
Cache
從Pipeline#1執行已經下載的東西,在Pipeline#2希望就不用重複下載
這時候就要引入 →Cache
Caching re-use between in pipeline run:
- 加速pipeline執行
- 減少CI的花費
Artifacts VS Cache
Artifacts:
- Job Artfact上傳保留在GitLab Server上
- 常用來在不同Stages間轉傳build過程中的結果
Cache:
- 通常用於dependencies,像是打包時常常去網路上下載的套件
- Cache的檔案是保留在GitLab Runner上面
- 但有一個前提是剛好Job跑在同一台Runner,才有re-use
- 因為這些Cache是保留在Runner的Server上
Distributed Cache
Distributed Cache:
- 好處:中心管理Cache storage
- 壞處:但是會多出要向遠端storage下載的部分,但是還是比從網路上下載快得多
- 好處:下載1個zip還是比分別下載多個dependency快
Configure a Cache
- 用"cache" attribute在.gitlab_ci.yml檔案內定義
- 其中要給定"cache key"
cache key:
- 每個cache的獨一無二的id key
- 如果沒給,預設是會叫"default"
- 所有Jobs透過相同的cache key來使用相同的cache
Common Naming of Cache Keys:
- 依據環境Branch來分,像是(cache_main,cache_dev)
- 也就是可能會需要動態地依據branch定義不同cache
- 所以需要另外引用到以下GitLab自帶的變數:
並指定要保留為cache的方式是可以用paths,寫法如下:
上述app/node_modules就是npm install後會長出來的套件
以上寫法可以完成兩個目的:
- 產生cache
- 或下載cache
在第一次執行該Pipeline#1時經過這段流程,會產出cache
在到第二次執行Pipeline#2經過這段流程,會下載cache
這誕生一個名詞 →pull-push policy(一種Cache Policies)
pull-push policy:
- Job開始的時候下載cache,並且在Job結束後上傳變更的cache
如上設定下
run_unit_tests這個Job載執行開始的時候會下載cache
run_unit_tests這個Job載執行結束的時候會上傳cache內容異動的部分
並且這個policy是default的,所以可以省略:
這邊課程講師為了demo用途,額外加入一個job →run_lint_checks
引用"Linting"這個靜態程式碼分析工具,查找程式中的錯誤:
並且跟run_unit_tests都在相同stage內,沒有needs來分順序
這時候會有一個嚴重問題:
也就是storage會同時被不同process更新
所以這時候我們會要求其中一個Job針對storage是read only
這時候就要這樣改:
pull policy:
- 只下載,不上傳
- 特別適合在很多併發平行處理的Jobs上使用
- 加速job執行的同時
- 也減少Cache Server的loading
反過來說還有另一個policy就是push policy
這也是很多人會把這個獨立寫成單一個Job:
push policy:
- 專門用來建置cache的Job
- 只上傳,不下載
另外要提醒,即便有獨立的push的Job或是其他別的Job建立了cache
需要相關套件的Job仍然需要執行"npm install"
Best Practice →保留如npm install:
- 不應該依賴Cache!
- Cache只是拿來優化,但無法保證都充足來執行Job內容
- 也就是Pipeline設計要考慮當沒有cache時(甚至拿不到)
- 也要仍可以正常運作(只是慢一點)
Configure Volume for Docker Executor
還有一個關於Cache使用上的問題是我們有用到:
也就是docker container的部分
當同時使用cache時,這些cache內容會建立在Container內
想當然爾,隨著Container消失,而不像Shell Runner那樣保留在Server上
其中設定要到該docker機台(Runner)上找到:
用root身分編輯其內容:
這邊只要新增一行實體路徑就好:
當前的Pipeline內容為:
Commit後執行看看結果:
run_unit_tests部分:
接著看看另一個新增的Job →run_lint_checks
接著仔細看看:
接著手動讓這個Pipeline重跑,看到:
Clearing the Cache
這邊先移除上面demo用的run_lint_checks這個Job
若有需求要清空Cache則有兩種方式:
1.按按鈕:
但是上述這個紐按了以後,舊的Cache實體檔其實還會在
而實體的Cache名稱會變新的
真的要清除還是要手動進到Runner storage內移除
這邊試著按下去,然後把移除了run_lint_checks這個job的pipeline重新執行
所以舊的cache還在,新的cache名稱會有一個index方式變化
main-X-protected
講師畫面是:
main-X
Where the caches are stored
#查找docker綁定的volume:
docker volume ls
docker volume inspect {volume name}#找到mount目錄後可以找到:
{mount目錄}/{帳號名}/{程式專案名}底下
其中一個裡面長這樣:
另外Shell與docker Executor綁的位置可能不一樣
可以去文件查看:
目前Pipeline內容為: