biblioteca cliente de Azure Container Registry para JavaScript: versión 1.1.0

Azure Container Registry permite almacenar y administrar imágenes y artefactos de contenedor en un registro privado para todos los tipos de implementaciones de contenedor.

Use la biblioteca cliente de Azure Container Registry para lo siguiente:

  • Enumeración de imágenes o artefactos en un registro
  • Obtención de metadatos para imágenes y artefactos, repositorios y etiquetas
  • Establecimiento de propiedades de lectura, escritura y eliminación en elementos del registro
  • Eliminación de imágenes y artefactos, repositorios y etiquetas

Vínculos principales:

Introducción

Entornos admitidos actualmente

Para más información, consulte la directiva de compatibilidad.

Nota: Este paquete no se puede usar en el explorador debido a las limitaciones del servicio, consulte este documento para obtener instrucciones.

Prerrequisitos

Para crear una instancia de Container Registry, puede usar Azure Portal, Azure PowerShell o la CLI de Azure. A continuación se facilita un ejemplo mediante el uso de la CLI de Azure:

az acr create --name MyContainerRegistry --resource-group MyResourceGroup --location westus --sku Basic

Instalar el paquete @azure/container-registry

Instale la biblioteca cliente de Container Registry para JavaScript con npm:

npm install @azure/container-registry

Autenticar el cliente

La biblioteca de identidades de Azure proporciona compatibilidad sencilla con Azure Active Directory para la autenticación.

const {
  ContainerRegistryClient,
  KnownContainerRegistryAudience,
} = 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(), {
  audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud,
});

Tenga en cuenta que en estos ejemplos se supone que tiene una CONTAINER_REGISTRY_ENDPOINT variable de entorno establecida, que es la dirección URL, incluido el nombre del servidor de inicio de sesión y el https:// prefijo.

Nubes nacionales

Para autenticarse con un registro en una nube nacional, deberá realizar las siguientes adiciones a la configuración:

  • Establecer en authorityHost las opciones de credenciales o a través de la variable de AZURE_AUTHORITY_HOST entorno
  • Establecer en audienceContainerRegistryClientOptions
const {
  ContainerRegistryClient,
  KnownContainerRegistryAudience,
} = require("@azure/container-registry");
const { DefaultAzureCredential, AzureAuthorityHosts } = require("@azure/identity");

const endpoint = process.env.CONTAINER_REGISTRY_ENDPOINT;
// Create a ContainerRegistryClient that will authenticate through AAD in the China national cloud
const client = new ContainerRegistryClient(
  endpoint,
  new DefaultAzureCredential({ authorityHost: AzureAuthorityHosts.AzureChina }),
  {
    audience: KnownContainerRegistryAudience.AzureResourceManagerChina,
  }
);

Para obtener más información sobre el uso de AAD con Azure Container Registry, consulte La información general sobre la autenticación del servicio.

Conceptos clave

Un registro almacena imágenes de Docker y artefactos de OCI. Una imagen o artefacto se compone de un manifiesto y capas. El manifiesto de una imagen describe las capas que componen la imagen y se identifica de forma única por su síntesis. Una imagen también se puede "etiquetar" para darle un alias legible. Una imagen o artefacto puede tener cero o más etiquetas asociadas y cada etiqueta identifica de forma única la imagen. Una colección de imágenes que comparten el mismo nombre, pero que tienen etiquetas diferentes, se conoce como repositorio.

Para más información, consulte Conceptos de Container Registry.

Ejemplos

Operaciones de registro

Enumeración de repositorios

Recorra en iteración la colección de repositorios del registro.

const {
  ContainerRegistryClient,
  KnownContainerRegistryAudience,
} = 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(), {
    audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud,
  });

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

Enumerar etiquetas con acceso anónimo

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

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

  // Create a new ContainerRegistryClient for anonymous access
  const client = new ContainerRegistryClient(endpoint, {
    audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud,
  });

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

  // List the set of tags on the hello_world image tagged as "latest"
  const tagIterator = image.listTagProperties();

  // Iterate through the image's tags, listing the tagged alias for the image
  console.log(`${image.fullyQualifiedReference}  has the following aliases:`);
  for await (const tag of tagIterator) {
    console.log(`  ${tag.registryLoginServer}/${tag.repositoryName}:${tag.name}`);
  }
}

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

Establecimiento de propiedades de artefactos

const {
  ContainerRegistryClient,
  KnownContainerRegistryAudience,
} = 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(), {
    audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud,
  });
  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);
});

Eliminación de imágenes

const {
  ContainerRegistryClient,
  KnownContainerRegistryAudience,
} = 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(), {
    audience: KnownContainerRegistryAudience.AzureResourceManagerPublicCloud,
  });

  // 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 `order` option
    const imageManifests = repository.listManifestProperties({
      order: "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);
});

Operaciones de blob y manifiesto

Carga de imágenes

const { ContainerRegistryContentClient } = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");
require("dotenv").config();

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 repository = process.env.CONTAINER_REGISTRY_REPOSITORY || "library/hello-world";
  const client = new ContainerRegistryContentClient(
    endpoint,
    repository,
    new DefaultAzureCredential()
  );

  const config = Buffer.from("Sample config");
  const { digest: configDigest, sizeInBytes: configSize } = await client.uploadBlob(config);

  const layer = Buffer.from("Sample layer");
  const { digest: layerDigest, sizeInBytes: layerSize } = await client.uploadBlob(layer);

  const manifest = {
    schemaVersion: 2,
    config: {
      digest: configDigest,
      size: configSize,
      mediaType: "application/vnd.oci.image.config.v1+json",
    },
    layers: [
      {
        digest: layerDigest,
        size: layerSize,
        mediaType: "application/vnd.oci.image.layer.v1.tar",
      },
    ],
  };

  await client.setManifest(manifest, { tag: "demo" });
}

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

Descargar imágenes

const {
  ContainerRegistryContentClient,
  KnownManifestMediaType,
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");
const dotenv = require("dotenv");
const fs = require("fs");
dotenv.config();

function trimSha(digest) {
  const index = digest.indexOf(":");
  return index === -1 ? digest : digest.substring(index);
}

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 repository = process.env.CONTAINER_REGISTRY_REPOSITORY || "library/hello-world";
  const client = new ContainerRegistryContentClient(
    endpoint,
    repository,
    new DefaultAzureCredential()
  );

  // Download the manifest to obtain the list of files in the image based on the tag
  const result = await client.getManifest("demo");

  if (result.mediaType !== KnownManifestMediaType.OciImageManifest) {
    throw new Error("Expected an OCI image manifest");
  }

  const manifest = result.manifest;

  // Manifests of all media types have a buffer containing their content; this can be written to a file.
  fs.writeFileSync("manifest.json", result.content);

  const configResult = await client.downloadBlob(manifest.config.digest);
  const configFile = fs.createWriteStream("config.json");
  configResult.content.pipe(configFile);

  // Download and write out the layers
  for (const layer of manifest.layers) {
    const fileName = trimSha(layer.digest);
    const layerStream = fs.createWriteStream(fileName);
    const downloadLayerResult = await client.downloadBlob(layer.digest);
    downloadLayerResult.content.pipe(layerStream);
  }
}

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

Eliminar manifiesto

const { ContainerRegistryContentClient } = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");
require("dotenv").config();

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

  const downloadResult = await client.getManifest("latest");
  await client.deleteManifest(downloadResult.digest);
}

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

Eliminación de un blob

const {
  ContainerRegistryContentClient,
  KnownManifestMediaType,
} = require("@azure/container-registry");
const { DefaultAzureCredential } = require("@azure/identity");
require("dotenv").config();

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

  const downloadResult = await client.getManifest("latest");

  if (downloadResult.mediaType !== KnownManifestMediaType.OciImageManifest) {
    throw new Error("Expected an OCI image manifest");
  }

  for (const layer of downloadResult.manifest.layers) {
    await client.deleteBlob(layer.digest);
  }
}

Solución de problemas

Para obtener información sobre la solución de problemas, consulte la guía de solución de problemas.

Pasos siguientes

Eche un vistazo al directorio de ejemplos para obtener ejemplos detallados que muestran cómo usar las bibliotecas cliente.

Contribuciones

Si desea contribuir a esta biblioteca, lea la guía de contribución para obtener más información sobre cómo compilar y probar el código.

Impresiones