Artifacts Management
Artifacts 是 CI/CD 很關鍵的點,他承接著接下來整個 Development Pipeline 的樞紐因子,能否有靈活、有彈性的佈署,都仰賴於 Artifacts Management。
Artifact 的目的就如同交付軟體給另一個陌生人,他可以透過取得一個檔案 (通常是壓縮檔),然後解開後,依據 README.md
的說明,不管手動還是自動,可以自行完成部署或者安裝。而這個過程交付的 一個檔案
就稱作 Artifacts
,在 github 上來講,就是 releases
上的檔案,像是 awscli
Updated:
- 這段整理後來的在社群 Meetup 的分享:聊聊軟體交付的濫觴 談產出物管理 (Artifacts Management)
- Updated 2023/07/19: 本文部分內容收錄在個人著作 《SRE 實踐與開發平台指南》 - 2023/08 上市
基本概念
本文延伸 導入 CI/CD 的第一步、Designing Test Architecture and Framework 提到的概念,重新整理關於 Artifact Management
的實踐經驗談,也就是如何從 Source Code 經過 Build or Packing 的過程,得到產出物 (Artifact),有了此步驟之後,才有後續的持續整合 (CI)、持續部署 (CD)、各式各樣的整合與自動化測試、然後才是 持續交付價值 (Continuous Delivery Values)
…
重點是:不只是可以部署到正式環境,而是 任何人
可以自行決定,部署到 任意環境
(不管手動、還是自動),目標就是底下張圖:
注意:
- 如果這個過程只能自動,卻無法手動,當自動程序有問題的時候就完蛋了。
- 如果只能自動部署到正式環境,但測試環境卻無法自行決定如何部署,這表示未來測試會是瓶頸。
- 如果無法透過 Artifact 交付部署,未來業務發展會受到影響,換句話說:公司長不大
Learning from Open Source Software (OSS)
談持續交付的實踐,通常建議不要先扯一堆工具,像是 Gitlab CI、Jenkins … 等,這些很重要,但是常常會讓很多不了解的人,抓不到方向,或者陷入技術的陷阱。從怎麼用軟體開始學習交付這件事情,,底下的例子是很常見的安裝方式:
1 | ## 安裝 kubectl |
這一段的精神就是下載 最新版本的 Artifact
,其中:
https://storage.googleapis.com/kubernetes-release/release/stable.txt
取得版本名稱,像是v1.13.2
- 再利用版本名稱,組合出實際下載 binary 的路徑
再舉一個例子 kops 的安裝
1 | # See: https://github.com/kubernetes/kops |
概念則是透過 github release api 取得 Artifact Meta (後述),然後取得關鍵的資訊,例如 tag 名稱,也就是版本。底下是取得 Release Info 的例子:
- kubernetes: https://api.github.com/repos/kubernetes/kubernetes/releases/latest
- vscode: https://api.github.com/repos/microsoft/vscode/releases/latest
- aws-go-sdk: https://api.github.com/repos/aws/aws-sdk-go/releases/latest
再舉一個例子是 docker 的安裝,也是一行
1 | curl -fsSL https://get.docker.com/ | sh |
這些概念基本上都是: Learning from Open Source Software
定義
Artifact
中文翻譯成 產出物
,在以前 Release Engineering 慣稱為 Build、Image,主要就是 Source Code 經過 編譯 (Compile)
、打包 (Packing)
最後的產出物。不管是什麼樣的語言,大致上都要經過這個過程。要注意的是,這個過程產出的東西,不包含 Configuration
、Settings
之類的東西,有也只是 Templates、Sample。
Config Management 和 Settings 的概念,有空另外整理專文。
目的
Artifact 目的就是要讓其他人、或者程式可以獨立部署。人會有以下:
- 內部的人:包含測試團隊、維運團隊、研究團隊,當然也包含開發團隊自己
- 跨地域的團隊,像是台灣的團隊,給美國團隊部署
- 跨團隊的權責切分,開發交付給測試的切點
- 外部的人:像是交付給其他合作夥伴自行部署
- 遊戲產業很常是韓國負責開發,台灣則維運。
- 整併的組織,權責移交
- 新業務需求部署
- 給客戶使用的沙箱環境
- 災難還原
在開發過程會出現的問題案例:
測試測出問題,去跟開發講,開發說我找找。結果偷偷在 local 改了 code,然後跟測試說沒問題。
這個現象,是實務上卻是真的發生過的,同時造成的溝通成本很高。比較切確的做法是:
- Tester 回報問題,附上 Artifact Meta 的資訊
- Dev 根據回報的內容復現問題
因為 Artifact Meta 會包含像是 git hashcode, branch, version, datetime 等資訊,可以讓雙方精準溝通,而不會有雞同鴨講的狀況。詳細參閱 如何有效的回報問題 (How to Report Problems Effectively)
所以簡單說,透過 Artifact 解偶 (decouple)
整個 pipeline,讓需要的角色可以獨立作業。如果 pipeline 只能是一件部署,而沒有其他的選擇,那麼表示部署流水線是沒有任何彈性的,換言之,部署的主動性只有開發團隊有,其他人都無法自主,造成的現象就是 強耦合 (couple)
,當有第二、第三環境要部署的時候,就要重新 Pull Code、Build … 實際上是沒有意義的。
Artifact Types
Artifacts 類型很多,整理如下:
Application Build
: 也就是一般開發者寫的應用程式產出物,可能是透過:- Compile: Java, C#, Golang, C, C++ ….
- Packing: Node.js, Webpack, PHP …
Docker Images
: Dockerfile 編譯出來的 ImagesApp Libraries
:- 應用程式依賴的函式庫,通常需要做資安檢測,或者考慮網路頻寬
- 自行開發的函示庫。像是 npm, NuGet, …
VM Images
: 虛擬機的 Image, 像是 Vagrant, AWS Machine Image (AMI) … 等。- 主要是一些中介軟體的配置管理、應用程式依賴的系統軟體、函式庫等
- 透過 Image + Auto Scaling 快速更新 OS Patch, Security Issues.
- Netflix 是使用 AMI 做管理到極致的案例,參見:AMI Creation with Aminator
這些 Artifacts 實際上基於一些因素,像是資安、維運效率化、一致性、部署等因素,需要納管、受控。
具備一定規模的企業,都會有私有的 Artifact Repository,甚至把 Open Source 都複製一份,內部修改過後,檢查資安、安規、移除不必要的依賴,重新 Build 提供 Binary ,並規定只能使用這樣的版本。
Updated 2019/12/02: AWS 的新服務 EC2 Image Builder 就是我提到的 VM Images 層次的 Artifacts.
Artifact Metadata
Artifact 必須包含以下這些重要的資訊 (Metadata),讓其他人、或者程式可以串接:
AppName
:應用程式名稱,參閱 你的靈魂 - 談產品名稱的命名Version
:通常是三碼規則 (x.y.z), 詳細參閱 Version Control 或者 Semantic VersioningTimestamp
:Packing 的時間,通常是像 20180701-1200 這樣的結構BuildId
:簽入 (Commit/Checkin) 的序號:git hash or svn numberBuildType
:預先為正式環境、測試環境置入的Configuration
,這段依照產品特性,會有不同的作法。正式版通常會有以下:- 通常會有 Sign 一些東西,像是版權控管之類的
- 會有 md5checksun,作為傳輸檢查用
- 相依的資源都會有
Branch
:根據產品性質,可能會有特殊 Branch 的編號,像是客製化的版本。Meta
:其他 Build 的 Meta 資訊,可以讓 CI/CD 串接使用。
這些資訊是之後持續整合的關鍵資料,不管是自動化測試、還是部署、還是交付給其他單位。相關例子參閱:Version Control。如果要自動化串接,則可以提供 API,像是 github 的 Release API
相關參閱 Version Control
產出物的存放
Artifact 盡可能集中儲存在 Storage Services,讓需要的人透過身份驗證可以自行存取。
這個存放空間通常會規劃底下結構:
- Release: 每個釋出的版本,通常會有 sign + md5 checksum,樣子大概就是一般下載 open source 時看到的目錄結構
- Dev: 通常會依照各個 products / roles / components 再細分目錄
- 每個目錄都會有個叫
LATEST
的 softlink,連結最新的 build - 依照產品或者 component 特性,會額外放置其他資料,像是 metadata、sample config
- 每個目錄都會有個叫
早期我習慣然後透過 Apache Index 方式分享出來,也曾經做過比較複雜的 console 一鍵部署
。現代作法應該就是直接提供 API,可以取得 Artifact Meta 串接自動化。
底下是要注意的:
- Artifacts 會一直長,所以要有 rotation 機制。
- 如果是放在 AWS S3 則可以透過 Lifecycle 管理。
- 要注意是否要至少保留一定數量,避免太久沒有 build,最後全被刪光了。
類似的產品有:Artifactory, Nexus
不同目的的部署
在 淺談軟體測試的階段與策略 一文提到很多測試方法、策略,其實每種測試都有期目的性,考量的東西不一樣,需要的部署也不一樣,但是在邏輯與抽象架構概念,他們的部署、與架構方法,應該都是一致的!
- 功能性測試 (FVT):麻雀雖小,五臟俱全
- 整合性測試 (Integration):有彈性
- 系統性測試 (System Test):有彈性
不同測試目的,有不同的架構,不同架構有不同的部署方法,他們都需要同樣的 Artifacts
誰來觸發自動部署?
這篇文章:持续交付:当前普遍存在的三个问题与解决方案 最後的表格提到 Dev、Test、Acceptance、Production 四個環境,最後有部署者,其中測試是 CI 自動觸發 (自動部署)
,這點是有問題的。
真實的測試情境是這樣的,以下是簡單的過程:
- 測試人員部署指定的版本到指定的環境,透過手動 or 自動跑測試
- 測試人員發現問題,檢查系統的 Log 找問題、檢查測試資料、情境
- 測試人員想比較兩個版本的差異,確認問題,指定前一個版本,
重新部署環境
- 測試人員想比較兩個版本的差異,確認問題,指定某個版本,
重新部署環境
- 測試人員想比較兩個版本的差異,確認問題,指定前一個版本,
- 測試人員確認問題的原因,開始開 Defect,整理測試步驟、蒐集問題的 Log
這些過程是基本的,實際的可能更複雜,因為要跟 Developer or PM 確認問題,甚至要確認環境建置之類的。
如果這個過程,如果測試環境被 CI 自動觸發 (自動部署)
,整個現場就毀了!測試等於被中斷。
持續整合與部署的第一步
在讀書會 Continuous Delivery
裡,我其實都很強調這個概念:
- 你平常怎麼使用別人的軟體?
- 哪些人可以部署?
- Learning from Open Source Software
我不太強調怎麼部署工具這件事情,因為技術隨時代會不斷改變,不管是 Jenkins、Gitlab CI、Drone、AWS CodeDeploy … 因為這些都做得到我想要的事。但是往往錯誤的觀念,會誤導團隊的前進,嚴重的甚至會影響整個公司的發展。
我很強調要看到下面這張圖四個面向:
如何實踐團隊的自主性
底下的 Youtube 是摘錄我在內部教育訓練的影片,主要說明這段 前提
重要性,以及 讓團隊在技術上自主性
的重要性。相關的關鍵字有:自主性、DevOps, Architecture, CI/CD, Provisioning, Infra as Code, Artifact Management
捨本逐末,一步登天
過去,我一直覺得這應該是每個公司都會做的,所以很少提這段。最近發現,太多人都過於強調所謂 自動化部署
,反而忽略最基本的工作:
不知道應該要有 Artifact ,讓其他人可以獨立部署。
這代表什麼?這代表:
- 無法完整建立整個測試過程所需要的資源!沒有 Resource Provisioning 的概念
- 不知道測試會因目的,而有不同的配置,但架構邏輯是一樣的。表示沒有清楚的系統架構概念!沒有看到全貌!
- 測試人員無法自己部署!測試可能隨時被中斷!產品沒有品質
- 無法做其他進階測試,像是整合、效能、部署驗證等。
現代太多 CI/CD 工具都強調一鍵佈署,但是佈署到哪卻很少提,所以當要部署不同情境的需求時,因為太自動,反而失去該要有的彈性!
老人當年勇
為什麼我會一直強調這件事情,因為不管在 Artifacts 的建置、管理,或者在帶測試團隊的時候,Artifact 是關鍵點。底下是當年的足跡,也是 Designing Test Architecture and Framework 一文中沒提到的,因為我覺得這是基本功:
下圖是當時自動化測試的 Artifact 管理介面 (用 ZK 寫的),主要會自動 mirror 米國的 build,然後建立 aritfact metadata,重點:
- 有分 rel / dev 兩種
- 每組 artifacts 的 metadata 都在資料庫
- 由需要的人自行選擇要部署的版本 (right click)
底下這張圖是我在 協同合作系統建制與導入 - 以 Redmine 為例 提到的 Build,這段做得比較簡單,但是卻是最常見的做法:
Continuous Delivery – Opening
書開宗明義第一張就講了,這段話就是核心重點:
其他公開討論:
- 2018/08/03: DevOps Taiwan
- 2018/08/30: SRE Taiwan 的討論
SaaS 平台 (Updated: 2019/01/18)
下圖是 2018/07/24 我在 FB 上隨機問的小題目,這樣的條件是我定義的 產品服務化
的基本要素。而問這問題目的就是想了解大家對於 持續交付
的想像與應用,而這個題目就可直接創造出有意義的價值,交付價值的最大化,而要做到這一步的基本條件就是 Artifact Management 要做好。
符合這樣的產品很多,AWS 的 SaaS 都是,像是 ElastiCache、RDS,外面的產品像是 CloudAMQP、一些 Wordpress 的 Provider 都是。
PS: 圖中文字的 PaaS 應該更正為 SaaS
延伸閱讀
站內文章
- 個人著作《SRE 實踐與開發平台指南》 (2023/08 上市)
- 聊聊軟體交付的濫觴 談產出物管理 (Artifacts Management)
- 導入 CI/CD 的第一步
- 怎樣的 CI/CD 才夠 Quality?
- Designing Test Architecture and Framework
- Study Notes - CodeDeploy Preparation
- Software Development Lifecycle
- 緊急應變 (Emergency Response)
- Version Control
- Go Live
- 文件的持續交付
- 淺談軟體測試的階段與策略
- Resource Provisioning and DevOps
- 如何有效的回報問題 (How to Report Problems Effectively)
- 自動化帶來的問題
- 協同合作系統建制與導入 - 以 Redmine 為例
- 心得:持續交付 2.0
延伸閱讀
- Continuous Delivery - Opening
- 持续交付:当前普遍存在的三个问题与解决方案
- Release engineering
- Semantic Versioning
- AMI Creation with Aminator
- Version Numbers for Continuous Delivery with Maven and Docker
- 你的靈魂 - 談產品名稱的命名
更新紀錄
- 2019/01/18: 新增
Learning from Open Source Software (OSS)
、SaaS 栗子的段落
- 2019/12/02: 註記 AWS 的新服務 EC2 Image Builder