您現在可以使用常規 Dockerfile 在 werf 中構建 Docker 鏡像

遲到總比不到好。 或者我們幾乎犯了一個嚴重的錯誤,因為不支援常規 Dockerfile 來建立應用程式映像。

您現在可以使用常規 Dockerfile 在 werf 中構建 Docker 鏡像

我們將討論 韋爾夫 — GitOps 實用程序,可與任何 CI/CD 系統整合並提供整個應用程式生命週期的管理,從而允許:

  • 收集並發布圖像,
  • 在 Kubernetes 中部署應用程序,
  • 使用特殊策略刪除未使用的影像。


該專案的理念是將低階工具收集到一個統一的系統中,使 DevOps 工程師能夠控制應用程式。 如果可能,應使用現有實用程式(例如 Helm 和 Docker)。 如果問題無法解決,我們可以為此創造並支持一切必要的東西。

背景:您自己的圖像收集器

這就是 werf 中映像收集器發生的情況:通常的 Dockerfile 對我們來說不夠。 如果你快速瀏覽一下該專案的歷史,你會發現這個問題已經出現在 werf 的第一個版本中(然後仍然存在) 稱為 dapp).

在創建用於將應用程式建置到 Docker 映像中的工具時,我們很快就意識到 Dockerfile 不適合我們執行一些非常具體的任務:

  1. 需要依照以下標準方案建構典型的小型Web應用:
    • 安裝系統範圍的應用程式依賴項,
    • 安裝一組應用程式依賴庫,
    • 收集資產,
    • 最重要的是,快速且有效率地更新鏡像中的程式碼。
  2. 當對專案文件進行更改時,建構者必須透過對更改的文件套用補丁來快速建立新層。
  3. 如果某些文件發生了變化,那麼就需要重建相應的依賴階段。

今天,我們的收藏家還有許多其他的可能性,但這些都是最初的願望和衝動。

一般來說,我們不假思索地用我們所使用的程式語言武裝自己 (見下文) 並踏上實施之路 自己的DSL! 根據目標,旨在分階段描述組裝過程並確定這些階段對文件的依賴性。 並對其進行了補充 自己的收藏家,這將DSL變成了最終目標——組裝圖像。 起初 DSL 是用 Ruby 寫的,但隨著 過渡到 Golang — 我們的收集器的設定開始在 YAML 檔案中描述。

您現在可以使用常規 Dockerfile 在 werf 中構建 Docker 鏡像
Ruby 中 dapp 的舊配置

您現在可以使用常規 Dockerfile 在 werf 中構建 Docker 鏡像
YAML 上 werf 的目前配置

隨著時間的推移,收集器的機制也發生了變化。 首先,我們只是根據配置動態產生一個臨時 Dockerfile,然後開始在臨時容器中執行彙編指令並提交。

NB:目前,我們的收集器使用自己的配置(在 YAML 中),稱為 Stapel 收集器,已經發展成為一個相當強大的工具。 其詳細描述值得單獨撰寫文章,基本細節可以在 文件.

對問題的認識

但我們並沒有立即意識到我們犯了一個錯誤:我們沒有添加這種能力 透過標準 Dockerfile 建置映像 並將它們整合到相同的端到端應用程式管理基礎架構中(即收集映像、部署和清理它們)。 怎麼可能製作一個在 Kubernetes 中部署的工具而不實現 Dockerfile 支持,即描述大多數項目圖像的標準方法?...

我們不回答這個問題,而是提供一個解決方案。 如果您已經有一個 Dockerfile(或一組 Dockerfile)並且想要使用 werf,該怎麼辦?

NB:順便問一下,為什麼要使用 werf? 主要特點如下:

  • 完整的應用程式管理週期,包括影像清理;
  • 能夠透過單一配置同時管理多個影像的組合;
  • 改進了 Helm 相容圖表的部署流程。

更完整的清單可以在以下位置找到: 專案頁面.

因此,如果早些時候我們願意在配置中重寫 Dockerfile,那麼現在我們會很高興地說:“讓 werf 建立您的 Dockerfile!”

如何使用?

此功能的完整實作出現在發行版中 werf v1.0.3-beta.1。 整體原理很簡單:使用者在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:

您現在可以使用常規 Dockerfile 在 werf 中構建 Docker 鏡像

此外,您也可以聲明以下內容 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 配置整合到其基礎架構中。 這是什麼意思?

  1. 從 Dockerfile 建構的每個映像都包含一個稱為 dockerfile (您可以閱讀更多有關 werf 中的階段的信息 這裡).
  2. 舞台用 dockerfile werf 計算取決於 Dockerfile 設定內容的簽章。 當 Dockerfile 配置更改時,階段簽名會更改 dockerfile werf 使用新的 Dockerfile 設定啟動此階段的重建。 如果簽章沒有改變,則werf從快取中取得影像 (有關在 werf 中使用簽名的更多詳細信息,請參閱 這份報告).
  3. 接下來,可以使用命令發布收集到的圖像 werf publish (或者 werf build-and-publish)並使用它來部署到 Kubernetes。 發佈到 Docker 註冊表的映像將使用標準 werf 清理工具進行清理,即舊鏡像(超過 N 天)、與不存在的 Git 分支關聯的鏡像以及其他策略將自動清理。

有關此處描述的要點的更多詳細資訊可以在文件中找到:

注意事項及注意事項

1.ADD不支援外部URL

目前不支援在指令中使用外部 URL ADD。 當指定 URL 處的資源發生變更時,Werf 不會啟動重建。 我們計劃很快添加此功能。

2. 無法將.git加入到鏡像中

一般來說,增加一個目錄 .git 在圖像中 - 這是一種惡毒的不良做法,原因如下:

  1. 如果 .git 保留在最終圖像中,這違反了原則 12 因素應用程式:由於最終圖像必須連結到單一提交,因此不可能這樣做 git checkout 任意提交。
  2. .git 增加圖像的大小(儲存庫可能會很大,因為大檔案曾經被添加到其中然後被刪除)。 僅與特定提交關聯的工作樹的大小不依賴 Git 中的操作歷史記錄。 在這種情況下,新增和隨後的刪除 .git 從最終的映像中將無法運作:映像仍然會獲得一個額外的圖層——這就是 Docker 的工作原理。
  3. 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 有關該主題的文檔列表

另請閱讀我們的部落格:“werf - 我們在 Kubernetes 中的 CI / CD 工具(概述和視頻報告)“。

來源: www.habr.com

添加評論