從一個 Git 儲存庫推出一組微服務
當應用程式被分成許多或多或少獨立的服務時,經常會發生這種情況。 這些服務的發布可以獨立進行:一次可以發布一個或多個服務,而其餘服務必須繼續工作而不做任何更改。 但從程式碼儲存和專案管理的角度來看,將此類應用程式服務保存在單一儲存庫中更為方便。
在某些情況下,服務是真正獨立的並且不與單一應用程式關聯。 在這種情況下,它們將位於不同的項目中,並且它們的發布將透過每個項目中單獨的 CI/CD 流程進行。
然而,實際上,開發人員經常將單個應用程式拆分為多個微服務,但為每個微服務創建單獨的存儲庫和項目......顯然是一種矯枉過正。 我們將進一步討論這種情況:多個此類微服務位於單一專案儲存庫中,並且透過 CI/CD 中的單一流程進行發布。
透過 Git 分支和 Git 標籤進行標記
假設使用最常見的標記策略 - 標籤或分支。 對於 Git 分支,映像以分支名稱標記,對於一個分支,一次只有一個以該分支名稱發布的映像。 對於 Git 標籤,圖像根據標籤名稱進行標記。
當建立新的 Git 標籤時(例如,發布新版本時),將為 Docker 註冊表中的所有專案映像建立一個新的 Docker 標籤:
-
myregistry.org/myproject/frontend:v1.1.10
-
myregistry.org/myproject/myservice1:v1.1.10
-
myregistry.org/myproject/myservice2:v1.1.10
-
myregistry.org/myproject/myservice3:v1.1.10
-
myregistry.org/myproject/myservice4:v1.1.10
-
myregistry.org/myproject/myservice5:v1.1.10
-
myregistry.org/myproject/database:v1.1.10
這些新的鏡像名稱透過 Helm 範本傳遞到 Kubernetes 配置。 使用命令啟動部署時 werf deploy
字段正在更新中 image
在 Kubernetes 資源清單中,由於鏡像名稱變更而重新啟動對應的資源。
問題:事實上,自上次發布(Git 標籤)以來,映像的內容沒有發生變化,而只有 Docker 標籤發生變化,就會發生這種情況 額外的 重新啟動此應用程序,因此可能會出現一些停機時間。 儘管沒有真正的理由執行此重啟。
因此,使用目前的標記方案,有必要隔離幾個單獨的 Git 儲存庫,並且出現了組織這幾個儲存庫的推出的問題。 一般來說,這樣的方案結果是超載且複雜的。 最好將許多服務合併到一個儲存庫中並建立 Docker 標籤,這樣就不會出現不必要的重新啟動。
透過 Git 提交標記
werf 還有一個與 Git 提交相關的標記策略。
Git-commit 是 Git 儲存庫內容的標識符,依賴 Git 儲存庫中檔案的編輯歷史記錄,因此使用它來標記 Docker 註冊表中的映像似乎是合乎邏輯的。
但是,透過 Git 提交進行標記與透過 Git 分支或 Git 標籤進行標記具有相同的缺點:
- 可以建立一個不更改任何檔案的空提交,但映像的 Docker 標記將被更改。
- 可以建立不更改檔案的合併提交,但映像的 Docker 標記將被更改。
- 可以進行提交來更改 Git 中未匯入映像中的那些文件,並且映像的 Docker 標記將再次變更。
標記 Git 分支名稱不反映鏡像版本
還有另一個與 Git 分支的標記策略相關的問題。
只要按時間順序順序收集該分支上的提交,就可以按分支名稱進行標記。
如果在目前方案中,使用者開始重建與某個分支關聯的舊提交,那麼 werf 將使用對應的 Docker 標籤和舊提交的新建置版本的映像來重寫映像。 從現在開始,使用此標籤的部署在重新啟動 pod 時存在拉取不同版本映像的風險,因此我們的應用程式將失去與 CI 系統的連線並變得不同步。
此外,如果連續推送到一個分支且時間間隔很短,則舊提交的編譯時間可能會晚於新提交:舊版本的映像將使用 Git 分支標籤覆蓋新版本。 此類問題可以透過 CI/CD 系統來解決(例如,在 GitLab CI 中,後者的管道是針對一系列提交啟動的)。 然而,並非所有系統都支援這一點,必須有更可靠的方法來防止這種根本問題。
什麼是基於內容的標記?
那麼,什麼是基於內容的標記——按內容標記圖像。
要建立 Docker 標籤,使用的不是 Git 原語(Git 分支、Git 標籤...),而是與以下內容關聯的校驗和:
- 圖像的內容。 圖像ID標籤反映其內容。 當建構新版本時,如果鏡像中的檔案沒有改變,這個標識符也不會改變;
- 在 Git 中建立此映像的歷史記錄。 與不同 Git 分支和透過 werf 的不同建構歷史關聯的映像將具有不同的 ID 標籤。
這樣的識別符標籤就是所謂的 影像階段簽名.
每個影像由一組階段組成: from
, before-install
, git-archive
, install
, imports-after-install
, before-setup
,... git-latest-patch
ETC。 每個階段都有一個反映其內容的識別碼 - 舞台簽名 (舞台簽名).
由這些階段組成的最終影像被標記為這些階段組的所謂簽名 - 階段簽名, - 這概括了圖像的所有階段。
對於配置中的每個影像 werf.yaml
一般情況下,會有自己的簽名,以及對應的 Docker 標籤。
階段簽名解決了所有這些問題:
- 抵抗空 Git 提交。
- 抵抗 Git 提交更改與圖像不相關的檔案。
- 當為分支的舊 Git 提交重新啟動建置時,不會導致徹底修改目前版本的映像的問題。
這是現在建議的標記策略,也是所有 CI 系統 werf 中的預設策略。
如何在werf中啟用和使用
該命令現在有相應的選項 werf publish
: --tag-by-stages-signature=true|false
在 CI 系統中,標記策略由指令指定 werf ci-env
。 之前為它定義了參數 werf ci-env --tagging-strategy=tag-or-branch
。 現在,如果您指定 werf ci-env --tagging-strategy=stages-signature
或不指定該選項,werf將預設使用標記策略 stages-signature
. 團隊 werf ci-env
將自動為命令設定必要的標誌 werf build-and-publish
(或者 werf publish
),因此不需要為這些命令指定其他選項。
例如,命令:
werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature
...可以建立以下圖像:
-
registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
-
registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6
這裡 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
是影像階段的簽名 backend
和 f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6
- 影像階段的簽名 frontend
.
使用特殊功能時 werf_container_image
и werf_container_env
無需更改 Helm 模板中的任何內容:這些函數將自動產生正確的圖像名稱。
CI 系統中的設定範例:
type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deploy
有關配置的更多資訊可在文件中找到:
在總
- 新選項
werf publish --tag-by-stages-signature=true|false
. - 新的選擇權價值
werf ci-env --tagging-strategy=stages-signature|tag-or-branch
(如果沒有指定,則預設為stages-signature
). - 如果您之前使用過 Git 提交的標記選項 (
WERF_TAG_GIT_COMMIT
或選項werf publish --tag-git-commit COMMIT
),那麼一定要切換到標記策略 階段簽名. - 最好立即將新項目切換到新的標記方案。
- 轉移到werf 1.1時,建議將舊項目切換到新標記方案,但舊項目 標籤或分支 仍然支持。
基於內容的標記解決了本文中涉及的所有問題:
- Docker 標記名稱對空 Git 提交的抵抗力。
- Docker 標籤名稱對 Git 提交的彈性,可變更與映像無關的檔案。
- 當重新啟動 Git 分支的舊 Git 提交建置時,不會導致徹底修改目前版本的鏡像的問題。
用它! 並且不要忘記訪問我們
聚苯乙烯
另請閱讀我們的博客:
- «
werf 1.1 版本:目前建構器的改進以及未來的計劃 » - «
介紹 werf 1.0 stable:GitOps 與它有什麼關係、狀態和計劃 » - «
werf - 我們在 Kubernetes 中的 CI / CD 工具(概述和視頻報告) “; - 關於werf創新的一系列註解:
來源: www.habr.com