.NET 用Azure Container Registry クライアント ライブラリ - バージョン 1.1.0

Azure Container Registryを使用すると、コンテナー イメージと成果物を、すべての種類のコンテナー デプロイのプライベート レジストリに格納および管理できます。

Azure Container Registry のクライアント ライブラリを使用して、次のことを行います。

  • レジストリ内のイメージまたは成果物を一覧表示する
  • イメージと成果物、リポジトリ、タグのメタデータを取得する
  • レジストリ項目の読み取り、書き込み、削除プロパティを設定する
  • イメージと成果物、リポジトリ、タグを削除する

ソースコード | パッケージ (NuGet) | API リファレンス ドキュメント | REST API のドキュメント | 製品ドキュメント

作業の開始

Azure Container Registry インスタンスに接続できる .NET アプリケーション コードを開発するには、Azure.Containers.ContainerRegistry ライブラリが必要です。

パッケージをインストールする

NuGet を使用して .NET 用の Azure Container Registry クライアント ライブラリをインストールします。

dotnet add package Azure.Containers.ContainerRegistry

前提条件

アプリケーションが接続するには、 Azure サブスクリプションContainer Registry サービス インスタンス が必要です。

新しい Container Registry を作成するには、Azure PortalAzure PowerShell、または Azure CLI を使用できます。 Azure CLI を使用して新しいレジストリを作成する例を次に示します。

az acr create --name myregistry --resource-group myresourcegroup --location westus --sku Basic

クライアントを認証する

アプリケーションをレジストリに接続するには、それによって認証できる ContainerRegistryClient を作成する必要があります。 Azure Identity ライブラリを使用すると、対応する Azure サービスを使用して Azure SDK クライアントを認証するための Azure Active Directory サポートを簡単に追加できます。

アプリケーションをローカルで開発およびデバッグする場合は、独自のユーザーを使用して自身のレジストリで認証できます。 これを実現する 1 つの方法は、Azure CLI を使用してユーザーを認証し、この環境からアプリケーションを実行することです。 DefaultAzureCredential で認証するように構築されたクライアントをアプリケーションで使用している場合、指定されたエンドポイントのレジストリで正しく認証されます。

// Create a ContainerRegistryClient that will authenticate to your registry through Azure Active Directory
Uri endpoint = new Uri("https://myregistry.azurecr.io");
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(),
    new ContainerRegistryClientOptions()
    {
        Audience = ContainerRegistryAudience.AzureResourceManagerPublicCloud
    });

ローカル環境とデプロイ環境の両方で DefaultAzureCredentialを使用して認証する方法の詳細については、Azure Identity README に関するページを参照してください。 非パブリック Azure クラウドのレジストリに接続するには、以下のサンプルを参照してください。

Azure Container Registryで AAD を使用する方法の詳細については、サービスの認証の概要に関するページを参照してください。

主要な概念

レジストリには、Docker イメージと OCI 成果物が格納されます。 イメージまたは成果物は、"マニフェスト"と "レイヤー" で構成されます。 イメージのマニフェストは、イメージを構成するレイヤーを記述し、 ダイジェストによって一意に識別されます。 画像に "タグ付け" して、人間が判読できるエイリアスを付けることもできます。 イメージまたは成果物には、0 個以上の タグ を関連付けることができ、各タグはイメージを一意に識別します。 同じ名前を共有し、異なるタグを持つイメージのコレクションは、 リポジトリと呼ばれます。

詳細については、「 コンテナー レジストリの概念」を参照してください。

スレッド セーフ

すべてのクライアント インスタンス メソッドがスレッド セーフであり、相互に独立していることを保証します (ガイドライン)。 これにより、スレッド間であっても、 クライアント インスタンスを再利用するための推奨事項 が常に安全になります。

その他の概念

クライアント オプション | 応答 | へのアクセス実行時間の長い操作 | エラーの | 処理診断 | あざける | クライアントの有効期間

次のスニペットは、ACR SDK ライブラリを使用した一般的な開発者シナリオの簡単なサンプルを示しています。 各サンプルでは、プレフィックスとログイン サーバーの名前 (例: "https://myregistry.azurecr.io") をhttps://含む文字列に設定された環境変数があることをREGISTRY_ENDPOINT前提としています。

同期の例

非同期の例

高度な認証

レジストリの操作

この割り当てにはサンプルが ContainerRegistryClient 含まれています。

リポジトリの一覧を表示する

レジストリ内のリポジトリのコレクションを反復処理します。

// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a new ContainerRegistryClient
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());

// Get the collection of repository names from the registry
Pageable<string> repositories = client.GetRepositoryNames();
foreach (string repository in repositories)
{
    Console.WriteLine(repository);
}

匿名アクセスを使用してタグを一覧表示する

// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a new ContainerRegistryClient for anonymous access
ContainerRegistryClient client = new ContainerRegistryClient(endpoint);

// Obtain a RegistryArtifact object to get access to image operations
RegistryArtifact image = client.GetArtifact("library/hello-world", "latest");

// List the set of tags on the hello_world image tagged as "latest"
Pageable<ArtifactTagProperties> tags = image.GetAllTagProperties();

// Iterate through the image's tags, listing the tagged alias for the image
Console.WriteLine($"{image.FullyQualifiedReference} has the following aliases:");
foreach (ArtifactTagProperties tag in tags)
{
    Console.WriteLine($"    {image.RegistryEndpoint.Host}/{image.RepositoryName}:{tag}");
}

成果物のプロパティを設定する

// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a new ContainerRegistryClient and RegistryArtifact to access image operations
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
RegistryArtifact image = client.GetArtifact("library/hello-world", "latest");

// Set permissions on the v1 image's "latest" tag
image.UpdateTagProperties("latest", new ArtifactTagProperties()
{
    CanWrite = false,
    CanDelete = false
});

イメージを削除する

// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a new ContainerRegistryClient
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());

// Iterate through repositories
Pageable<string> repositoryNames = client.GetRepositoryNames();
foreach (string repositoryName in repositoryNames)
{
    ContainerRepository repository = client.GetRepository(repositoryName);

    // Obtain the images ordered from newest to oldest
    Pageable<ArtifactManifestProperties> imageManifests =
        repository.GetAllManifestProperties(manifestOrder: ArtifactManifestOrder.LastUpdatedOnDescending);

    // Delete images older than the first three.
    foreach (ArtifactManifestProperties imageManifest in imageManifests.Skip(3))
    {
        RegistryArtifact image = repository.GetArtifact(imageManifest.Digest);
        Console.WriteLine($"Deleting image with digest {imageManifest.Digest}.");
        Console.WriteLine($"   Deleting the following tags from the image: ");
        foreach (var tagName in imageManifest.Tags)
        {
            Console.WriteLine($"        {imageManifest.RepositoryName}:{tagName}");
            image.DeleteTag(tagName);
        }
        image.Delete();
    }
}

リポジトリを非同期的に一覧表示する

非同期 API は同期 API と同じですが、メソッドは標準の .NET "Async" サフィックスで終わり、Task を返します。

// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a new ContainerRegistryClient
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());

// Get the collection of repository names from the registry
AsyncPageable<string> repositories = client.GetRepositoryNamesAsync();
await foreach (string repository in repositories)
{
    Console.WriteLine(repository);
}

匿名アクセスを使用してタグを非同期的に一覧表示する

// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a new ContainerRegistryClient for anonymous access
ContainerRegistryClient client = new ContainerRegistryClient(endpoint);

// Obtain a RegistryArtifact object to get access to image operations
RegistryArtifact image = client.GetArtifact("library/hello-world", "latest");

// List the set of tags on the hello_world image tagged as "latest"
AsyncPageable<ArtifactTagProperties> tags = image.GetAllTagPropertiesAsync();

// Iterate through the image's tags, listing the tagged alias for the image
Console.WriteLine($"{image.FullyQualifiedReference} has the following aliases:");
await foreach (ArtifactTagProperties tag in tags)
{
    Console.WriteLine($"    {image.RegistryEndpoint.Host}/{image.RepositoryName}:{tag}");
}

成果物のプロパティを非同期的に設定する

// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a new ContainerRegistryClient and RegistryArtifact to access image operations
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
RegistryArtifact image = client.GetArtifact("library/hello-world", "v1");

// Set permissions on the image's "latest" tag
await image.UpdateTagPropertiesAsync("latest", new ArtifactTagProperties()
{
    CanWrite = false,
    CanDelete = false
});

イメージを非同期的に削除する

// Get the service endpoint from the environment
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a new ContainerRegistryClient
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());

// Iterate through repositories
AsyncPageable<string> repositoryNames = client.GetRepositoryNamesAsync();
await foreach (string repositoryName in repositoryNames)
{
    ContainerRepository repository = client.GetRepository(repositoryName);

    // Obtain the images ordered from newest to oldest
    AsyncPageable<ArtifactManifestProperties> imageManifests =
        repository.GetAllManifestPropertiesAsync(manifestOrder: ArtifactManifestOrder.LastUpdatedOnDescending);

    // Delete images older than the first three.
    await foreach (ArtifactManifestProperties imageManifest in imageManifests.Skip(3))
    {
        RegistryArtifact image = repository.GetArtifact(imageManifest.Digest);
        Console.WriteLine($"Deleting image with digest {imageManifest.Digest}.");
        Console.WriteLine($"   Deleting the following tags from the image: ");
        foreach (var tagName in imageManifest.Tags)
        {
            Console.WriteLine($"        {imageManifest.RepositoryName}:{tagName}");
            await image.DeleteTagAsync(tagName);
        }
        await image.DeleteAsync();
    }
}

BLOB とマニフェストの操作

このセクションには、画像をアップロードおよびダウンロードする方法を示す の ContainerRegistryContentClient サンプルが含まれています。

まず、BLOB クライアントを作成します。

// Get the service endpoint from the environment
Uri endpoint = new(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

string repository = "sample-oci-image";
string tag = "demo";

// Create a new ContainerRegistryContentClient
ContainerRegistryContentClient client = new(endpoint, repository, new DefaultAzureCredential());

画像のアップロード

完全なイメージをアップロードするには、個々のレイヤーと構成をアップロードする必要があります。 その後、イメージまたは成果物を記述するマニフェストをアップロードし、タグを割り当てることができます。

// Create a manifest to list files in this image
OciImageManifest manifest = new(schemaVersion: 2);

// Upload a config file
BinaryData config = BinaryData.FromString("Sample config");
UploadRegistryBlobResult uploadConfigResult = await client.UploadBlobAsync(config);

// Update manifest with config info
manifest.Configuration = new OciDescriptor()
{
    Digest = uploadConfigResult.Digest,
    SizeInBytes = uploadConfigResult.SizeInBytes,
    MediaType = "application/vnd.oci.image.config.v1+json"
};

// Upload a layer file
BinaryData layer = BinaryData.FromString("Sample layer");
UploadRegistryBlobResult uploadLayerResult = await client.UploadBlobAsync(layer);

// Update manifest with layer info
manifest.Layers.Add(new OciDescriptor()
{
    Digest = uploadLayerResult.Digest,
    SizeInBytes = uploadLayerResult.SizeInBytes,
    MediaType = "application/vnd.oci.image.layer.v1.tar"
});

// Finally, upload the manifest file
await client.SetManifestAsync(manifest, tag);

画像をダウンロードする

完全なイメージをダウンロードするには、マニフェストをダウンロードし、個々のレイヤーと構成をダウンロードする必要があります。

// Download the manifest to obtain the list of files in the image
GetManifestResult result = await client.GetManifestAsync(tag);
OciImageManifest manifest = result.Manifest.ToObjectFromJson<OciImageManifest>();

string manifestFile = Path.Combine(path, "manifest.json");
using (FileStream stream = File.Create(manifestFile))
{
    await result.Manifest.ToStream().CopyToAsync(stream);
}

// Download and write out the config
DownloadRegistryBlobResult configBlob = await client.DownloadBlobContentAsync(manifest.Configuration.Digest);

string configFile = Path.Combine(path, "config.json");
using (FileStream stream = File.Create(configFile))
{
    await configBlob.Content.ToStream().CopyToAsync(stream);
}

// Download and write out the layers
foreach (OciDescriptor layerInfo in manifest.Layers)
{
    string layerFile = Path.Combine(path, TrimSha(layerInfo.Digest));
    using (FileStream stream = File.Create(layerFile))
    {
        await client.DownloadBlobToAsync(layerInfo.Digest, stream);
    }
}

static string TrimSha(string digest)
{
    int index = digest.IndexOf(':');
    if (index > -1)
    {
        return digest.Substring(index + 1);
    }

    return digest;
}

マニフェストの削除

GetManifestResult manifestResult = await client.GetManifestAsync(tag);
await client.DeleteManifestAsync(manifestResult.Digest);

BLOB を削除する

GetManifestResult result = await client.GetManifestAsync(tag);
OciImageManifest manifest = result.Manifest.ToObjectFromJson<OciImageManifest>();

foreach (OciDescriptor layerInfo in manifest.Layers)
{
    await client.DeleteBlobAsync(layerInfo.Digest);
}

高度な認証

National Cloud での認証

National Cloud のレジストリで認証するには、クライアント構成に次の追加を行う必要があります。

  • AuthorityHost資格情報オプションで、または環境変数を使用して を設定しますAZURE_AUTHORITY_HOST
  • で を設定するAudienceContainerRegistryClientOptions
// Create a ContainerRegistryClient that will authenticate through AAD in the China national cloud
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));
ContainerRegistryClient client = new ContainerRegistryClient(endpoint,
    new DefaultAzureCredential(
        new DefaultAzureCredentialOptions()
        {
            AuthorityHost = AzureAuthorityHosts.AzureChina
        }),
    new ContainerRegistryClientOptions()
    {
        Audience = ContainerRegistryAudience.AzureChina
    });

トラブルシューティング

さまざまな障害シナリオを診断する方法の詳細については、 トラブルシューティング ガイド を参照してください。

次のステップ

共同作成

このプロジェクトでは、共同作成と提案を歓迎しています。 ほとんどの共同作成では、共同作成者使用許諾契約書 (CLA) にご同意いただき、ご自身の共同作成内容を使用する権利を Microsoft に供与する権利をお持ちであり、かつ実際に供与することを宣言していただく必要があります。 詳細については、「 cla.microsoft.com」を参照してください。

このプロジェクトでは、Microsoft オープン ソースの倫理規定を採用しています。 詳しくは、「Code of Conduct FAQ (倫理規定についてよくある質問)」を参照するか、opencode@microsoft.com 宛てに質問またはコメントをお送りください。

インプレッション数