Mulai Cepat: Menggunakan pustaka klien Azure Container Registry

Gunakan artikel ini untuk memulai dengan pustaka klien untuk Azure Container Registry. Ikuti langkah-langkah ini untuk mencoba contoh kode untuk operasi pesawat data pada citra dan artefak.

Gunakan pustaka klien untuk Azure Container Registry untuk:

  • Membuat daftar citra atau artefak dalam registri
  • Mendapatkan metadata untuk citra dan artefak, repositori, dan tag
  • Mengatur properti baca/tulis/hapus pada item registri
  • Menghapus citra dan artefak, repositori, dan tag

Azure Container Registry juga memiliki perpustakaan manajemen untuk operasi kontrol pesawat termasuk pembuatan dan pembaruan registri.

Prasyarat

Konsep utama

  • Registri kontainer Azure menyimpan citra kontainer dan artefak OCI.
  • Citra atau artefak terdiri dari manifes dan lapisan.
  • Manifes menggambarkan lapisan yang membentuk citra atau artefak. Manifes tersebut diidentifikasi secara unik oleh digest.
  • Citra atau artefak juga dapat diberi tag agar memiliki alias yang dapat dibaca. Citra atau artefak dapat memiliki nol atau beberapa tag yang terkait dengannya, dan setiap tag secara unik mengidentifikasi citra.
  • Kumpulan citra atau artefak yang memiliki nama yang sama, tetapi memiliki tag yang berbeda, adalah repositori.

Untuk informasi selengkapnya, lihat Tentang registri, repositori, dan artefak.

Mulai

Kode sumber | Paket (NuGet) | Referensi API | Sampel

Untuk mengembangkan kode aplikasi .NET yang dapat tersambung ke instans Azure Container Registry, Anda memerlukan pustaka Azure.Containers.ContainerRegistry.

Pasang paket

Pasang pustaka klien Azure Container Registry untuk .NET dengan NuGet:

dotnet add package Azure.Containers.ContainerRegistry --prerelease

Mengautentikasi klien

Agar aplikasi Anda tersambung ke registri, Anda harus membuat yang ContainerRegistryClient dapat mengautentikasi dengannya. Gunakan pustaka Azure Identity untuk menambahkan dukungan ID Microsoft Entra untuk mengautentikasi klien Azure SDK dengan layanan Azure yang sesuai.

Ketika Anda mengembangkan dan melakukan debug aplikasi Anda secara lokal, Anda dapat menggunakan pengguna Anda sendiri untuk mengautentikasi dengan registri Anda. Salah satu cara untuk mencapai hal ini adalah untuk mengautentikasi pengguna Anda dengan Azure CLI dan menjalankan aplikasi Anda dari lingkungan ini. Jika aplikasi Anda menggunakan klien yang telah dibangun untuk mengautentikasi dengan DefaultAzureCredential, aplikasi Anda akan dengan benar mengautentikasi menggunakan registri pada titik akhir tertentu.

// 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
    });

Lihat README Identitas Azure untuk lebih banyak pendekatan untuk mengautentikasi dengan DefaultAzureCredential, baik secara lokal maupun di lingkungan penyebaran. Untuk tersambung ke registri di cloud Azure non-publik, lihat Referensi API.

Untuk informasi selengkapnya tentang menggunakan MICROSOFT Entra ID dengan Azure Container Registry, lihat gambaran umum autentikasi.

Contoh

Setiap sampel mengasumsikan ada variabel lingkungan REGISTRY_ENDPOINT yang diatur ke string yang berisi prefiks https:// dan nama server masuk, misalnya "https://myregistry.azurecr.io".

Sampel berikut menggunakan API asinkron yang mengembalikan tugas. API sinkron juga tersedia.

Membuat daftar repositori secara asinkron

Lakukan iterasi melalui kumpulan repositori dalam registri.

// 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(),
    new ContainerRegistryClientOptions()
    {
        Audience = ContainerRegistryAudience.AzureResourceManagerPublicCloud
    });

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

Mengatur properti artefak secara asinkron

// 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(),
    new ContainerRegistryClientOptions()
    {
        Audience = ContainerRegistryAudience.AzureResourceManagerPublicCloud
    });

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

Menghapus gambar secara asinkron

using System.Linq;
using Azure.Containers.ContainerRegistry;
using Azure.Identity;

// 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(),
    new ContainerRegistryClientOptions()
    {
        Audience = ContainerRegistryAudience.AzureResourceManagerPublicCloud
    });

// 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.GetManifestPropertiesCollectionAsync(orderBy: ArtifactManifestOrderBy.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();
    }
}

Mulai

Kode sumber | Paket (Maven) | Referensi API | Sampel

Lingkungan yang didukung saat ini

Sertakan paket

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-containers-containerregistry</artifactId>
  <version>1.0.0-beta.3</version>
</dependency>

Mengautentikasi klien

Pustaka Azure Identity menyediakan dukungan ID Microsoft Entra untuk autentikasi.

Sampel berikut mengasumsikan Anda memiliki string titik akhir registri yang berisi prefiks https:// dan nama server login, misalnya "https://myregistry.azurecr.io".

DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();
ContainerRegistryClient client = new ContainerRegistryClientBuilder()
    .endpoint(endpoint)
    .credential(credential)
    .buildClient();
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();
ContainerRegistryAsyncClient client = new ContainerRegistryClientBuilder()
    .endpoint(endpoint)
    .credential(credential)
    .buildAsyncClient();

Untuk informasi selengkapnya tentang menggunakan MICROSOFT Entra ID dengan Azure Container Registry, lihat gambaran umum autentikasi.

Contoh

Setiap sampel mengasumsikan Anda memiliki string titik akhir registri yang berisi prefiks https:// dan nama server login, misalnya "https://myregistry.azurecr.io".

Membuat daftar nama repositori

Lakukan iterasi melalui kumpulan repositori dalam registri.

DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();
ContainerRegistryClient client = new ContainerRegistryClientBuilder()
    .endpoint(endpoint)
    .credential(credential)
    .buildClient();

client.listRepositoryNames().forEach(repository -> System.out.println(repository));

Mengatur properti artefak

TokenCredential defaultCredential = new DefaultAzureCredentialBuilder().build();

ContainerRegistryClient client = new ContainerRegistryClientBuilder()
    .endpoint(endpoint)
    .credential(defaultCredential)
    .buildClient();

RegistryArtifact image = client.getArtifact(repositoryName, digest);

image.updateTagProperties(
    tag,
    new ArtifactTagProperties()
        .setWriteEnabled(false)
        .setDeleteEnabled(false));

Hapus gambar

TokenCredential defaultCredential = new DefaultAzureCredentialBuilder().build();

ContainerRegistryClient client = new ContainerRegistryClientBuilder()
    .endpoint(endpoint)
    .credential(defaultCredential)
    .buildClient();

final int imagesCountToKeep = 3;
for (String repositoryName : client.listRepositoryNames()) {
    final ContainerRepository repository = client.getRepository(repositoryName);

    // Obtain the images ordered from newest to oldest
    PagedIterable<ArtifactManifestProperties> imageManifests =
        repository.listManifestProperties(
            ArtifactManifestOrderBy.LAST_UPDATED_ON_DESCENDING,
            Context.NONE);

    imageManifests.stream().skip(imagesCountToKeep)
        .forEach(imageManifest -> {
            System.out.printf(String.format("Deleting image with digest %s.%n", imageManifest.getDigest()));
            System.out.printf("    This image has the following tags: ");

            for (String tagName : imageManifest.getTags()) {
                System.out.printf("        %s:%s", imageManifest.getRepositoryName(), tagName);
            }

            repository.getArtifact(imageManifest.getDigest()).delete();
        });
}

Mulai

Kode sumber | Paket (npm) | Referensi API | Sampel

Lingkungan yang didukung saat ini

Lihat kebijakan dukungan kami untuk detail selengkapnya.

Pasang paket @azure/container-registry

Pasang pustaka klien Azure Container Registry untuk JavaScript dengan npm:

npm install @azure/container-registry

Mengautentikasi klien

Pustaka Azure Identity menyediakan dukungan ID Microsoft Entra untuk autentikasi.

const { ContainerRegistryClient } = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");

const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT;
// Create a ContainerRegistryClient that will authenticate through Active Directory
const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());

Untuk informasi selengkapnya tentang menggunakan MICROSOFT Entra ID dengan Azure Container Registry, lihat gambaran umum autentikasi.

Contoh

Setiap sampel mengasumsikan ada variabel lingkungan CONTAINER_REGISTRY_ENDPOINT yang diatur ke string yang berisi prefiks https:// dan nama server masuk, misalnya "https://myregistry.azurecr.io".

Membuat daftar repositori secara asinkron

Lakukan iterasi melalui kumpulan repositori dalam registri.

const { ContainerRegistryClient } = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");

async function main() {
  // endpoint should be in the form of "https://myregistryname.azurecr.io"
  // where "myregistryname" is the actual name of your registry
  const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
  const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());

  console.log("Listing repositories");
  const iterator = client.listRepositoryNames();
  for await (const repository of iterator) {
    console.log(`  repository: ${repository}`);
  }
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

Mengatur properti artefak secara asinkron

const { ContainerRegistryClient } = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");

async function main() {
  // Get the service endpoint from the environment
  const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";

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

  // Set permissions on the image's "latest" tag
  await image.updateTagProperties("latest", { canWrite: false, canDelete: false });
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

Menghapus gambar secara asinkron

const { ContainerRegistryClient } = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");

async function main() {
  // Get the service endpoint from the environment
  const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT || "<endpoint>";
  // Create a new ContainerRegistryClient
  const client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());

  // Iterate through repositories
  const repositoryNames = client.listRepositoryNames();
  for await (const repositoryName of repositoryNames) {
    const repository = client.getRepository(repositoryName);
    // Obtain the images ordered from newest to oldest by passing the `orderBy` option
    const imageManifests = repository.listManifestProperties({
      orderBy: "LastUpdatedOnDescending"
    });
    const imagesToKeep = 3;
    let imageCount = 0;
    // Delete images older than the first three.
    for await (const manifest of imageManifests) {
      imageCount++;
      if (imageCount > imagesToKeep) {
        const image = repository.getArtifact(manifest.digest);
        console.log(`Deleting image with digest ${manifest.digest}`);
        console.log(`  Deleting the following tags from the image:`);
        for (const tagName of manifest.tags) {
          console.log(`    ${manifest.repositoryName}:${tagName}`);
          image.deleteTag(tagName);
        }
        await image.delete();
      }
    }
  }
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

Mulai

Kode sumber | Paket (Pypi) | Referensi API | Sampel

Pasang paket

Pasang pustaka klien Azure Container Registry untuk Python dengan pip:

pip install --pre azure-containerregistry

Mengautentikasi klien

Pustaka Azure Identity menyediakan dukungan ID Microsoft Entra untuk autentikasi. DefaultAzureCredential mengasumsikan bahwa variabel lingkungan AZURE_CLIENT_ID, AZURE_TENANT_ID, and AZURE_CLIENT_SECRET telah diatur. Untuk informasi selengkapnya, lihat Variabel lingkungan Identitas Azure.

# Create a ContainerRegistryClient that will authenticate through Active Directory
from azure.containerregistry import ContainerRegistryClient
from azure.identity import DefaultAzureCredential

account_url = "https://mycontainerregistry.azurecr.io"
client = ContainerRegistryClient(account_url, DefaultAzureCredential())

Contoh

Setiap sampel mengasumsikan ada variabel lingkungan CONTAINERREGISTRY_ENDPOINT yang diatur ke string yang berisi prefiks https:// dan nama server masuk, misalnya "https://myregistry.azurecr.io".

Membuat daftar tag secara asinkron

Sampel ini mengasumsikan registri memiliki hello-world repositori.

import asyncio
from dotenv import find_dotenv, load_dotenv
import os

from azure.containerregistry.aio import ContainerRegistryClient
from azure.identity.aio import DefaultAzureCredential


class ListTagsAsync(object):
    def __init__(self):
        load_dotenv(find_dotenv())

    async def list_tags(self):
        # Create a new ContainerRegistryClient      
        audience = "https://management.azure.com"
        account_url = os.environ["CONTAINERREGISTRY_ENDPOINT"]
        credential = DefaultAzureCredential()
        client = ContainerRegistryClient(account_url, credential, audience=audience)

        manifest = await client.get_manifest_properties("library/hello-world", "latest")
        print(manifest.repository_name + ": ")
        for tag in manifest.tags:
            print(tag + "\n")

Mengatur properti artefak secara asinkron

Sampel ini mengasumsikan registri memiliki hello-world repositori dengan citra yang memiliki tag v1.

import asyncio
from dotenv import find_dotenv, load_dotenv
import os

from azure.containerregistry.aio import ContainerRegistryClient
from azure.identity.aio import DefaultAzureCredential


class SetImagePropertiesAsync(object):
    def __init__(self):
        load_dotenv(find_dotenv())

    async def set_image_properties(self):
        # Create a new ContainerRegistryClient
        account_url = os.environ["CONTAINERREGISTRY_ENDPOINT"]
        audience = "https://management.azure.com"
        credential = DefaultAzureCredential()
        client = ContainerRegistryClient(account_url, credential, audience=audience)

        # [START update_manifest_properties]
        # Set permissions on the v1 image's "latest" tag
        await client.update_manifest_properties(
            "library/hello-world",
            "latest",
            can_write=False,
            can_delete=False
        )
        # [END update_manifest_properties]
        # After this update, if someone were to push an update to "myacr.azurecr.io\hello-world:v1", it would fail.
        # It's worth noting that if this image also had another tag, such as "latest", and that tag did not have
        # permissions set to prevent reads or deletes, the image could still be overwritten. For example,
        # if someone were to push an update to "myacr.azurecr.io\hello-world:latest"
        # (which references the same image), it would succeed.

Menghapus gambar secara asinkron

import asyncio
from dotenv import find_dotenv, load_dotenv
import os

from azure.containerregistry import ManifestOrder
from azure.containerregistry.aio import ContainerRegistryClient
from azure.identity.aio import DefaultAzureCredential


class DeleteImagesAsync(object):
    def __init__(self):
        load_dotenv(find_dotenv())

    async def delete_images(self):
        # [START list_repository_names]   
        audience = "https://management.azure.com"
        account_url = os.environ["CONTAINERREGISTRY_ENDPOINT"]
        credential = DefaultAzureCredential()
        client = ContainerRegistryClient(account_url, credential, audience=audience)

        async with client:
            async for repository in client.list_repository_names():
                print(repository)
                # [END list_repository_names]

                # [START list_manifest_properties]
                # Keep the three most recent images, delete everything else
                manifest_count = 0
                async for manifest in client.list_manifest_properties(repository, order_by=ManifestOrder.LAST_UPDATE_TIME_DESCENDING):
                    manifest_count += 1
                    if manifest_count > 3:
                        await client.delete_manifest(repository, manifest.digest)
                # [END list_manifest_properties]

Mulai

Referensi Paket kode sumber | (pkg.go.dev) | REST API

Pasang paket

Instal pustaka klien Azure Container Registry untuk Go dengan go get:

go get github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry

Mengautentikasi klien

Saat mengembangkan dan menelusuri kesalahan aplikasi secara lokal, Anda dapat menggunakan azidentity. NewDefaultAzureCredential untuk mengautentikasi. Sebaiknya gunakan identitas terkelola di lingkungan produksi.

import (
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry"
	"log"
)

func main() {
	cred, err := azidentity.NewDefaultAzureCredential(nil)
	if err != nil {
		log.Fatalf("failed to obtain a credential: %v", err)
	}

	client, err := azcontainerregistry.NewClient("https://myregistry.azurecr.io", cred, nil)
	if err != nil {
		log.Fatalf("failed to create client: %v", err)
	}
}

Lihat dokumentasi azidentitas untuk informasi selengkapnya tentang pendekatan autentikasi lainnya.

Contoh

Setiap sampel mengasumsikan URL titik akhir registri kontainer adalah "https://myregistry.azurecr.io".

Daftar tag

Sampel ini mengasumsikan registri memiliki hello-world repositori.

import (
	"context"
	"fmt"
	"github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry"
	"log"
)

func Example_listTagsWithAnonymousAccess() {
	client, err := azcontainerregistry.NewClient("https://myregistry.azurecr.io", nil, nil)
	if err != nil {
		log.Fatalf("failed to create client: %v", err)
	}
	ctx := context.Background()
	pager := client.NewListTagsPager("library/hello-world", nil)
	for pager.More() {
		page, err := pager.NextPage(ctx)
		if err != nil {
			log.Fatalf("failed to advance page: %v", err)
		}
		for _, v := range page.Tags {
			fmt.Printf("tag: %s\n", *v.Name)
		}
	}
}

Mengatur properti artefak

Sampel ini mengasumsikan registri memiliki hello-world repositori dengan citra yang memiliki tag latest.

package azcontainerregistry_test

import (
	"context"
	"fmt"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry"
	"log"
)

func Example_setArtifactProperties() {
	cred, err := azidentity.NewDefaultAzureCredential(nil)
	if err != nil {
		log.Fatalf("failed to obtain a credential: %v", err)
	}
	client, err := azcontainerregistry.NewClient("https://myregistry.azurecr.io", cred, nil)
	if err != nil {
		log.Fatalf("failed to create client: %v", err)
	}
	ctx := context.Background()
	res, err := client.UpdateTagProperties(ctx, "library/hello-world", "latest", &azcontainerregistry.ClientUpdateTagPropertiesOptions{
		Value: &azcontainerregistry.TagWriteableProperties{
			CanWrite:  to.Ptr(false),
			CanDelete: to.Ptr(false),
		}})
	if err != nil {
		log.Fatalf("failed to finish the request: %v", err)
	}
	fmt.Printf("repository library/hello-world - tag latest: 'CanWrite' property: %t, 'CanDelete' property: %t\n", *res.Tag.ChangeableAttributes.CanWrite, *res.Tag.ChangeableAttributes.CanDelete)
}

Hapus gambar

package azcontainerregistry_test

import (
	"context"
	"fmt"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry"
	"log"
)

func Example_deleteImages() {
	cred, err := azidentity.NewDefaultAzureCredential(nil)
	if err != nil {
		log.Fatalf("failed to obtain a credential: %v", err)
	}
	client, err := azcontainerregistry.NewClient("https://myregistry.azurecr.io", cred, nil)
	if err != nil {
		log.Fatalf("failed to create client: %v", err)
	}
	ctx := context.Background()
	repositoryPager := client.NewListRepositoriesPager(nil)
	for repositoryPager.More() {
		repositoryPage, err := repositoryPager.NextPage(ctx)
		if err != nil {
			log.Fatalf("failed to advance repository page: %v", err)
		}
		for _, r := range repositoryPage.Repositories.Names {
			manifestPager := client.NewListManifestsPager(*r, &azcontainerregistry.ClientListManifestsOptions{
				OrderBy: to.Ptr(azcontainerregistry.ArtifactManifestOrderByLastUpdatedOnDescending),
			})
			for manifestPager.More() {
				manifestPage, err := manifestPager.NextPage(ctx)
				if err != nil {
					log.Fatalf("failed to advance manifest page: %v", err)
				}
				imagesToKeep := 3
				for i, m := range manifestPage.Manifests.Attributes {
					if i >= imagesToKeep {
						for _, t := range m.Tags {
							fmt.Printf("delete tag from image: %s", *t)
							_, err := client.DeleteTag(ctx, *r, *t, nil)
							if err != nil {
								log.Fatalf("failed to delete tag: %v", err)
							}
						}
						_, err := client.DeleteManifest(ctx, *r, *m.Digest, nil)
						if err != nil {
							log.Fatalf("failed to delete manifest: %v", err)
						}
						fmt.Printf("delete image with digest: %s", *m.Digest)
					}
				}
			}
		}
	}
}

Membersihkan sumber daya

Jika ingin membersihkan dan menghapus Azure Container Registry, Anda dapat menghapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga menghapus sumber daya apa pun yang terkait dengannya.

Langkah berikutnya

Dalam mulai cepat ini, Anda telah mempelajari penggunaan pustaka klien Azure Container Registry untuk melakukan operasi pada citra dan artefak di registri kontainer Anda.