Краткое руководство. Использование клиентских библиотек Реестра контейнеров Azure

Ознакомьтесь со сведениями этой статьи, чтобы начать работу с клиентской библиотекой для Реестра контейнеров Azure. Выполните указанные ниже действия, чтобы опробовать пример кода для операций плоскости данных на изображениях и артефактах.

Используйте клиентскую библиотеку для Реестра контейнеров Azure, чтоб выполнить следующие действия:

  • Составить список образов или артефактов в реестре.
  • Получить метаданные для изображений и артефактов, репозиториев и тегов.
  • Задать свойства чтения, записи и удаления для элементов реестра.
  • Удалить образы, артефакты, репозитории и теги.

Реестр контейнеров Azure также содержит библиотеку управления для операций уровня управления, включая создание и обновление реестра.

Необходимые компоненты

Основные понятия

  • В реестре контейнеров Azure хранятся образы контейнеров и артефакты OCI.
  • Образ или артефакт состоит из манифеста и слоев.
  • Манифест описывает слои, составляющие образ или артефакт. Он идентифицируется исключительно по хэш-коду.
  • Образ или артефакт можно также пометить тегом, чтобы дать ему понятный псевдоним. С образом или артефактом может быть не связано ни одного тега или связано сразу несколько, и каждый тег уникально идентифицирует образ.
  • Коллекция образов или артефактов, имеющих одно и то же имя, но разные тэги, является репозиторием.

Дополнительные сведения см. в статье о реестрах, репозиториях и артефактах.

Начало работы

Исходный код | Пакет (NuGet) | Справочник по API | Примеры

Для разработки кода приложения .NET, который может подключаться к экземпляру Реестра контейнеров Azure, потребуется библиотека Azure.Containers.ContainerRegistry.

Установка пакета

Установите клиентскую библиотеку Реестра контейнеров Azure для .NET с помощью NuGet:

dotnet add package Azure.Containers.ContainerRegistry --prerelease

аутентификация клиента;

Для подключения приложения к реестру необходимо создать элемент ContainerRegistryClient, который может пройти проверку подлинности. Используйте библиотеку удостоверений Azure, чтобы добавить поддержку идентификатора Microsoft Entra для проверки подлинности клиентов Azure SDK с соответствующими службами Azure.

При локальной разработке и отладке приложения можно использовать собственного пользователя для проверки подлинности в реестре. Один из способов это сделать — выполнить проверку подлинности пользователя с помощью 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. Сведения о подключении к реестрам в облаках Azure, не являющихся общедоступными, см. в справочнике по API.

Дополнительные сведения об использовании идентификатора Microsoft Entra с Реестр контейнеров Azure см. в обзоре проверки подлинности.

Примеры

В каждом примере предполагается, что существует переменная среды REGISTRY_ENDPOINT, заданная в строке, содержащей префикс https://, и имя сервера входа, например "https://myregistry.azurecr.io"".

В следующих примерах используются асинхронные API-интерфейсы, возвращающие задачу. Доступны также синхронные API-интерфейсы.

Асинхронное составление списка репозиториев

Выполните итерацию по коллекции репозиториев в реестре.

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

Асинхронное задание свойств артефакта

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

Асинхронное удаление образов

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

Начало работы

Исходный код | Пакет (Maven) | Справочник по API | Примеры

Поддерживаемые в настоящее время среды

Включение пакета

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

аутентификация клиента;

Библиотека удостоверений Azure предоставляет поддержку идентификатора Microsoft Entra для проверки подлинности.

В следующих примерах предполагается, что у вас есть строка конечной точки реестра, содержащая префикс https:// и имя сервера входа, например "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();

Дополнительные сведения об использовании идентификатора Microsoft Entra с Реестр контейнеров Azure см. в обзоре проверки подлинности.

Примеры

В каждом примере предполагается, что у вас есть строка конечной точки реестра, содержащая префикс https:// и имя сервера входа, например "https://myregistry.azurecr.io"".

Составление списка имен репозиториев

Выполните итерацию по коллекции репозиториев в реестре.

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

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

Задание свойств артефакта

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

Удаление изображений

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

Начало работы

Исходный код | Пакет (npm) | Справочник по API | Примеры

Поддерживаемые в настоящее время среды

Чтобы получить дополнительные сведения, ознакомьтесь с нашей политикой поддержки.

Установите пакет @azure/container-registry.

Установите клиентскую библиотеку Реестра контейнеров для JavaScript с помощью npm:

npm install @azure/container-registry

аутентификация клиента;

Библиотека удостоверений Azure предоставляет поддержку идентификатора Microsoft Entra для проверки подлинности.

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());

Дополнительные сведения об использовании идентификатора Microsoft Entra с Реестр контейнеров Azure см. в обзоре проверки подлинности.

Примеры

В каждом примере предполагается, что существует переменная среды CONTAINER_REGISTRY_ENDPOINT, заданная в строке, содержащей префикс https://, и имя сервера входа, например "https://myregistry.azurecr.io"".

Асинхронное составление списка репозиториев

Выполните итерацию по коллекции репозиториев в реестре.

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

Асинхронное задание свойств артефакта

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

Асинхронное удаление образов

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

Начало работы

Исходный код | Пакет (Pypi) | Справочник по API | Примеры

Установка пакета

Установите клиентскую библиотеку Реестра контейнеров Azure для Python с помощью pip:

pip install --pre azure-containerregistry

аутентификация клиента;

Библиотека удостоверений Azure предоставляет поддержку идентификатора Microsoft Entra для проверки подлинности. В DefaultAzureCredential предполагается, что переменные среды AZURE_CLIENT_ID, AZURE_TENANT_ID и AZURE_CLIENT_SECRET установлены. Дополнительную информацию см. в разделе Переменные среды удостоверения 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())

Примеры

В каждом примере предполагается, что существует переменная среды CONTAINERREGISTRY_ENDPOINT, заданная в строке, содержащей префикс https://, и имя сервера входа, например "https://myregistry.azurecr.io"".

Асинхронное составление списка тегов

В этом примере предполагается, что в реестре есть репозиторий hello-world.

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")

Асинхронное задание свойств артефакта

В этом примере предполагается, что в реестре есть репозиторий hello-world с образом, помеченным тегом 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.

Асинхронное удаление образов

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]

Начало работы

Справочник по REST API исходного кода | (pkg.go.dev) | REST API

Установка пакета

Установка клиентской библиотеки Реестр контейнеров Azure для Go с помощьюgo get:

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

аутентификация клиента;

При локальной разработке и отладке приложения можно использовать azidentity. NewDefaultAzureCredential для проверки подлинности. Рекомендуется использовать управляемое удостоверение в рабочей среде.

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

Дополнительные сведения о других подходах проверки подлинности см. в документации по azidentity .

Примеры

Каждый пример предполагает, что URL-адрес конечной точки реестра контейнеров имеет значение "https://myregistry.azurecr.io".

Вывод списка тегов

В этом примере предполагается, что в реестре есть репозиторий hello-world.

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

Задание свойств артефакта

В этом примере предполагается, что в реестре есть репозиторий hello-world с образом, помеченным тегом 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)
}

Удаление изображений

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

Очистка ресурсов

Если вы хотите очистить и удалить ресурс Реестра контейнеров Azure, вы можете удалить ресурс или группу ресурсов. При удалении группы ресурсов также удаляются все связанные с ней ресурсы.

Следующие шаги

Из этого краткого руководства вы узнали, как использовать клиентскую библиотеку Реестра контейнеров Azure для выполнения операций с образами и артефактами в реестре контейнеров.

  • Дополнительные сведения см. в справочной документации по API:

  • Дополнительные сведения о REST API Реестра контейнеров Azure.