跳转到主要内容

Microsoft Azure Azure容器注册表Python客户端库

项目描述

Azure容器注册表Python客户端库

Azure容器注册表允许您在私有注册表中存储和管理所有类型容器部署的容器镜像和工件。

使用Azure容器注册表的客户端库可以

  • 列出注册表中的镜像或工件
  • 获取镜像和工件的元数据,存储库和标签
  • 在注册表项上设置读写/删除属性
  • 删除镜像和工件,存储库和标签

源代码 | 包(Pypi) | 包(Conda) | API参考文档 | REST API文档 | 产品文档

免责声明

Azure SDK Python包对Python 2.7的支持已于2022年1月1日结束。有关更多信息及疑问,请参考 https://github.com/Azure/azure-sdk-for-python/issues/20691 使用此包需要Python 3.7或更高版本。有关更多详细信息,请参考 Azure SDK for Python版本支持策略

入门指南

安装包

使用pip安装Azure Container Registry客户端库

pip install --pre azure-containerregistry

先决条件

要创建新的容器注册表,您可以使用Azure门户Azure PowerShellAzure CLI。以下是一个使用Azure CLI的示例:

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

验证客户端

Azure Identity库提供了简单的Azure Active Directory身份验证支持。DefaultAzureCredential假定已设置环境变量AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_CLIENT_SECRET,有关更多信息请参考Azure Identity环境变量部分

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

关键概念

注册表存储Docker镜像和OCI工件。一个镜像或工件由一个manifestlayers组成。镜像的manifest描述了构成镜像的层,并由其digest唯一标识。镜像还可以“标记”以赋予其可读的别名。一个镜像或工件可以关联零个或多个tags,每个tag唯一标识该镜像。具有相同名称但不同tags的镜像集合称为仓库

有关更多信息,请参阅容器注册表概念

示例

以下部分提供了几个代码片段,涵盖了ACR服务的一些常见任务,包括:

请注意,每个示例都假定已设置环境变量CONTAINERREGISTRY_ENDPOINT,其值为包含https://前缀和登录服务器名称的字符串,例如 "https://myregistry.azurecr.io"。匿名访问示例是从环境变量CONTAINERREGISTRY_ANONREGISTRY_ENDPOINT获取端点值。

列出仓库

遍历注册表中的仓库集合。

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

使用匿名访问列出tags

遍历仓库中的tags集合,使用匿名访问。

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)

设置工件属性

设置工件的属性。

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
    )

删除镜像

删除仓库中排名前三的镜像。

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)

上传镜像

要上传完整的镜像,我们需要上传单个层和配置。然后我们可以上传一个描述镜像或工件的manifest并为其分配一个tag。

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

下载镜像

要下载完整的镜像,我们需要下载其manifest,然后下载单个层和配置。

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

删除manifest

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)

删除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"])

故障排除

有关故障排除的信息,请参考故障排除指南

通用

ACR客户端库会抛出Azure Core中定义的异常。

日志记录

此库使用标准logging库进行日志记录。

HTTP会话的基本信息(URL、头部等)以INFO级别记录。

启用详细的DEBUG级别日志,包括请求/响应体和未编辑的头部,可以通过在客户端或每个操作中使用logging_enable关键字参数来实现。

请参阅完整的SDK日志文档和示例这里

可选配置

可选关键字参数可以在客户端和每个操作级别传递。azure-core的参考文档描述了重试、日志记录、传输协议等可用的配置。

下一步

贡献

本项目欢迎贡献和建议。大多数贡献需要您同意贡献者许可协议(CLA),声明您有权并且实际上授予我们使用您贡献的权利。有关详细信息,请访问cla.microsoft.com

本项目已采用Microsoft开源行为准则。有关更多信息,请参阅行为准则FAQ或通过opencode@microsoft.com联系,以获取任何额外的问题或评论。

Impressions

项目详情


下载文件

下载适用于您平台的应用程序。如果您不确定选择哪个,请了解更多关于安装软件包的信息。

源分布

azure-containerregistry-1.2.0.zip (159.6 kB 查看哈希值)

上传时间

构建分布

azure_containerregistry-1.2.0-py3-none-any.whl (101.2 kB 查看哈希值)

上传时间 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面