返回列表

AWS帳號開戶服務 AWS ECR 磁碟空間爆滿?生命周期策略(Lifecycle Policy)清理舊鏡像指南

亞馬遜雲AWS / 2026-08-04 15:57:49

AWS帳號開戶服務 先搞懂:ECR 為什麼會越堆越大

AWS帳號開戶服務 很多人第一次發現 ECR「爆滿」,通常不是某一次大版本發布造成的,而是長期累積的結果。CI/CD 每次建置都會推一個新鏡像,分支很多、環境很多、標籤很多,久了之後,同一個專案在 ECR 裡可能留下幾百甚至幾千個 image。雖然 ECR 是託管服務,不是你本機的磁碟,但它一樣會產生儲存費用,也會讓倉庫管理變得混亂。

最常見的情況有三種:第一,開發分支每次 commit 都產出一個新 tag,例如 feature-xxx、build-123、pr-456;第二,發布流程保留太多歷史版本,回滾卻很少真的回到更早的版本;第三,untagged image 越積越多,因為鏡像被重新標記或流程中斷後,舊 image 仍留在倉庫裡。這些鏡像單看一個不大,堆在一起就很可觀。

更麻煩的是,ECR 的鏡像不是刪了 tag 就等於刪了內容。實際上,倉庫裡會有 layers 共享,某些鏡像刪除後可釋放的空間不一定和你想像一樣線性下降。所以面對「空間爆滿」,最重要的不是手動亂刪,而是建立一套可預期、可重複執行的清理規則。

Lifecycle Policy 是什麼,能解決什麼問題

AWS ECR 的 Lifecycle Policy,就是讓倉庫依照條件自動刪除舊鏡像的規則。它不是一個清理腳本,也不是排程任務,而是由 ECR 直接執行的保留策略。你先定義哪些鏡像要留下、哪些可以過期,之後 ECR 會依照規則判斷並清除符合條件的 image。

它最適合處理的,就是「有規律、可分類」的鏡像。像是:

  • 只保留最新的 20 個開發鏡像。
  • 只保留最近 30 天內推送的測試鏡像。
  • 保留 release 標籤,但其他臨時 tag 自動淘汰。
  • 清掉沒有 tag 的殘留鏡像,避免倉庫越來越亂。

要注意的是,Lifecycle Policy 的核心不是「刪越多越好」,而是「刪得剛好」。真正成熟的做法,是先分清楚哪些鏡像屬於可回滾資產,哪些只是流水線產物。前者要保守,後者可以積極清理。只要分類做對,ECR 不但不會爆滿,還能維持很乾淨的狀態。

Lifecycle Policy 常用的幾個條件

ECR 的規則其實不難,但要用對條件。最常用的是這幾種:

  • tagStatus:指定 tagged、untagged 或 any。
  • tagPrefixList:用標籤前綴篩選,例如 prod-、release-、dev-。
  • countType:常見是 imageCountMoreThan 或 sinceImagePushed。
  • countNumber:保留數量,或保留天數。
  • AWS帳號開戶服務 countUnit:只有使用 sinceImagePushed 時才會用到,通常是 days。

這裡最容易踩坑的是 tag 設計。Lifecycle Policy 並不適合拿來做很複雜的匹配,它更適合靠命名規則管理。例如你把正式版統一命名為 release-20250101,開發版統一命名為 dev-commit-id,那政策就很好寫。反過來,如果 tag 命名毫無規律,策略就會很難維護。

先別急著刪:策略要先按倉庫生命週期來設計

很多團隊一想到節省空間,就直接設一條「超過 7 天全刪」的規則。這種做法看起來乾脆,實際上很危險。因為不是每一個鏡像都只是測試用,有些版本可能是回滾依據,有些則是某次重大發布留下的里程碑。你要先搞清楚倉庫裡不同鏡像的角色,再決定刪除節奏。

建議把鏡像分成四類:

  • 正式版:要保留較多,因為可能牽涉回滾。
  • 預發布 / 測試版:保留中等數量,避免佔太多空間。
  • 開發版 / 分支版:保留最少,因為產生頻率最高。
  • untagged:通常可以更積極清理,避免殘留。

如果你的團隊已經有 release 流程,最好的做法是讓正式版和臨時版使用不同前綴。這樣一來,Lifecycle Policy 只要看 tag prefix 就能分流,規則簡單又穩定。真正可維護的策略,通常不是最複雜的,而是最一致的。

可以直接參考的 ECR Lifecycle Policy 範例

下面是一份常見、實用的範例。它的思路是:正式版保留較多、測試版次之、開發版更少、untagged 最後清理。你可以依照團隊發版速度調整數字,但邏輯最好保持一致。

{
  "rules": [
    {
      "rulePriority": 1,
      "description": "保留最新 30 個正式版鏡像",
      "selection": {
        "tagStatus": "tagged",
        "tagPrefixList": ["prod-"],
        "countType": "imageCountMoreThan",
        "countNumber": 30
      },
      "action": {
        "type": "expire"
      }
    },
    {
      "rulePriority": 2,
      "description": "保留最新 20 個測試版鏡像",
      "selection": {
        "tagStatus": "tagged",
        "tagPrefixList": ["release-"],
        "countType": "imageCountMoreThan",
        "countNumber": 20
      },
      "action": {
        "type": "expire"
      }
    },
    {
      "rulePriority": 3,
      "description": "清理 14 天前的開發版鏡像",
      "selection": {
        "tagStatus": "tagged",
        "tagPrefixList": ["dev-"],
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 14
      },
      "action": {
        "type": "expire"
      }
    },
    {
      "rulePriority": 100,
      "description": "清理 7 天前的未標記鏡像",
      "selection": {
        "tagStatus": "untagged",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 7
      },
      "action": {
        "type": "expire"
      }
    }
  ]
}

這份規則有幾個重點。第一,rulePriority 數字越小,優先級越高,所以正式版放前面,untagged 放最後。第二,正式版和測試版用數量保留,這樣可以避免因為發布密集,導致最近幾天全被刪掉。第三,開發版和 untagged 用天數保留,比較符合它們「短生命週期」的特性。

如果你的團隊沒有明確的 prod、release、dev 分類,也可以先從「保留最新 N 個 tagged image,加上刪除 X 天前的 untagged image」開始。先把最容易膨脹的部分控制住,再慢慢細分規則,會比一次到位來得穩。

實際設計時,最容易忽略的幾個細節

1. 不要把重要版本混進臨時 tag

很多倉庫最後不好管,不是因為鏡像太多,而是因為命名太亂。正式版如果偶爾用 dev-xxx 推送,或測試版時不時掛上 latest,Lifecycle Policy 就很難準確判斷。最好的做法是先定規範,再寫策略,而不是反過來。

2. 刪除的是 image,不是部署中的容器

有些人會擔心:把 ECR 裡的 image 刪掉,會不會影響正在跑的服務?答案是,已經部署出去的容器不會因為你刪了 registry 裡的 image 立刻停止,但如果之後需要重新拉取、回滾或重新部署,就可能出問題。所以正式版一定要留足夠的回滾窗口,不要只看空間,不看風險。

3. 不要低估 untagged 的累積速度

CI 流水線一旦中斷、標籤被重新覆蓋、某些 build 流程只推送不打標籤,untagged image 就會快速變多。這類鏡像通常沒有保留價值,卻很容易被忽略。實務上,先清 untagged 往往是最快見效的方法。

4. 保留數量要跟發版頻率對齊

如果你們一天發布 20 次,保留最新 10 個開發鏡像可能兩三個小時就被覆蓋;如果你們一週才發布一次,保留 50 個正式版又可能太多。數字沒有標準答案,真正的標準是團隊的發版節奏與回滾需求。

上線前的檢查清單

在把策略套到核心倉庫之前,建議先做一輪檢查,避免刪錯。

  • 確認 tag 命名是否一致,尤其是 prod、release、dev 是否有固定前綴。
  • 確認正式版是否有明確回滾窗口,例如保留最近 30 天或最近 20 個版本。
  • 先挑一個非核心倉庫驗證規則,觀察刪除結果是否符合預期。
  • 確認 CI/CD 流程不會依賴過舊的鏡像 tag。
  • 記錄策略版本,讓日後調整時知道是哪一版規則在生效。

如果你們有多個 AWS account 或多個 region,也要留意每個倉庫是否需要不同策略。不要把所有倉庫套同一份規則,因為不同服務的鏡像密度和保存需求通常差很多。資料庫、核心 API、前端靜態站點,三者的保留策略通常不會一樣。

常見誤區:不是設定了政策就萬事大吉

Lifecycle Policy 很好用,但它不是魔法。第一個誤區,是以為設定後就會立刻清空舊鏡像。實際上,規則通常是在 ECR 的生命週期掃描中逐步生效,不是你按下儲存就瞬間結束。第二個誤區,是把政策寫得太激進,結果一兩天後回滾所需的版本已經不見了。第三個誤區,是沒先整理 tag,導致規則根本無法準確分類。

還有一個很常見的問題:有人以為刪掉 image 之後,帳單立刻大幅下降。其實儲存費用的下降通常會有延遲,而且 shared layers 釋放也不是完全同步。你會先看到倉庫整潔很多,之後才慢慢反映到成本上。這很正常,不需要誤判成「政策沒生效」。

結語:先讓規則可預期,空間問題自然會變小

ECR 爆滿不是一個單純的容量問題,而是流程設計的結果。只靠手動刪除,今天清掉一批,明天又會長出來;但如果你把 tag 規範、版本分類、保留窗口和 Lifecycle Policy 一起做好,ECR 就會從「亂堆的倉庫」變成「可控的發版資產庫」。

真正好用的策略,通常有三個特徵:能看懂、能預期、能維護。看懂,代表任何工程師都知道哪類 image 會被刪;能預期,代表回滾和發布風險可控;能維護,代表半年後你還願意碰它,而不是看到就怕。把這三件事做好,ECR 的磁碟空間問題,基本上就不會再是日常麻煩。

Telegram售前客服
客服ID
@cloudcup
联系
Telegram售后客服
客服ID
@yanhuacloud
联系