BuildKit

概述

BuildKit 是一個改進的後端,用於替換舊版構建器。從 Docker Desktop 上的使用者和 Docker Engine 23.0 版本開始,BuildKit 是預設的構建器。

BuildKit 提供新功能並提高構建效能。它還引入了對處理更復雜場景的支援。

  • 檢測並跳過執行未使用的構建階段
  • 並行構建獨立的構建階段
  • 在構建之間僅增量傳輸構建上下文中更改的檔案
  • 檢測並跳過傳輸構建上下文中未使用的檔案
  • 使用具有許多新功能的Dockerfile 前端實現
  • 避免與 API 的其餘部分(中間映象和容器)產生副作用
  • 優先處理構建快取以進行自動清理

除了許多新功能之外,BuildKit 在當前體驗中改進的主要領域是效能、儲存管理和可擴充套件性。在效能方面,一個重要的更新是一個全新的完全併發構建圖求解器。它可以在可能的情況下並行執行構建步驟,並最佳化對最終結果沒有影響的命令。對本地原始檔的訪問也得到了最佳化。透過僅跟蹤在重複構建呼叫之間對這些檔案進行的更新,無需等待讀取或上傳本地檔案即可開始工作。

LLB

BuildKit 的核心是低階構建 (LLB) 定義格式。LLB 是一種中間二進位制格式,允許開發人員擴充套件 BuildKit。LLB 定義了一個內容可定址的依賴圖,可用於組合複雜的構建定義。它還支援 Dockerfile 中未公開的功能,例如直接資料掛載和巢狀呼叫。

關於構建的執行和快取的一切都在 LLB 中定義。與舊版構建器相比,快取模型完全重寫。LLB 不再使用啟發式方法比較映象,而是直接跟蹤構建圖和掛載到特定操作的內容的校驗和。這使其速度更快、更精確且可移植。構建快取甚至可以匯出到登錄檔,然後可以在任何主機上通過後續呼叫按需拉取。

LLB 可以直接使用golang 客戶端包生成,該包允許使用 Go 語言原語定義構建操作之間的關係。這使您能夠完全自由地執行任何您可以想象的東西,但可能不是大多數人定義構建的方式。相反,大多數使用者會使用前端元件或 LLB 巢狀呼叫來執行一組預備的構建步驟。

前端

前端是一個元件,它接收人類可讀的構建格式並將其轉換為 LLB,以便 BuildKit 可以執行它。前端可以作為映象分發,使用者可以針對特定版本的前端,該版本保證適用於其定義使用的功能。

例如,要使用 BuildKit 構建Dockerfile,您將使用外部 Dockerfile 前端

入門

BuildKit 是 Docker Desktop 使用者和 Docker Engine v23.0 及更高版本的預設構建器。

如果您安裝了 Docker Desktop,則無需啟用 BuildKit。如果您執行的是早於 23.0 版本的 Docker Engine,則可以透過設定環境變數或將 BuildKit 設定為守護程式配置中的預設設定來啟用 BuildKit。

要在執行 `docker build` 命令時設定 BuildKit 環境變數,請執行

$ DOCKER_BUILDKIT=1 docker build .
注意

Buildx 總是使用 BuildKit。

要預設使用 Docker BuildKit,請按如下方式編輯 `/etc/docker/daemon.json` 中的 Docker 守護程式配置,然後重新啟動守護程式。

{
  "features": {
    "buildkit": true
  }
}

如果 `/etc/docker/daemon.json` 檔案不存在,請建立一個名為 `daemon.json` 的新檔案,然後將以下內容新增到該檔案中。然後重新啟動 Docker 守護程式。

Windows 上的 BuildKit

警告

BuildKit 僅完全支援構建 Linux 容器。Windows 容器支援尚處於實驗階段。

BuildKit 從 0.13 版開始對 Windows 容器 (WCOW) 提供實驗性支援。本節將引導您完成試用步驟。要提供反饋,請在倉庫中提交問題,特別是 `buildkitd.exe`。

已知限制

有關 BuildKit 在 Windows 上開放錯誤和限制的資訊,請參閱GitHub 問題

先決條件

  • 架構:`amd64`、`arm64`(二進位制檔案可用但尚未正式測試)。
  • 支援的作業系統:Windows Server 2019、Windows Server 2022、Windows 11。
  • 基礎映象:`ServerCore:ltsc2019`、`ServerCore:ltsc2022`、`NanoServer:ltsc2022`。請參閱此處相容性圖
  • Docker Desktop 4.29 或更高版本

步驟

注意

以下命令需要在 PowerShell 終端中具有管理員(提升)許可權。

  1. 啟用 **Hyper-V** 和 **Containers** Windows 功能。

    > Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V, Containers -All
    

    如果看到 `RestartNeeded` 為 `True`,請重新啟動機器並以管理員身份重新開啟 PowerShell 終端。否則,繼續執行下一步。

  2. 在 Docker Desktop 中切換到 Windows 容器。

    選擇工作列中的 Docker 圖示,然後選擇 **Switch to Windows containers...**。

  3. 按照此處的設定說明安裝 containerd 1.7.7 或更高版本。

  4. 下載並解壓最新的 BuildKit 版本。

    $version = "v0.22.0" # specify the release version, v0.13+
    $arch = "amd64" # arm64 binary available too
    curl.exe -LO https://github.com/moby/buildkit/releases/download/$version/buildkit-$version.windows-$arch.tar.gz
    # there could be another `.\bin` directory from containerd instructions
    # you can move those
    mv bin bin2
    tar.exe xvf .\buildkit-$version.windows-$arch.tar.gz
    ## x bin/
    ## x bin/buildctl.exe
    ## x bin/buildkitd.exe
  5. 在 `PATH` 上安裝 BuildKit 二進位制檔案。

    # after the binaries are extracted in the bin directory
    # move them to an appropriate path in your $Env:PATH directories or:
    Copy-Item -Path ".\bin" -Destination "$Env:ProgramFiles\buildkit" -Recurse -Force
    # add `buildkitd.exe` and `buildctl.exe` binaries in the $Env:PATH
    $Path = [Environment]::GetEnvironmentVariable("PATH", "Machine") + `
        [IO.Path]::PathSeparator + "$Env:ProgramFiles\buildkit"
    [Environment]::SetEnvironmentVariable( "Path", $Path, "Machine")
    $Env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + `
        [System.Environment]::GetEnvironmentVariable("Path","User")
  6. 啟動 BuildKit 守護程式。

    > buildkitd.exe
    
    注意

    如果您正在執行 *dockerd-managed* `containerd` 程序,請透過提供地址來使用它:`buildkitd.exe --containerd-worker-addr "npipe:////./pipe/docker-containerd"`

  7. 在另一個具有管理員許可權的終端中,建立一個使用本地 BuildKit 守護程式的遠端構建器。

    注意

    這需要 Docker Desktop 4.29 或更高版本。

    > docker buildx create --name buildkit-exp --use --driver=remote npipe:////./pipe/buildkitd
    buildkit-exp
    
  8. 透過執行 `docker buildx inspect` 驗證構建器連線。

    > docker buildx inspect
    

    輸出應表明構建器平臺為 Windows,並且構建器端點為命名管道。

    Name:          buildkit-exp
     Driver:        remote
     Last Activity: 2024-04-15 17:51:58 +0000 UTC
     Nodes:
     Name:             buildkit-exp0
     Endpoint:         npipe:////./pipe/buildkitd
     Status:           running
     BuildKit version: v0.13.1
     Platforms:        windows/amd64
    ...
  9. 建立一個 Dockerfile 並構建 `hello-buildkit` 映象。

    > mkdir sample_dockerfile
    > cd sample_dockerfile
    > Set-Content Dockerfile @"
    FROM mcr.microsoft.com/windows/nanoserver:ltsc2022
    USER ContainerAdministrator
    COPY hello.txt C:/
    RUN echo "Goodbye!" >> hello.txt
    CMD ["cmd", "/C", "type C:\\hello.txt"]
    "@
    Set-Content hello.txt @"
    Hello from BuildKit!
    This message shows that your installation appears to be working correctly.
    "@
    
  10. 構建並將映象推送到登錄檔。

    > docker buildx build --push -t <username>/hello-buildkit .
    
  11. 推送到登錄檔後,使用 `docker run` 執行映象。

    > docker run <username>/hello-buildkit