構建垃圾回收

雖然 docker builder prunedocker buildx prune 命令會立即執行,但垃圾回收 (GC) 會定期執行並遵循有序的清除策略列表。當快取大小變得太大或快取過期時,BuildKit 守護程序會清除構建快取。

對於大多數使用者來說,預設的 GC 行為已足夠,無需任何干預。高階使用者,特別是那些處理大規模構建、自管理構建器或受限儲存環境的使用者,可能會受益於自定義這些設定,以更好地適應其工作流程需求。以下部分將解釋 GC 的工作原理,並提供透過自定義配置調整其行為的指導。

垃圾回收策略

GC 策略定義了一組規則,用於確定如何管理和清理構建快取。這些策略包括何時刪除快取條目的標準,例如快取的年齡、使用的空間量以及要清除的快取記錄型別。

每個 GC 策略都會按順序評估,從最具體的標準開始,如果之前的策略未能釋放足夠的快取,則會繼續執行更廣泛的規則。這使得 BuildKit 能夠優先處理快取條目,在保留最有價值的快取的同時,確保系統保持效能和可用性。

例如,假設您有以下 GC 策略:

  1. 查詢過去 48 小時內未使用的“陳舊”快取記錄,並刪除記錄,直到“陳舊”快取最多剩下 5GB。
  2. 如果構建快取大小超過 10GB,請刪除記錄,直到總快取大小不超過 10GB。

第一條規則更具體,優先處理陳舊快取記錄,併為價值較低的快取型別設定較低的限制。第二條規則施加了適用於任何型別快取記錄的更高硬限制。有了這些策略,如果您有 11GB 的構建快取,其中:

  • 其中 7GB 是“陳舊”快取
  • 4GB 是其他更有價值的快取

GC 清理將刪除 5GB 的陳舊快取作為第一個策略的一部分,剩餘 6GB,這意味著第二個策略不需要清除更多快取。

預設 GC 策略(大致)為:

  1. 如果快取已超過 48 小時未使用,則刪除可以輕鬆重新生成的快取,例如來自本地目錄或遠端 Git 儲存庫的構建上下文以及快取掛載。
  2. 刪除 60 天以上未在構建中使用的快取。
  3. 刪除超出構建快取大小限制的非共享快取。非共享快取記錄是指未被其他資源(通常是作為映象層)使用的層 blob。
  4. 刪除超出構建快取大小限制的任何構建快取。

確切的演算法和配置策略的方式略有不同,具體取決於您使用的構建器型別。有關更多詳細資訊,請參閱配置

配置

注意

如果您對預設的垃圾回收行為感到滿意,並且不需要微調其設定,則可以跳過此部分。預設配置適用於大多數用例,無需額外設定。

根據您使用的構建驅動程式型別,您將使用不同的配置檔案來更改構建器的 GC 設定:

Docker 守護程序配置檔案

如果您使用的是預設的 `docker` 驅動程式,GC 在 `daemon.json` 配置檔案中配置,或者如果您使用 Docker Desktop,則在 **設定 > Docker Engine** 中配置。

以下程式碼片段顯示了 Docker Desktop 使用者 `docker` 驅動程式的預設構建器配置:

{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  }
}

`defaultKeepStorage` 選項配置構建快取的大小限制,這會影響 GC 策略。 `docker` 驅動程式的預設策略工作方式如下:

  1. 如果瞬時、未使用的構建快取超過 `defaultKeepStorage` 的 13.8% 或至少 512MB 並且已超過 48 小時,則將其刪除。
  2. 刪除 60 天以上未使用的構建快取。
  3. 刪除超出 `defaultKeepStorage` 限制的非共享構建快取。
  4. 刪除超出 `defaultKeepStorage` 限制的任何構建快取。

鑑於 Docker Desktop 的 `defaultKeepStorage` 預設值為 20GB,預設 GC 策略解析為:

{
  "builder": {
    "gc": {
      "enabled": true,
      "policy": [
        {
          "keepStorage": "2.764GB",
          "filter": [
            "unused-for=48h",
            "type==source.local,type==exec.cachemount,type==source.git.checkout"
          ]
        },
        { "keepStorage": "20GB", "filter": ["unused-for=1440h"] },
        { "keepStorage": "20GB" },
        { "keepStorage": "20GB", "all": true }
      ]
    }
  }
}

調整 `docker` 驅動程式的構建快取配置最簡單的方法是調整 `defaultKeepStorage` 選項:

  • 如果您覺得 GC 過於激進,請增加限制。
  • 如果需要節省空間,請減小限制。

如果您需要更多控制,可以直接定義自己的 GC 策略。以下示例定義了一個更保守的 GC 配置,包含以下策略:

  1. 如果構建快取超過 50GB,則刪除超過 1440 小時(即 60 天)未使用的快取條目。
  2. 如果構建快取超過 50GB,則刪除非共享快取條目。
  3. 如果構建快取超過 100GB,則刪除任何快取條目。
{
  "builder": {
    "gc": {
      "enabled": true,
      "defaultKeepStorage": "50GB",
      "policy": [
        { "keepStorage": "0", "filter": ["unused-for=1440h"] },
        { "keepStorage": "0" },
        { "keepStorage": "100GB", "all": true }
      ]
    }
  }
}

這裡的策略 1 和 2 將 `keepStorage` 設定為 `0`,這意味著它們將回退到 `defaultKeepStorage` 定義的預設限制 50GB。

BuildKit 配置檔案

對於 `docker` 以外的構建驅動程式,GC 是使用 `buildkitd.toml` 配置檔案配置的。此檔案使用以下高階配置選項,您可以使用它們來調整 BuildKit 應用於快取的磁碟空間閾值:

選項描述預設值
reservedSpace(保留空間)BuildKit 允許為快取分配的最小磁碟空間量。低於此閾值的使用量在垃圾回收期間不會被回收。總磁碟空間的 10% 或 10GB(以較低者為準)
maxUsedSpace(最大已用空間)BuildKit 允許使用的最大磁碟空間量。超出此閾值的使用量將在垃圾回收期間被回收。總磁碟空間的 60% 或 100GB(以較低者為準)
minFreeSpace(最小可用空間)必須保留的可用磁碟空間量。20GB

您可以將這些選項設定為位元組數、單位字串(例如,`512MB`),或總磁碟大小的百分比。更改這些選項會影響 BuildKit worker 使用的預設 GC 策略。在預設閾值下,GC 策略解析如下:

# Global defaults
[worker.oci]
  gc = true
  reservedSpace = "10GB"
  maxUsedSpace = "100GB"
  minFreeSpace = "20%"

# Policy 1
[[worker.oci.gcpolicy]]
  filters = [ "type==source.local", "type==exec.cachemount", "type==source.git.checkout" ]
  keepDuration = "48h"
  maxUsedSpace = "512MB"

# Policy 2
[[worker.oci.gcpolicy]]
  keepDuration = "1440h" # 60 days
  reservedSpace = "10GB"
  maxUsedSpace = "100GB"

# Policy 3
[[worker.oci.gcpolicy]]
  reservedSpace = "10GB"
  maxUsedSpace = "100GB"

# Policy 4
[[worker.oci.gcpolicy]]
  all = true
  reservedSpace = "10GB"
  maxUsedSpace = "100GB"

實際情況是:

  • 策略 1:如果構建快取超過 512MB,BuildKit 將刪除 48 小時內未使用的本地構建上下文、遠端 Git 上下文和快取掛載的快取記錄。
  • 策略 2:如果磁碟使用量超過 100GB,將刪除 60 天以上未使用的非共享構建快取,確保至少保留 10GB 磁碟空間用於快取。
  • 策略 3:如果磁碟使用量超過 100GB,將刪除任何非共享快取,確保至少保留 10GB 磁碟空間用於快取。
  • 策略 4:如果磁碟使用量超過 100GB,將刪除所有快取(包括共享和內部記錄),確保至少保留 10GB 磁碟空間用於快取。

`reservedSpace` 在定義構建快取大小下限方面具有最高優先順序。如果 `maxUsedSpace` 或 `minFreeSpace` 會定義較低的值,則最小快取大小永遠不會低於 `reservedSpace`。

如果同時設定了 `reservedSpace` 和 `maxUsedSpace`,則 GC 清理後快取大小將在這些閾值之間。例如,如果 `reservedSpace` 設定為 10GB,`maxUsedSpace` 設定為 20GB,則 GC 執行後生成的快取量將小於 20GB,但至少為 10GB。

您還可以定義完全自定義的 GC 策略。自定義策略還允許您定義過濾器,讓您能夠精確指定給定策略可以清除的快取條目型別。

BuildKit 中的自定義 GC 策略

自定義 GC 策略允許您微調 BuildKit 管理其快取的方式,並根據快取型別、持續時間或磁碟空間閾值等標準,完全控制快取保留。如果您需要完全控制快取閾值以及快取記錄的優先順序,那麼定義自定義 GC 策略是最佳選擇。

要定義自定義 GC 策略,請在 `buildkitd.toml` 中使用 `[[worker.oci.gcpolicy]]` 配置塊。每個策略定義將用於該策略的閾值。如果您使用自定義策略,則 `reservedSpace`、`maxUsedSpace` 和 `minFreeSpace` 的全域性值將不適用。

這是一個示例配置:

# Custom GC Policy 1: Remove unused local contexts older than 24 hours
[[worker.oci.gcpolicy]]
  filters = ["type==source.local"]
  keepDuration = "24h"
  reservedSpace = "5GB"
  maxUsedSpace = "50GB"

# Custom GC Policy 2: Remove remote Git contexts older than 30 days
[[worker.oci.gcpolicy]]
  filters = ["type==source.git.checkout"]
  keepDuration = "720h"
  reservedSpace = "5GB"
  maxUsedSpace = "30GB"

# Custom GC Policy 3: Aggressively clean all cache if disk usage exceeds 90GB
[[worker.oci.gcpolicy]]
  all = true
  reservedSpace = "5GB"
  maxUsedSpace = "90GB"

除了 `reservedSpace`、`maxUsedSpace` 和 `minFreeSpace` 閾值之外,在定義 GC 策略時,您還有兩個額外的配置選項:

  • `all`:預設情況下,BuildKit 會將某些快取記錄排除在 GC 期間的清除之外。將此選項設定為 `true` 將允許清除任何快取記錄。
  • `filters`:過濾器允許您指定 GC 策略允許清除的特定型別的快取記錄。