为何通过Bicep创建的AKS集群无法从ACR拉取镜像?
问题分析与解决方案
你遇到的核心问题是:仅给AKS集群的系统身份分配ACR权限是不够的——节点上拉取镜像的kubelet组件使用的是专属的kubelet身份(默认是AKS自动创建的用户分配身份),而非集群系统身份,因此该身份没有ACR访问权限,导致ImagePullBackOff和401未授权错误。而az aks create --attach-acr会自动为kubelet身份分配ACR权限,所以部署流程正常。
下面提供三种可行的解决方案:
方案一:让kubelet复用集群系统身份
修改AKS资源定义,添加useSystemIdentityForKubelet: true配置,让kubelet使用集群的系统身份,你已有的ACR角色分配就能直接生效:
param clusterName string = 'MyTestCluster' param location string = resourceGroup().location param acrName string = 'mytestacr' param sshRSAPublicKey string // 补充缺失的dnsPrefix参数 param dnsPrefix string = clusterName resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-10-01' = { name: clusterName location: location identity: { type: 'SystemAssigned' } sku: { name: 'Base' tier: 'Standard' } properties: { dnsPrefix: dnsPrefix // 新增:让kubelet使用集群系统身份 useSystemIdentityForKubelet: true agentPoolProfiles: [ { name: 'agentpool' osDiskSizeGB: 30 count: 1 vmSize: 'standard_d2s_v3' osType: 'Linux' mode: 'System' } ] linuxProfile: { adminUsername: 'azureuser' ssh: { publicKeys: [ { keyData: sshRSAPublicKey } ] } } networkProfile: { loadBalancerSku: 'standard' networkPlugin: 'azure' networkPluginMode: 'overlay' networkDataplane: 'azure' networkPolicy: 'azure' } } } resource acr 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = { name: acrName scope: resourceGroup() } resource acrRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = { name: guid(acr.id, aksCluster.id, '7f951dda-4ed3-4680-a7ca-43fe172d538d') scope: acr properties: { roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') // ACR Pull角色ID principalId: aksCluster.identity.principalId principalType: 'ServicePrincipal' } }
方案二:为kubelet身份单独分配ACR权限
在现有角色分配的基础上,新增针对kubelet身份的ACR Pull权限分配:
// 原有AKS、ACR资源定义保持不变 // 新增:为kubelet身份分配ACR Pull权限 resource acrKubeletRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = { name: guid(acr.id, aksCluster.properties.kubeletIdentity.principalId, '7f951dda-4ed3-4680-a7ca-43fe172d538d') scope: acr properties: { roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') // ACR Pull角色ID principalId: aksCluster.properties.kubeletIdentity.principalId principalType: 'ServicePrincipal' } }
方案三:通过attachedACRs自动关联ACR
在AKS资源的properties中添加attachedACRs配置,让AKS自动完成ACR权限分配(和az aks create --attach-acr的行为完全一致):
param clusterName string = 'MyTestCluster' param location string = resourceGroup().location param acrName string = 'mytestacr' param sshRSAPublicKey string param dnsPrefix string = clusterName resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-10-01' = { name: clusterName location: location identity: { type: 'SystemAssigned' } sku: { name: 'Base' tier: 'Standard' } properties: { dnsPrefix: dnsPrefix // 新增:自动关联ACR,AKS会处理所有权限分配 attachedACRs: [ acr.id ] agentPoolProfiles: [ { name: 'agentpool' osDiskSizeGB: 30 count: 1 vmSize: 'standard_d2s_v3' osType: 'Linux' mode: 'System' } ] linuxProfile: { adminUsername: 'azureuser' ssh: { publicKeys: [ { keyData: sshRSAPublicKey } ] } } networkProfile: { loadBalancerSku: 'standard' networkPlugin: 'azure' networkPluginMode: 'overlay' networkDataplane: 'azure' networkPolicy: 'azure' } } } resource acr 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = { name: acrName scope: resourceGroup() }
额外注意
你原Bicep代码中缺失dnsPrefix参数的定义,需要补充param dnsPrefix string = clusterName(或自定义值),否则部署会报错。
内容的提问来源于stack exchange,提问作者MorayM
相关产品推荐
相关产品推荐

