Azure Container Registry のコンテナー イメージを削除する

Azure コンテナー レジストリのサイズを管理するには、古いイメージ データを定期的に削除する必要があります。 運用環境にデプロイされるコンテナー イメージには、長期間保存する必要があるものと、通常は短期間で削除できるものがあります。 たとえば、ビルドとテストの自動化シナリオでは、デプロイされない可能性のあるイメージでレジストリが短時間のうちにいっぱいになることがあります。このようなイメージは、ビルドとテスト パスが完了したらすぐに消去できるものです。

イメージ データを削除する方法は複数あるので、各削除操作によるストレージの使用への影響を理解しておく必要があります。 この記事では、イメージ データを削除するためのいくつかの方法について説明します。

  • リポジトリを削除する:リポジトリ内のイメージと一意のレイヤーがすべて削除されます。
  • タグを指定して削除する:イメージ、タグ、イメージによって参照されている一意のレイヤーすべて、およびイメージに関連付けられている他のすべてのタグが削除されます。
  • マニフェスト ダイジェストを指定して削除する:イメージ、イメージによって参照されている一意のレイヤーすべて、およびイメージに関連付けられているすべてのタグが削除されます。

これらの概念の概要については、「レジストリ、リポジトリ、イメージについて」を参照してください。

Note

Azure Container Registry は、イメージ データが削除されるとすぐ、関連ストレージに対する課金を停止します。 ただし、関連するストレージ領域は、レジストリにより非同期プロセスを使用して復旧されます。 レジストリがレイヤーをクリーンアップして、ストレージの使用状況の表示が更新されるまでにはしばらく時間がかかります。

リポジトリを削除する

リポジトリを削除すると、タグ、一意のレイヤー、マニフェストのすべてを含め、リポジトリ内のすべてのイメージが削除されます。 リポジトリを削除すると、そのリポジトリ内の一意レイヤーを参照するイメージによって使われていたストレージ領域が回復されます。

次の Azure CLI コマンドは、"acr-helloworld" リポジトリと、そのリポジトリ内のすべてタグとマニフェストを削除します。 削除されるマニフェストによって参照されているレイヤーが、レジストリ内の他のイメージによって参照されていない場合、そのレイヤーのデータも削除されて、ストレージ領域が回復されます。

 az acr repository delete --name myregistry --repository acr-helloworld

タグで削除する

削除操作でリポジトリの名前とタグを指定することにより、リポジトリから個別のイメージを削除できます。 タグを指定して削除すると、イメージ内の一意レイヤー (レジストリ内の他のイメージによって共有されていないレイヤー) で使われているストレージ領域が回復されます。

タグを使用して削除するには、az acr repository delete を使用し、--image パラメーターでイメージ名を指定します。 イメージに固有のすべてのレイヤーと、イメージに関連付けられている他のすべてのタグが削除されます。

たとえば、次の例では、レジストリ "myregistry" から "acr-helloworld:latest" イメージを削除しています。

az acr repository delete --name myregistry --image acr-helloworld:latest
This operation will delete the manifest 'sha256:0a2e01852872580b2c2fea9380ff8d7b637d3928783c55beb3f21a6e58d5d108' and all the following images: 'acr-helloworld:latest', 'acr-helloworld:v3'.
Are you sure you want to continue? (y/n):

ヒント

"タグによる" 削除を、タグの削除 (タグ付けの解除) と混同しないでください。 タグの削除は、Azure CLI コマンド az acr repository untag を使用して行うことができます。 イメージのタグを解除しても、マニフェストとレイヤーのデータがレジストリに残っているため、領域は解放されません。 タグ参照自体だけが削除されます。

マニフェスト ダイジェストで削除する

1 つのマニフェスト ダイジェストを 1 つまたは複数のタグと関連付けることができ、マニフェスト ダイジェストをタグに関連付けないでおくこともできます。 ダイジェストを指定して削除すると、マニフェストによって参照されているすべてのタグが削除され、イメージに固有のレイヤーのレイヤー データも削除されます。 共有されているレイヤーのデータは削除されません。

ダイジェストを使用して削除するには、最初に、削除するイメージを含むリポジトリのマニフェスト ダイジェストのリストを取得します。 次に例を示します。

az acr manifest list-metadata --name acr-helloworld --registry myregistry
[
  {
    "digest": "sha256:0a2e01852872580b2c2fea9380ff8d7b637d3928783c55beb3f21a6e58d5d108",
    "tags": [
      "latest",
      "v3"
    ],
    "timestamp": "2018-07-12T15:52:00.2075864Z"
  },
  {
    "digest": "sha256:3168a21b98836dda7eb7a846b3d735286e09a32b0aa2401773da518e7eba3b57",
    "tags": [
      "v2"
    ],
    "timestamp": "2018-07-12T15:50:53.5372468Z"
  }
]

次に、az acr repository delete コマンドで削除するダイジェストを指定します。 コマンドの形式は次のとおりです。

az acr repository delete --name <acrName> --image <repositoryName>@<digest>

たとえば、前の出力のリストで最後のマニフェスト (タグ "v2" のもの) を削除するには、次のようにします。

az acr repository delete --name myregistry --image acr-helloworld@sha256:3168a21b98836dda7eb7a846b3d735286e09a32b0aa2401773da518e7eba3b57
This operation will delete the manifest 'sha256:3168a21b98836dda7eb7a846b3d735286e09a32b0aa2401773da518e7eba3b57' and all the following images: 'acr-helloworld:v2'.
Are you sure you want to continue? (y/n): 

acr-helloworld:v2 イメージがレジストリから削除され、そのイメージに固有のレイヤー データも削除されます。 マニフェストが複数のタグに関連付けられている場合は、関連付けられているすべてのタグも削除されます。

ダイジェストをタイムスタンプに基づいて削除する

リポジトリまたはレジストリのサイズを維持するためには、特定の日付よりも古いマニフェスト ダイジェストを定期的に削除する必要があります。

以下の Azure CLI コマンドは、リポジトリから、特定のタイムスタンプより古いすべてのマニフェスト ダイジェストを昇順に一覧表示するものです。 <acrName><repositoryName> は、環境に適した値に置き換えます。 タイムスタンプは、完全な日付/時刻表現の場合と日付の場合とがあります。その例を次に示します。

az acr manifest list-metadata --name <repositoryName> --registry <acrName> \
    --orderby time_asc -o tsv --query "[?lastUpdateTime < '2019-04-05'].[digest, lastUpdateTime]"

古いマニフェスト ダイジェストを特定した後、次の Bash スクリプトを実行することで、指定のタイムスタンプより古いマニフェスト ダイジェストを削除することができます。 Azure CLI と xargs が必要です。 既定では、このスクリプトは削除を実行しません。 イメージの削除を有効にするには、ENABLE_DELETE の値を true に変更します。

警告

次のサンプル スクリプトを使用するときは注意してください。削除したイメージ データを元に戻すことはできません。 (イメージ名ではなく) マニフェスト ダイジェストを使用してイメージをプルするシステムの場合は、これらのスクリプトを実行しないでください。 そのようなシステムでは、マニフェスト ダイジェストを削除すると、レジストリからイメージをプルできなくなります。 マニフェストでプルするのではなく、一意のタグ付けスキームの推奨されるベスト プラクティスを採用することを検討してください。

#!/bin/bash

# WARNING! This script deletes data!
# Run only if you do not have systems
# that pull images via manifest digest.

# Change to 'true' to enable image delete
ENABLE_DELETE=false

# Modify for your environment
# TIMESTAMP can be a date-time string such as 2019-03-15T17:55:00.
REGISTRY=myregistry
REPOSITORY=myrepository
TIMESTAMP=2019-04-05  

# Delete all images older than specified timestamp.

if [ "$ENABLE_DELETE" = true ]
then
    az acr manifest list-metadata --name $REPOSITORY --registry $REGISTRY \
    --orderby time_asc --query "[?lastUpdateTime < '$TIMESTAMP'].digest" -o tsv \
    | xargs -I% az acr repository delete --name $REGISTRY --image $REPOSITORY@% --yes
else
    echo "No data deleted."
    echo "Set ENABLE_DELETE=true to enable deletion of these images in $REPOSITORY:"
    az acr manifest list-metadata --name $REPOSITORY --registry $REGISTRY \
   --orderby time_asc --query "[?lastUpdateTime < '$TIMESTAMP'].[digest, lastUpdateTime]" -o tsv
fi

タグの付いていないイメージを削除する

マニフェスト ダイジェスト」セクションで説明したように、既存のタグを使用して変更されたイメージをプッシュすると、以前にプッシュされたイメージのタグが解除されて、孤立した (または "未解決の") イメージになります。 以前にプッシュされたイメージのマニフェストとそのレイヤー データは、レジストリに残っています。 次のような一連のイベントについて考えてみます。

  1. latest というタグが付いたイメージ acr-helloworld をプッシュします。docker push myregistry.azurecr.io/acr-helloworld:latest

  2. リポジトリ acr-helloworld のマニフェストを確認します。

    az acr manifest list-metadata --name acr-helloworld --registry myregistry
    
    
    [
      {
        "digest": "sha256:d2bdc0c22d78cde155f53b4092111d7e13fe28ebf87a945f94b19c248000ceec",
        "tags": [
          "latest"
        ],
        "timestamp": "2018-07-11T21:32:21.1400513Z"
      }
    ]
    
  3. acr-helloworld Docker ファイルを変更します

  4. latest というタグが付いたイメージ acr-helloworld をプッシュします。docker push myregistry.azurecr.io/acr-helloworld:latest

  5. リポジトリ acr-helloworld のマニフェストを確認します。

    az acr manifest list-metadata --name acr-helloworld --registry myregistry
    
    [
      {
     "architecture": "amd64",
     "changeableAttributes": {
       "deleteEnabled": true,
       "listEnabled": true,
       "quarantineDetails": "{\"state\":\"Scan Passed\",\"link\":\"https://aka.ms/test\",\"scanner\":\"Azure Security Monitoring-Qualys Scanner\",\"result\":{\"version\":\"2020-05-13T00:23:31.954Z\",\"summary\":[{\"severity\":\"High\",\"count\":2},{\"severity\":\"Medium\",\"count\":0},{\"severity\":\"Low\",\"count\":0}]}}",
       "quarantineState": "Passed",
       "readEnabled": true,
       "writeEnabled": true
     },
     "configMediaType": "application/vnd.docker.container.image.v1+json",
     "createdTime": "2020-05-16T04:25:14.3112885Z",
     "digest": "sha256:eef2ef471f9f9d01fd2ed81bd2492ddcbc0f281b0a6e4edb700fbf9025448388",
     "imageSize": 22906605,
     "lastUpdateTime": "2020-05-16T04:25:14.3112885Z",
     "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
     "os": "linux",
     "timestamp": "2020-05-16T04:25:14.3112885Z"
      }
    ]
    

画像がタグ付けされていないときは、タグ配列がメタデータから削除されます。 このマニフェストは、それが参照する一意レイヤーのデータと共に、レジストリ内に依然として存在します。 このような孤立したイメージとそのレイヤー データを削除するには、マニフェスト ダイジェストを使って削除する必要があります

タグとマニフェストを自動的に消去する

タグとマニフェスト、さらに、そこに関連付けられている一意のレイヤー データを削除する手段として、Azure Container Registry には、次の自動化された方法が用意されています。

  • 特定の期間よりも古いタグまたは指定の名前フィルターと一致するタグを、acr purge コンテナー コマンドを実行してすべて削除する ACR タスクを作成します。 必要に応じて、タグのないマニフェストを削除するよう acr purge を構成します。

    acr purge コンテナーコマンドは現在プレビュー段階です。 詳細については、「Azure コンテナー レジストリからイメージを自動的に消去する」を参照してください。

  • 必要に応じて、タグなしマニフェストを管理するためのアイテム保持ポリシーをレジストリごとに設定します。 アイテム保持ポリシーを有効にすると、タグが一切関連付けられておらず、また基になるレイヤー データを持たないイメージのマニフェストが、設定した期間の経過後、レジストリから自動的に削除されます。

    アイテム保持ポリシーは現在、Premium コンテナー レジストリのプレビュー機能です。 アイテム保持ポリシーが適用されるのは、ポリシーが有効になった後に作成されたタグなしのマニフェストのみです。

次の手順

Azure Container Registry でのイメージ ストレージの詳細については、「Azure Container Registry へのコンテナー イメージの保存」を参照してください。