Azure Container Registry bibliothèque de client pour .NET - version 1.1.0

Azure Container Registry vous permet de stocker et de gérer des images conteneur et des artefacts dans un registre privé pour tous les types de déploiements de conteneurs.

Utilisez la bibliothèques de client pour Azure Container Registry afin de :

  • Lister des images ou des artefacts dans un registre.
  • Obtenir des métadonnées pour les images et les artefacts, les référentiels et les étiquettes
  • Définir les propriétés de lecture/écriture/suppression sur des éléments du registre.
  • Supprimer des images et des artefacts, des référentiels et des étiquettes

| Code sourcePackage (NuGet) | Documentation de référence sur les | API Documentation | sur l’API RESTDocumentation produit

Prise en main

Pour développer du code d’application .NET capable de se connecter à une instance d’Azure Container Registry, vous aurez besoin de la bibliothèque Azure.Containers.ContainerRegistry.

Installer le package

Installez la bibliothèque de client Azure Container Registry pour .NET avec NuGet :

dotnet add package Azure.Containers.ContainerRegistry

Prérequis

Vous aurez besoin d’un abonnement Azure et d’un service Container Registry instance auquel votre application peut se connecter.

Pour créer un registre de conteneurs, vous pouvez utiliser le portail Azure, Azure PowerShell ou Azure CLI. Voici un exemple de création d’un registre à l’aide d’Azure CLI :

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

Authentifier le client

Pour que votre application se connecte à votre registre, vous devez créer un ContainerRegistryClient qui peut s’authentifier auprès de celui-ci. La bibliothèque d’identités Azure facilite l’ajout de la prise en charge d’Azure Active Directory pour l’authentification des clients du Kit de développement logiciel (SDK) Azure auprès de leurs services Azure correspondants.

Lorsque vous développez et déboguez votre application localement, vous pouvez utiliser votre propre utilisateur pour vous authentifier auprès de votre registre. L’une des manières d’y parvenir consiste à authentifier votre utilisateur auprès d’Azure CLI et à exécuter votre application à partir de cet environnement. Si votre application utilise un client qui a été construit pour s’authentifier avec DefaultAzureCredential, il s’authentifiera correctement auprès du registre au point de terminaison spécifié.

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

Pour plus d’approches de l’authentification avec DefaultAzureCredential, consultez le FICHIER LISEZ-MOI d’identité Azure, tant localement que dans les environnements de déploiement. Pour vous connecter à des registres dans des clouds Azure non publics, consultez les exemples ci-dessous.

Pour plus d’informations sur l’utilisation d’AAD avec Azure Container Registry, consultez vue d’ensemble de l’authentification du service.

Concepts clés

Un registre stocke les images Docker et les artefacts OCI. Une image ou un artefact se compose d’un manifeste et de couches. Le manifeste d’une image décrit les couches qui composent l’image et est identifié de manière unique par son condensé. Une image peut également être « étiquetée » pour lui donner un alias lisible par l’homme. Une image ou un artefact peut avoir zéro ou plusieurs balises associées , et chaque balise identifie l’image de manière unique. Une collection d’images qui partagent le même nom, mais qui ont des balises différentes, est appelée dépôt.

Pour plus d’informations, consultez Concepts de Container Registry.

Sécurité des threads

Nous garantissons que toutes les méthodes de instance client sont thread-safe et indépendantes les unes des autres (instructions). Cela garantit que la recommandation de réutilisation des instances clientes est toujours sécurisée, même entre les threads.

Concepts supplémentaires

Options | du client Accès à la réponse | Opérations | de longue duréeGestion des défaillances | Diagnostics | Moqueur | Durée de vie du client

Exemples

Les extraits de code suivants montrent de brefs exemples de scénarios de développement courants utilisant la bibliothèque du SDK ACR. Notez que chaque exemple suppose qu’il existe une variable d’environnement REGISTRY_ENDPOINT définie sur une chaîne contenant le https:// préfixe et le nom du serveur de connexion, par exemple « https://myregistry.azurecr.io".

Exemples de synchronisation

Exemples asynchrones

Authentification avancée

Opérations du registre

Cette sécion contient ContainerRegistryClient des exemples.

Répertorier les référentiels

Itérez au sein de la collection de référentiels dans le registre.

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

Répertorier les étiquettes avec accès anonyme

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

Définir les propriétés des artefacts

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

Supprimer des images

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

Lister les référentiels de manière asynchrone

Les API asynchrones sont identiques à leurs équivalents synchrones, mais les méthodes se terminent par le suffixe « Async » .NET standard et retournent une tâche.

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

Répertorier les étiquettes avec accès anonyme de façon asynchrone

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

Définir des propriétés d’artefacts de manière asynchrone

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

Supprimer des images de manière asynchrone

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

Opérations d’objet blob et de manifeste

Cette section contient des exemples qui ContainerRegistryContentClient montrent comment charger et télécharger des images.

Tout d’abord, créez un client d’objets 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());

Charger des images

Pour charger une image complète, nous devons charger des couches et une configuration individuelles. Après cela, nous pouvons charger un manifeste qui décrit une image ou un artefact et lui attribuer une balise.

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

Télécharger des images

Pour télécharger une image complète, nous devons télécharger son manifeste, puis télécharger les couches et la configuration individuelles.

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

Supprimer le manifeste

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

Supprimer un objet blob

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

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

Authentification avancée

S’authentifier dans un cloud national

Pour vous authentifier auprès d’un registre dans un cloud national, vous devez effectuer les ajouts suivants à votre configuration client :

  • Définir dans AuthorityHost les options d’informations d’identification ou via la variable d’environnement AZURE_AUTHORITY_HOST
  • Définir le Audience dans ContainerRegistryClientOptions
// 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
    });

Dépannage

Consultez notre guide de résolution des problèmes pour plus d’informations sur la façon de diagnostiquer différents scénarios d’échec.

Étapes suivantes

Contribution

Ce projet accepte les contributions et les suggestions. La plupart des contributions vous demandent d’accepter un contrat de licence de contribution (CLA) déclarant que vous avez le droit de nous accorder, et que vous nous accordez réellement, les droits d’utilisation de votre contribution. Pour plus d’informations, visitez cla.microsoft.com.

Ce projet a adopté le Code de conduite Open Source de Microsoft. Pour plus d’informations, consultez les Questions fréquentes (FAQ) sur le code de conduite ou envoyez vos questions ou vos commentaires à opencode@microsoft.com.

Impressions