使用Python SDK创建Azure容器实例时遭遇权限访问问题
问题描述
我通过Azure CLI可以成功从Azure容器注册表(ACR)运行Docker容器:
az login az container create -g RESOURCE-GROUP --name INSTANCE-GROUP --image workers.azurecr.io/MY-IMAGE:latest --registry-username USERNAME --registry-password PSWD
但使用Python SDK操作时却失败,报错信息如下:
Code: InaccessibleImage
Message: The image 'MY-ACR.azurecr.io/MY-IMAGE:latest' in container group 'INSTANCE-GROUP' is not accessible. Please check the image and registry credential.
我已创建Azure应用并配置AZURE_CLIENT_ID、AZURE_TENANT_ID、AZURE_CLIENT_SECRET环境变量,该应用在目标资源组拥有Contributor和AcrPull角色,为何仍无法获取访问权限?
原Python代码:
from azure.identity import DefaultAzureCredential from azure.mgmt.containerinstance import ContainerInstanceManagementClient from azure.mgmt.containerinstance.models import ( ContainerGroup, Container, EnvironmentVariable, ResourceRequests, ResourceRequirements, ) # Replace these values with your own subscription_id = "..." resource_group_name = "..." aci_name = "..." acr_name = "..." acr_username = "..." acr_password = "..." image = "MY-ACR.azurecr.io/MY-IMAGE:latest" cpu_cores = 1.0 memory_in_gb = 1.5 location = "North Europe" # Create the credential object credential = DefaultAzureCredential() # Create the ACI management client client = ContainerInstanceManagementClient(credential, subscription_id) # Create the container group definition env_vars = [ EnvironmentVariable(name="KEY", value="VAL"), ] # set memory and cpu container_resource_requests = ResourceRequests(memory_in_gb=memory_in_gb, cpu=cpu_cores) container_resource_requirements = ResourceRequirements( requests=container_resource_requests ) container = Container( name=aci_name, image=image, resources=container_resource_requirements, environment_variables=env_vars, ) # Create the container group container_group = ContainerGroup( location=location, containers=[container], os_type="Linux", restart_policy="Always", ) client.container_groups.begin_create_or_update( resource_group_name, aci_name, container_group )
问题原因
你的Python代码未配置ACR的访问凭证。Azure CLI命令显式指定了--registry-username和--registry-password参数,但Python SDK的ContainerGroup定义中缺少容器注册表的身份验证信息,导致ACI服务无法拉取ACR中的镜像。
另外,虽然应用拥有AcrPull角色,但ACI默认不会自动复用管理客户端的凭据拉取镜像,仍需在容器组配置中明确指定注册表凭证,或启用ACR与ACI的托管身份集成。
修正方案
方案1:显式添加ACR凭证到容器组
在创建ContainerGroup时,添加image_registry_credentials参数,传入ACR的用户名和密码:
from azure.mgmt.containerinstance.models import ImageRegistryCredential # 保留原代码中其他部分不变 # 创建容器组时添加镜像注册表凭证 container_group = ContainerGroup( location=location, containers=[container], os_type="Linux", restart_policy="Always", # 添加ACR访问凭证 image_registry_credentials=[ ImageRegistryCredential( server=f"{acr_name}.azurecr.io", username=acr_username, password=acr_password ) ] ) client.container_groups.begin_create_or_update( resource_group_name, aci_name, container_group )
方案2:使用托管身份访问ACR(推荐)
若不想硬编码凭证,可利用已配置AcrPull角色的应用托管身份,在容器组中启用托管身份并关联ACR:
from azure.mgmt.containerinstance.models import ManagedServiceIdentity, ManagedServiceIdentityType # 保留原代码中其他部分不变 # 创建容器组时启用托管身份 container_group = ContainerGroup( location=location, containers=[container], os_type="Linux", restart_policy="Always", # 启用系统分配托管身份(也可选择用户分配身份,需指定user_assigned_identities) identity=ManagedServiceIdentity( type=ManagedServiceIdentityType.SYSTEM_ASSIGNED ) ) client.container_groups.begin_create_or_update( resource_group_name, aci_name, container_group )
注意:使用系统分配身份时,需为ACI生成的系统身份分配
AcrPull角色到目标ACR;若使用用户分配身份,确保该身份已拥有AcrPull权限。
内容的提问来源于stack exchange,提问作者Bertil Johannes Ipsen

