通过 ARM/Bicep 模板将网络贡献者角色分配给 AKS 集群的正确方法是什么?

通过 ARM/Bicep 模板将网络贡献者角色分配给 AKS 集群的正确方法是什么?

我正在尝试使用 Bicep/ARM 为我的 AKS 服务器配置负载均衡器。我在 kubernetes 中使用 NGinx Ingress Controller,它似乎可以工作,但当我第一次启动时,我遇到了一个错误。

我主要想知道 Azure 文档中此步骤的等效 ARM 或 Bicep 模板是什么?

https://docs.microsoft.com/en-us/azure/aks/static-ip#create-a-service-using-the-static-ip-address

az role assignment create \
    --assignee <Client ID> \
    --role "Network Contributor" \
    --scope /subscriptions/<subscription id>/resourceGroups/<resource group name>

我正在使用 Bicep 并创建了我的 AKS 服务器,例如:

resource ExampleKubernetes 'Microsoft.ContainerService/managedClusters@2021-07-01' = {
  // ...
}

然后我向 kubelet 身份添加角色分配,如下所示:

var NetworkContibutor = '4d97b98b-1d4f-4787-a291-c67834d212e7'
resource AssignNetworkContributorToKubelet 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = {
  name: guid(resourceGroup().id, ExampleKubernetes.id, NetworkContibutor)
  dependsOn: [
    ExampleKubernetes
  ]
  properties: {
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', NetworkContibutor)
    principalType: 'ServicePrincipal'
    principalId: ExampleKubernetes.properties.identityProfile.kubeletidentity.objectId
  }
}

这似乎有效,我可以在仪表板中看到分配给托管主体的角色......但 kubernetes 中的服务似乎仍然因权限问题而失败:

  Error syncing load balancer: failed to ensure load balancer: Retriable: false,
  RetryAfter: 0s, HTTPStatusCode: 403, RawError: Retriable: false, RetryAfter:
  0s, HTTPStatusCode: 403, RawError:
  {"error":{"code":"AuthorizationFailed","message":"The client
  '<some guid A>' with object id
  '<some buid A>' does not have authorization to perform
  action 'Microsoft.Network/publicIPAddresses/read' over scope
  '/subscriptions/<subid>/resourceGroups/example/providers/Microsoft.Network/publicIPAddresses/example'
  or the scope is invalid. If access was recently granted, please refresh your
  credentials."}}

奇怪的是,后来在某个时候它似乎奇迹般地起作用了。那个错误显示“可重试错误”,看起来服务确实没有重试,但随后将 NGinx 部署到 kubernetes 会然后使其重试并突然开始工作。

似乎错误消息告诉我角色传播存在一些非确定性的延迟......所以我的问题是:

  • 对吗?事实上这只是一个延迟,我的代码基本上是正确的吗?
  • 我使用的 principalId 是否正确?或者这实际上是不必要的?
  • 有没有办法强制传播这些角色更新?如果需要,我可以在两者之间执行 CLI 步骤。我如何等到权限准备好后再安装连接到 LB 的入口控制器?

答案1

我不确定为什么之前的答案被认为是正确的。你在这里使用了 kubelet 身份。这用于进行身份验证Azure 容器注册表,但对于你的情况,你必须使用 Cluster (Control Plane) Identity,而我找不到分配系统管理身份的方法。我认为目前唯一的办法就是自带。

1 添加托管身份创建到你的 ARM 模板:

resource managedidentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: aksManIdentityName
  location: location
}

2 更新 AKS Identity 属性:

  identity:{
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${managedidentity.id}': {}
    }
  }

3 授予网络贡献者权限

resource RBAC_Network_Contributor 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  scope: resourceGroup()
  name: guid(resourceGroup().id, '${aksClusterName}-NetworkContributor') 
  properties: {
    roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')
    principalId: managedidentity.properties.principalId
    principalType: 'ServicePrincipal'
  }
}

答案2

你的问题(虽然不是直接的)得到了回答这里

您所描述的行为已在本节由于 Azure 资源管理器有时会缓存配置和数据以提高性能,因此在分配角色或删除角色分配时,更改有时可能需要长达 30 分钟才能生效。

使用 Azure CLI,可以通过以下方式强制刷新角色分配更改:退出和登录

相关内容