遲到總比不到好。 或者我們幾乎犯了一個嚴重的錯誤,因為不支援常規 Dockerfile 來建立應用程式映像。
我們將討論
- 收集並發布圖像,
- 在 Kubernetes 中部署應用程序,
- 使用特殊策略刪除未使用的影像。
該專案的理念是將低階工具收集到一個統一的系統中,使 DevOps 工程師能夠控制應用程式。 如果可能,應使用現有實用程式(例如 Helm 和 Docker)。 如果問題無法解決,我們可以為此創造並支持一切必要的東西。
背景:您自己的圖像收集器
這就是 werf 中映像收集器發生的情況:通常的 Dockerfile 對我們來說不夠。 如果你快速瀏覽一下該專案的歷史,你會發現這個問題已經出現在 werf 的第一個版本中(然後仍然存在)
在創建用於將應用程式建置到 Docker 映像中的工具時,我們很快就意識到 Dockerfile 不適合我們執行一些非常具體的任務:
- 需要依照以下標準方案建構典型的小型Web應用:
- 安裝系統範圍的應用程式依賴項,
- 安裝一組應用程式依賴庫,
- 收集資產,
- 最重要的是,快速且有效率地更新鏡像中的程式碼。
- 當對專案文件進行更改時,建構者必須透過對更改的文件套用補丁來快速建立新層。
- 如果某些文件發生了變化,那麼就需要重建相應的依賴階段。
今天,我們的收藏家還有許多其他的可能性,但這些都是最初的願望和衝動。
一般來說,我們不假思索地用我們所使用的程式語言武裝自己 (見下文) 並踏上實施之路 自己的DSL! 根據目標,旨在分階段描述組裝過程並確定這些階段對文件的依賴性。 並對其進行了補充 自己的收藏家,這將DSL變成了最終目標——組裝圖像。 起初 DSL 是用 Ruby 寫的,但隨著
Ruby 中 dapp 的舊配置
YAML 上 werf 的目前配置
隨著時間的推移,收集器的機制也發生了變化。 首先,我們只是根據配置動態產生一個臨時 Dockerfile,然後開始在臨時容器中執行彙編指令並提交。
NB:目前,我們的收集器使用自己的配置(在 YAML 中),稱為 Stapel 收集器,已經發展成為一個相當強大的工具。 其詳細描述值得單獨撰寫文章,基本細節可以在
對問題的認識
但我們並沒有立即意識到我們犯了一個錯誤:我們沒有添加這種能力 透過標準 Dockerfile 建置映像 並將它們整合到相同的端到端應用程式管理基礎架構中(即收集映像、部署和清理它們)。 怎麼可能製作一個在 Kubernetes 中部署的工具而不實現 Dockerfile 支持,即描述大多數項目圖像的標準方法?...
我們不回答這個問題,而是提供一個解決方案。 如果您已經有一個 Dockerfile(或一組 Dockerfile)並且想要使用 werf,該怎麼辦?
NB:順便問一下,為什麼要使用 werf? 主要特點如下:
- 完整的應用程式管理週期,包括影像清理;
- 能夠透過單一配置同時管理多個影像的組合;
- 改進了 Helm 相容圖表的部署流程。
更完整的清單可以在以下位置找到:
因此,如果早些時候我們願意在配置中重寫 Dockerfile,那麼現在我們會很高興地說:“讓 werf 建立您的 Dockerfile!”
如何使用?
此功能的完整實作出現在發行版中 werf build
....就是這樣 - werf 將組裝圖像。 讓我們來看一個抽象的例子。
讓我們宣布下一篇 Dockerfile
在專案根目錄中:
FROM ubuntu:18.04
RUN echo Building ...
我們將宣布 werf.yaml
它使用這個 Dockerfile
:
configVersion: 1
project: dockerfile-example
---
image: ~
dockerfile: ./Dockerfile
全部! 左邊 跑 werf build
:
此外,您也可以聲明以下內容 werf.yaml
一次從不同的 Dockerfile 建置多個映像:
configVersion: 1
project: dockerfile-example
---
image: backend
dockerfile: ./dockerfiles/Dockerfile-backend
---
image: frontend
dockerfile: ./dockerfiles/Dockerfile-frontend
最後,它還支援傳遞額外的建置參數,例如 --build-arg
и --add-host
- 透過werf配置。 Dockerfile 映像配置的完整描述可在下列位置找到:
它是如何工作的呢?
在建置過程中,Docker 中本機層的標準快取發揮作用。 然而,重要的是 werf 也 將 Dockerfile 配置整合到其基礎架構中。 這是什麼意思?
- 從 Dockerfile 建構的每個映像都包含一個稱為
dockerfile
(您可以閱讀更多有關 werf 中的階段的信息這裡 ). - 舞台用
dockerfile
werf 計算取決於 Dockerfile 設定內容的簽章。 當 Dockerfile 配置更改時,階段簽名會更改dockerfile
werf 使用新的 Dockerfile 設定啟動此階段的重建。 如果簽章沒有改變,則werf從快取中取得影像 (有關在 werf 中使用簽名的更多詳細信息,請參閱這份報告 ). - 接下來,可以使用命令發布收集到的圖像
werf publish
(或者werf build-and-publish
)並使用它來部署到 Kubernetes。 發佈到 Docker 註冊表的映像將使用標準 werf 清理工具進行清理,即舊鏡像(超過 N 天)、與不存在的 Git 分支關聯的鏡像以及其他策略將自動清理。
有關此處描述的要點的更多詳細資訊可以在文件中找到:
注意事項及注意事項
1.ADD不支援外部URL
目前不支援在指令中使用外部 URL ADD
。 當指定 URL 處的資源發生變更時,Werf 不會啟動重建。 我們計劃很快添加此功能。
2. 無法將.git加入到鏡像中
一般來說,增加一個目錄 .git
在圖像中 - 這是一種惡毒的不良做法,原因如下:
- 如果
.git
保留在最終圖像中,這違反了原則12 因素應用程式 :由於最終圖像必須連結到單一提交,因此不可能這樣做git checkout
任意提交。 -
.git
增加圖像的大小(儲存庫可能會很大,因為大檔案曾經被添加到其中然後被刪除)。 僅與特定提交關聯的工作樹的大小不依賴 Git 中的操作歷史記錄。 在這種情況下,新增和隨後的刪除.git
從最終的映像中將無法運作:映像仍然會獲得一個額外的圖層——這就是 Docker 的工作原理。 - Docker 可以啟動不必要的重建,即使正在建立相同的提交,但來自不同的工作樹。 例如,GitLab 在以下位置建立單獨的克隆目錄
/home/gitlab-runner/builds/HASH/[0-N]/yourproject
當啟用並行組裝時。 額外的重組將是由於目錄.git
即使建置了相同的提交,同一儲存庫的不同克隆版本也是不同的。
最後一點在使用 werf 時也會產生影響。 Werf 要求在執行某些命令時(例如 werf deploy
)。 當這些命令運行時,werf 會計算指定影像的階段簽名 werf.yaml
,並且它們必須位於組件快取中 - 否則該命令將無法繼續工作。 如果舞台簽名取決於內容 .git
,然後我們得到一個對不相關文件的更改不穩定的緩存,並且 werf 將無法原諒這種疏忽(有關更多詳細信息,請參閱
整體 僅添加某些必要的文件 透過說明 ADD
在任何情況下都會提高書面的效率和可靠性 Dockerfile
,並且還提高了為此收集的快取的穩定性 Dockerfile
,到 Git 中不相關的變更。
總
我們為特定需求編寫自己的建構器的最初路徑是艱難、誠實和直接的:我們沒有在標準 Dockerfile 之上使用拐杖,而是使用自訂語法編寫了我們的解決方案。 這有它的優點:Stapel 收集器完美地完成了它的任務。
然而,在編寫我們自己的建構器的過程中,我們忽略了對現有 Dockerfile 的支援。 這個缺陷現已修復,將來我們計劃開發Dockerfile 支援以及我們的自訂Stapel 建構器,用於分散式組裝和使用Kubernetes 進行組裝(即在Kubernetes 內的運行器上進行組裝,如kaniko 中所做的那樣)。
所以,如果你突然有幾個 Dockerfile ...... 嘗試
PS 有關該主題的文檔列表
-
快速入門指南 ; -
dockerfile 建構器配置 ; -
werf 中的階段設備 ; -
圖片發布流程 ; -
與 Kubernetes 部署流程集成 ; -
清洗工藝 ; -
Stapel 建構器作為 Dockerfile 的替代品 .
另請閱讀我們的部落格:“
來源: www.habr.com