Share via


Registro de Contêiner do Azure biblioteca de clientes para Python – versão 1.2.0

Registro de Contêiner do Azure permite armazenar e gerenciar imagens e artefatos de contêiner em um registro privado para todos os tipos de implantações de contêiner.

Use a biblioteca de clientes do Registro de Contêiner do Azure para:

  • Listar imagens ou artefatos em um registro
  • Obter metadados para imagens e artefatos, repositórios e marcas
  • Definir propriedades de leitura/gravação/exclusão em itens do registro
  • Excluir imagens e artefatos, repositórios e marcas

Código-fonte | Pacote (Pypi) | Pacote (Conda) | Documentação | de referência da APIDocumentação | da API RESTDocumentação do produto

Aviso de isenção de responsabilidade

O suporte a pacotes python do SDK do Azure para Python 2.7 terminou em 01 de janeiro de 2022. Para obter mais informações e perguntas, consulte https://github.com/Azure/azure-sdk-for-python/issues/20691Python 3.7 ou posterior é necessário para usar esse pacote. Para obter mais detalhes, consulte a política de suporte do SDK do Azure para Python.

Introdução

Instalar o pacote

Instale a biblioteca de clientes do Registro de Contêiner do Azure para o Python com o pip:

pip install --pre azure-containerregistry

Pré-requisitos

Para criar um novo Registro de Contêiner, você pode usar o Portal do Azure, Azure PowerShell ou a CLI do Azure. Aqui, está um exemplo usando a CLI do Azure:

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

Autenticar o cliente

A biblioteca de Identidade do Azure fornece suporte fácil ao Azure Active Directory para autenticação. O DefaultAzureCredential pressupõe que as AZURE_CLIENT_IDvariáveis de ambiente , AZURE_TENANT_IDe AZURE_CLIENT_SECRET estão definidas, para obter mais informações, consulte a seção Variáveis de ambiente de identidade do Azure

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

endpoint = "https://mycontainerregistry.azurecr.io"
audience = "https://management.azure.com"
client = ContainerRegistryClient(endpoint, DefaultAzureCredential(), audience=audience)

Principais conceitos

Um registro armazena imagens do Docker e artefatos OCI. Uma imagem ou um artefato consiste em um manifesto e em camadas. O manifesto de uma imagem descreve as camadas que compõem a imagem e é identificado exclusivamente por seu resumo. Uma imagem também pode ser "marcada" para dar a ela um alias legível por humanos. Uma imagem ou artefato pode ter zero ou mais marcas associadas a ela e cada marca identifica exclusivamente a imagem. Uma coleção de imagens que compartilham o mesmo nome, mas têm marcas diferentes, é conhecida como um repositório.

Para obter mais informações, consulte Conceitos do Registro de Contêiner.

Exemplos

As seções a seguir fornecem vários snippets de código que abrangem algumas das tarefas mais comuns do Serviço do ACR, incluindo:

Observe que cada exemplo pressupõe que há uma CONTAINERREGISTRY_ENDPOINT variável de ambiente definida como uma cadeia de caracteres que contém o https:// prefixo e o nome do servidor de logon, por exemplo"https://myregistry.azurecr.io". Exemplos de acesso anônimo estão obtendo o valor do ponto de extremidade da variávelCONTAINERREGISTRY_ANONREGISTRY_ENDPOINT de ambiente.

Listar repositórios

Itere na coleção de repositórios no registro.

with ContainerRegistryClient(self.endpoint, self.credential) as client:
    # Iterate through all the repositories
    for repository_name in client.list_repository_names():
        print(repository_name)

Listar marcas com acesso anônimo

Iterar por meio da coleção de marcas no repositório com acesso anônimo.

with ContainerRegistryClient(endpoint) as anon_client:
    manifest = anon_client.get_manifest_properties("library/hello-world", "latest")
    print(f"Tags of {manifest.repository_name}: ")
    # Iterate through all the tags
    for tag in manifest.tags:
        print(tag)

Definir propriedades do artefato

Definir propriedades de um artefato.

with ContainerRegistryClient(self.endpoint, self.credential) as client:
    # Set permissions on image "library/hello-world:v1"
    client.update_manifest_properties(
        "library/hello-world",
        "v1",
        can_write=False,
        can_delete=False
    )

Excluir imagens

Exclua imagens mais antigas do que as três primeiras no repositório.

with ContainerRegistryClient(self.endpoint, self.credential) as client:
    for repository in client.list_repository_names():
        # Keep the three most recent images, delete everything else
        manifest_count = 0
        for manifest in client.list_manifest_properties(
            repository, order_by=ArtifactManifestOrder.LAST_UPDATED_ON_DESCENDING
        ):
            manifest_count += 1
            if manifest_count > 3:
                # Make sure will have the permission to delete the manifest later
                client.update_manifest_properties(
                    repository,
                    manifest.digest,
                    can_write=True,
                    can_delete=True
                )
                print(f"Deleting {repository}:{manifest.digest}")
                client.delete_manifest(repository, manifest.digest)

Carregar imagens

Para carregar uma imagem completa, precisamos carregar camadas e configurações individuais. Depois disso, podemos carregar um manifesto que descreve uma imagem ou artefato e atribuí-lo a uma marca.

self.repository_name = "sample-oci-image"
layer = BytesIO(b"Sample layer")
config = BytesIO(json.dumps(
    {
        "sample config": "content",
    }).encode())
with ContainerRegistryClient(self.endpoint, self.credential) as client:
    # Upload a layer
    layer_digest, layer_size = client.upload_blob(self.repository_name, layer)
    print(f"Uploaded layer: digest - {layer_digest}, size - {layer_size}")
    # Upload a config
    config_digest, config_size = client.upload_blob(self.repository_name, config)
    print(f"Uploaded config: digest - {config_digest}, size - {config_size}")
    # Create an oci image with config and layer info
    oci_manifest = {
        "config": {
            "mediaType": "application/vnd.oci.image.config.v1+json",
            "digest": config_digest,
            "sizeInBytes": config_size,
        },
        "schemaVersion": 2,
        "layers": [
            {
                "mediaType": "application/vnd.oci.image.layer.v1.tar",
                "digest": layer_digest,
                "size": layer_size,
                "annotations": {
                    "org.opencontainers.image.ref.name": "artifact.txt",
                },
            },
        ],
    }
    # Set the image with tag "latest"
    manifest_digest = client.set_manifest(self.repository_name, oci_manifest, tag="latest")
    print(f"Uploaded manifest: digest - {manifest_digest}")

Baixar imagens

Para baixar uma imagem completa, precisamos baixar seu manifesto e baixar camadas e configurações individuais.

with ContainerRegistryClient(self.endpoint, self.credential) as client:
    # Get the image
    get_manifest_result = client.get_manifest(self.repository_name, "latest")
    received_manifest = get_manifest_result.manifest
    print(f"Got manifest:\n{received_manifest}")
    
    # Download and write out the layers
    for layer in received_manifest["layers"]:
        # Remove the "sha256:" prefix from digest
        layer_file_name = layer["digest"].split(":")[1]
        try:
            stream = client.download_blob(self.repository_name, layer["digest"])
            with open(layer_file_name, "wb") as layer_file:
                for chunk in stream:
                    layer_file.write(chunk)
        except DigestValidationError:
            print(f"Downloaded layer digest value did not match. Deleting file {layer_file_name}.")
            os.remove(layer_file_name)
        print(f"Got layer: {layer_file_name}")
    # Download and write out the config
    config_file_name = "config.json"
    try:
        stream = client.download_blob(self.repository_name, received_manifest["config"]["digest"])
        with open(config_file_name, "wb") as config_file:
            for chunk in stream:
                config_file.write(chunk)
    except DigestValidationError:
        print(f"Downloaded config digest value did not match. Deleting file {config_file_name}.")
        os.remove(config_file_name)
    print(f"Got config: {config_file_name}")

Excluir manifesto

with ContainerRegistryClient(self.endpoint, self.credential) as client:
    get_manifest_result = client.get_manifest(self.repository_name, "latest")
    # Delete the image
    client.delete_manifest(self.repository_name, get_manifest_result.digest)

Excluir Blob

with ContainerRegistryClient(self.endpoint, self.credential) as client:
    get_manifest_result = client.get_manifest(self.repository_name, "latest")
    received_manifest = get_manifest_result.manifest
    # Delete the layers
    for layer in received_manifest["layers"]:
        client.delete_blob(self.repository_name, layer["digest"])
    # Delete the config
    client.delete_blob(self.repository_name, received_manifest["config"]["digest"])

Solução de problemas

Para obter informações sobre solução de problemas, consulte o guia de solução de problemas.

Geral

A biblioteca de clientes do ACR gerará exceções definidas no Azure Core.

Registro em log

Essa biblioteca usa a biblioteca de log padrão para registro em log.

Informações básicas sobre sessões HTTP (URLs, cabeçalhos etc.) são registradas no INFO nível.

O log de nível detalhadoDEBUG, incluindo corpos de solicitação/resposta e cabeçalhos não redigidos, pode ser habilitado no cliente ou por operação com o logging_enable argumento palavra-chave.

Confira a documentação completa de registro em log do SDK com exemplos aqui.

Configuração opcional

Argumentos opcionais de palavra-chave podem ser passados no nível do cliente e por operação. A documentação de referência do azure-core descreve as configurações disponíveis para repetições, registro em log, protocolos de transporte e muito mais.

Próximas etapas

Contribuição

Este projeto aceita contribuições e sugestões. A maioria das contribuições exige que você concorde com um CLA (Contrato de Licença do Colaborador) declarando que você tem o direito de nos conceder, e de fato concede, os direitos de usar sua contribuição. Para obter detalhes, visite cla.microsoft.com.

Este projeto adotou o Código de Conduta de Software Livre da Microsoft. Para obter mais informações, confira as Perguntas frequentes sobre o Código de Conduta ou contate opencode@microsoft.com para enviar outras perguntas ou comentários.

Impressões