You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Batch用户分配托管身份创建池遇权限及网关超时问题

问题:Azure Batch池用户分配托管身份创建失败(权限及网关超时)

我们正将Python解决方案从服务主体(SPN)迁移至托管身份(MI)认证,已完成代码适配,但创建带用户分配托管身份的Azure Batch池时,先遇到权限错误,添加Managed Identity Operator角色后又出现网关超时错误。

原代码

import os
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
from azure.mgmt.batch import BatchManagementClient
from azure.mgmt.batch.models import (
    Pool, CloudServiceConfiguration, PoolIdentityType, FixedScaleSettings,
    ContainerRegistry, ContainerConfiguration, PoolAllocationMode, ComputeNodeIdentityReference,
    VirtualMachineConfiguration, BatchPoolIdentity, UserAssignedIdentities, DeploymentConfiguration,
    ScaleSettings, NetworkConfiguration
)

app_name      = 'BatchTest' #The name of the Batch Application to load onto the pool.
app_version   = 0.0.1 #The version of the Batch Application to load. If omitted the default version will be loaded.
registry_name = 'sampleregistry.azurecr.io'
image_name    = 'test-image'
image_version = 'latest'
sku_to_use = 'batch.node.ubuntu 20.04' # Marketplace image sku
image_ref_to_use = {'additional_properties': {}, 'publisher': 'microsoft-azure-batch', 'offer': 'ubuntu-server-container', 'sku': '20-04-lts', 'version': 'latest', 'virtual_machine_image_id': None}
client_id = "xxx-xxx-xx-xx-xx"
subscription_id = "yyyy-yyy-yyy-yyy-yyy"
resource_group_name = "TestRG"
user_assigned_identity_name = "testUMI"
resource_id = f"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{user_assigned_identity_name}"
pool_vm_size = "STANDARD_DS4_V2"
pool_vm_count = 4
pool_vm_maxcount = 1

if app_version is None:
    version_str = " with the Default {} Version".format(app_name)
else:
    version_str = "with {} Version {}".format(app_name, app_version)

# 错误:镜像名称拼接重复了registry的域名
image_name = registry_name + image_name + image_version

# 错误:未导入batchmodels就使用
application_references = [batchmodels.ApplicationPackageReference(application_id = app_name, version = app_version)]

network_config = None

# Authenticate using DefaultAzureCredential
credentials = ManagedIdentityCredential(client_id = f"{client_id}")
batch_client = BatchManagementClient(credential=credentials,subscription_id=f"{subscription_id}")

# Define the container registry (with username and password if needed)
container_registry = ContainerRegistry(
    registry_server=f"{registry_name}",
    user_name=None,
    password=None,
    identity_reference = ComputeNodeIdentityReference(resource_id = resource_id))

# Define the container configuration
# 错误:镜像地址重复了registry域名(registry_name已经包含.azurecr.io,又加了一次)
container_config = ContainerConfiguration(
    type="dockerCompatible",
    container_registries=[container_registry],
    container_image_names=[f"{registry_name}.azurecr.io/{image_name}:{image_version}"])    

vm_config = VirtualMachineConfiguration(
    image_reference=image_ref_to_use,
    node_agent_sku_id=sku_to_use,
    container_configuration=container_config)    

# 错误:user_assigned_identities格式错误,max_tasks_per_node未定义
pool = Pool(
    identity=BatchPoolIdentity(
        type=PoolIdentityType.USER_ASSIGNED,
        user_assigned_identities={f"{resource_id}:UserAssignedIdentities()"}
    ), 
    display_name='managedidentitytest',
    vm_size=pool_vm_size,
    deployment_configuration=DeploymentConfiguration(
    virtual_machine_configuration=vm_config,
    ),
    scale_settings=ScaleSettings(
        fixed_scale=FixedScaleSettings(
            target_dedicated_nodes=pool_vm_count,
            target_low_priority_nodes=0)
    ),
    task_slots_per_node=max_tasks_per_node
)

# 错误:pool_id未定义
batch_client.pool.create(
    resource_group_name="TestRG",
    account_name="Teststsystemdev",
    pool_name=pool_id,
    parameters=pool
)

遇到的错误

1. 权限错误

Code: LinkedAuthorizationFailed
Message: The client "xxx-xxx-xx-xx-xx" with object id "xxx-xxx-xx-xx-xx" has permission to perform action 'Microsoft.Batch/batchAccounts/pools/write' on scope '/subscriptions/yyyy-yyy-yyy-yyy-yyy/resourceGroups/TestRG/providers/Microsoft.Batch/batchAccounts/Teststsystemdev/pools/ForecastCluster'; however, it does not have permission to perform action(s) 'Microsoft.ManagedIdentity/userAssignedIdentities/assign/action' on the linked scope(s) '/subscriptions/yyyy-yyy-yyy-yyy-yyy/resourcegroups/ProdRG/providers/microsoft.managedidentity/userassignedidentities/testUMI' (respectively) or the linked scope(s) are invalid.

2. 网关超时错误

Encountered unexpected exception of type <class 'azure.core.exceptions.HttpResponseError'> when trying to create a pool. Exception details: (GatewayTimeout) The gateway did not receive a response from 'Microsoft.Batch' within the specified time period.
Code: GatewayTimeout
Message: The gateway did not receive a response from 'Microsoft.Batch' within the specified time period.

解决方案

1. 修复代码中的关键错误

(1)修正用户分配身份的格式

BatchPoolIdentity的user_assigned_identities参数是字典类型,键为用户分配MI的资源ID,值为空对象或UserAssignedIdentities实例,原代码的字符串拼接格式完全错误:

# 错误写法
user_assigned_identities={f"{resource_id}:UserAssignedIdentities()"}

# 正确写法
user_assigned_identities={resource_id: {}}

(2)修正镜像地址拼接错误

原代码中registry_name已经包含.azurecr.io,无需重复添加,同时镜像名称拼接逻辑错误:

# 错误写法
image_name = registry_name + image_name + image_version
container_image_names=[f"{registry_name}.azurecr.io/{image_name}:{image_version}"]

# 正确写法
full_image_name = f"{registry_name}/{image_name}:{image_version}"

(3)补全未定义的变量

添加max_tasks_per_node和pool_id的定义:

max_tasks_per_node = 1  # 根据需求调整
pool_id = "ForecastCluster"  # 对应错误信息中的池名称

(4)修正应用包引用的导入问题

原代码中使用batchmodels但未导入,直接使用azure.mgmt.batch.models中的类:

from azure.mgmt.batch.models import ApplicationPackageReference
# ...
application_references = [ApplicationPackageReference(application_id=app_name, version=app_version)]

2. 修正权限配置

之前的LinkedAuthorizationFailed错误是因为执行代码的托管身份(即ManagedIdentityCredential对应的MI)没有权限分配目标用户托管身份,需:

  • 在用户分配MI的资源范围上,给执行代码的MI分配Managed Identity Operator角色(或自定义角色包含Microsoft.ManagedIdentity/userAssignedIdentities/assign/action权限)
  • 确保用户分配MI拥有Azure容器注册表(ACR)的ACR Pull角色,用于拉取容器镜像

3. 解决网关超时问题

网关超时通常是Batch服务处理请求超时导致,可尝试:

  • 先减少目标节点数(比如target_dedicated_nodes=1),测试基础配置是否能成功创建
  • 增加客户端请求超时时间,创建BatchManagementClient时配置超时:
    from azure.core.pipeline.transport import RequestsTransport
    
    transport = RequestsTransport(timeout=120)  # 设置120秒超时
    batch_client = BatchManagementClient(
        credential=credentials,
        subscription_id=subscription_id,
        transport=transport
    )
    
  • 确保Batch账户、用户分配MI、ACR处于同一Azure区域,减少跨区域延迟
  • 检查容器镜像大小,过大的镜像会延长节点初始化时间,导致超时

修正后的完整代码

import os
from azure.identity import ManagedIdentityCredential
from azure.mgmt.batch import BatchManagementClient
from azure.mgmt.batch.models import (
    Pool, PoolIdentityType, FixedScaleSettings,
    ContainerRegistry, ContainerConfiguration, ComputeNodeIdentityReference,
    VirtualMachineConfiguration, BatchPoolIdentity, DeploymentConfiguration,
    ScaleSettings, ApplicationPackageReference
)

# 配置参数
app_name = 'BatchTest'
app_version = '0.0.1'
registry_name = 'sampleregistry.azurecr.io'
image_name = 'test-image'
image_version = 'latest'
sku_to_use = 'batch.node.ubuntu 20.04'
image_ref_to_use = {
    'publisher': 'microsoft-azure-batch',
    'offer': 'ubuntu-server-container',
    'sku': '20-04-lts',
    'version': 'latest'
}
client_id = "xxx-xxx-xx-xx-xx"
subscription_id = "yyyy-yyy-yyy-yyy-yyy"
resource_group_name = "TestRG"
user_assigned_identity_name = "testUMI"
resource_id = f"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{user_assigned_identity_name}"
pool_vm_size = "STANDARD_DS4_V2"
pool_vm_count = 1  # 先测试1个节点
max_tasks_per_node = 1
pool_id = "ForecastCluster"
batch_account_name = "Teststsystemdev"

# 认证
credentials = ManagedIdentityCredential(client_id=client_id)
batch_client = BatchManagementClient(credential=credentials, subscription_id=subscription_id)

# 容器注册表配置(使用用户分配身份认证)
container_registry = ContainerRegistry(
    registry_server=registry_name,
    identity_reference=ComputeNodeIdentityReference(resource_id=resource_id)
)

# 容器配置
full_image_name = f"{registry_name}/{image_name}:{image_version}"
container_config = ContainerConfiguration(
    type="dockerCompatible",
    container_registries=[container_registry],
    container_image_names=[full_image_name]
)

# VM配置
vm_config = VirtualMachineConfiguration(
    image_reference=image_ref_to_use,
    node_agent_sku_id=sku_to_use,
    container_configuration=container_config
)

# 池配置(修正用户分配身份格式)
pool = Pool(
    identity=BatchPoolIdentity(
        type=PoolIdentityType.USER_ASSIGNED,
        user_assigned_identities={resource_id: {}}
    ),
    display_name='managedidentitytest',
    vm_size=pool_vm_size,
    deployment_configuration=DeploymentConfiguration(
        virtual_machine_configuration=vm_config
    ),
    scale_settings=ScaleSettings(
        fixed_scale=FixedScaleSettings(
            target_dedicated_nodes=pool_vm_count,
            target_low_priority_nodes=0
        )
    ),
    task_slots_per_node=max_tasks_per_node
)

# 创建池
batch_client.pool.create(
    resource_group_name=resource_group_name,
    account_name=batch_account_name,
    pool_name=pool_id,
    parameters=pool
)

内容的提问来源于stack exchange,提问作者RSK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 10:27:33