Python용 Azure Container Registry 클라이언트 라이브러리 - 버전 1.2.0
Azure Container Registry 모든 유형의 컨테이너 배포에 대해 프라이빗 레지스트리에 컨테이너 이미지 및 아티팩트 저장 및 관리할 수 있습니다.
Azure Container Registry 클라이언트 라이브러리를 사용하여 다음을 수행합니다.
- 레지스트리의 이미지 또는 아티팩트 나열
- 이미지 및 아티팩트, 리포지토리 및 태그에 대한 메타데이터 가져오기
- 레지스트리 항목에 대한 읽기/쓰기/삭제 속성 설정
- 이미지 및 아티팩트, 리포지토리 및 태그 삭제
소스 코드 | 패키지(Pypi) | 패키지(Conda) | API 참조 설명서 | REST API 설명서 | 제품 설명서
고지 사항
Python 2.7에 대한 Azure SDK Python 패키지 지원은 2022년 1월 1일에 종료되었습니다. 자세한 내용과 질문은 이 패키지를 사용하려면 https://github.com/Azure/azure-sdk-for-python/issues/20691Python 3.7 이상을 참조하세요. 자세한 내용은 Python용 Azure SDK 버전 지원 정책을 참조하세요.
시작
패키지 설치
pip를 사용하여 Python용 Azure Container Registry 클라이언트 라이브러리를 설치합니다.
pip install --pre azure-containerregistry
사전 요구 사항
- 이 패키지를 사용하려면 Python 3.7 이상이 필요합니다.
- 이 패키지를 사용하려면 Azure 구독 및 Container Registry 계정이 필요합니다.
새 Container Registry를 만들려면 Azure Portal, Azure PowerShell 또는 Azure CLI를 사용할 수 있습니다. 다음은 Azure CLI 사용 예입니다.
az acr create --name MyContainerRegistry --resource-group MyResourceGroup --location westus --sku Basic
클라이언트 인증
Azure ID 라이브러리는 인증을 위한 간편한 Azure Active Directory 지원을 제공합니다. 에서는 DefaultAzureCredential
, AZURE_TENANT_ID
및 AZURE_CLIENT_SECRET
환경 변수가 설정된다고 가정AZURE_CLIENT_ID
합니다. 자세한 내용은 Azure ID 환경 변수 섹션을 참조하세요.
# 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 아티팩트가 저장됩니다. 이미지 또는 아티팩트는 매니페스트와 레이어로 구성됩니다. 이미지의 매니페스트는 이미지를 구성하는 레이어를 설명하고 다이 제스트를 통해 고유하게 식별됩니다. 이미지를 "태그"로 지정하여 사람이 읽을 수 있는 별칭을 제공할 수도 있습니다. 이미지 또는 아티팩트와 연결된 태그가 0개 이상 있을 수 있으며 각 태그는 이미지를 고유하게 식별합니다. 이름이 같지만 태그가 다른 이미지 컬렉션을 리포지토리라고 합니다.
자세한 내용은 Container Registry 개념을 참조하세요.
예제
다음 섹션에서는 다음을 포함하여 가장 일반적인 ACR 서비스 작업 중 일부를 다루는 몇 가지 코드 조각을 제공합니다.
- 레지스트리 작업:
- Blob 및 매니페스트 작업:
각 샘플에서는 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)
익명 액세스 권한이 있는 태그 나열
익명 액세스를 사용하여 리포지토리의 태그 컬렉션을 반복합니다.
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)
이미지 업로드
전체 이미지를 업로드하려면 개별 계층 및 구성을 업로드해야 합니다. 그런 다음 이미지 또는 아티팩트를 설명하는 매니페스트를 업로드하고 태그를 할당할 수 있습니다.
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}")
이미지 다운로드
전체 이미지를 다운로드하려면 매니페스트를 다운로드한 다음 개별 계층 및 구성을 다운로드해야 합니다.
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}")
매니페스트 삭제
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에 정의된 예외를 발생합니다.
로깅
이 라이브러리는 로깅에 표준 로깅 라이브러리를 사용합니다.
HTTP 세션(URL, 헤더 등)에 대한 기본 정보는 수준에서 기록됩니다 INFO
.
DEBUG
요청/응답 본문 및 수정되지 않은 헤더를 포함한 자세한 수준 로깅은 클라이언트 또는 키워드(keyword) 인수를 logging_enable
사용하여 작업별로 사용하도록 설정할 수 있습니다.
여기에 예제가 있는 전체 SDK 로깅 설명서를 참조 하세요.
선택적 구성
선택적 키워드(keyword) 인수는 클라이언트 및 작업별 수준에서 전달할 수 있습니다. azure-core 참조 설명서 에서는 재시도, 로깅, 전송 프로토콜 등에 사용할 수 있는 구성에 대해 설명합니다.
다음 단계
- azure.containerregistry 및 샘플을 사용하여 더 자세히 설명합니다.
- 데모 또는 심층 분석 비디오를 시청하세요.
- Azure Container Registry 서비스에 대해 자세히 알아보세요.
참여
이 프로젝트에 대한 기여와 제안을 환영합니다. 대부분의 경우 기여하려면 권한을 부여하며 실제로 기여를 사용할 권한을 당사에 부여한다고 선언하는 CLA(기여자 라이선스 계약)에 동의해야 합니다. 자세한 내용은 cla.microsoft.com.
이 프로젝트에는 Microsoft Open Source Code of Conduct(Microsoft 오픈 소스 준수 사항)가 적용됩니다. 자세한 내용은 Code of Conduct FAQ(규정 FAQ)를 참조하세요. 또는 추가 질문이나 의견은 opencode@microsoft.com으로 문의하세요.
Azure SDK for Python
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기