4. AKS身份与权限

在AKS中,“身份”不是一个单一概念,而是贯穿控制平面、节点、Pod与Azure资源四层的一条信任链。理解这条链的关键,是先区分两类主体:人(运维、开发者)与工作负载(Pod中的应用)。前者通过Microsoft Entra ID登录,再由Azure RBAC for Kubernetes或Kubernetes原生RBAC决定能对集群做什么;后者通过托管标识或工作负载标识获取令牌,去访问Key Vault、存储、数据库等Azure资源。把这两条路径混在一起,是权限配置出错的最常见原因。

一、托管标识:节点与集群自身的Azure身份

AKS集群在创建时必须绑定一个身份,用于控制平面操作Azure资源,例如创建负载均衡器、附加磁盘、拉取ACR镜像。这个身份有两种形态:系统分配的托管标识(由AKS自动创建,生命周期与集群绑定)和用户分配的托管标识(提前创建,可被多个资源复用,权限预配置更可控)。生产环境通常推荐用户分配的托管标识,因为它允许在集群创建前就把所需角色授予到位,避免创建过程中因权限不足而失败。

节点池中的每个节点也拥有自己的托管标识(kubelet identity),它负责从ACR拉取镜像、挂载Azure磁盘、写入监控日志。需要特别注意:kubelet identity与集群控制平面身份是两个不同的主体,授予权限时不要混淆。例如要让节点从ACR拉镜像,应把 AcrPull 角色授予kubelet identity,而不是控制平面身份。

# 查看集群身份与kubelet身份
az aks show -g rg-aks -n aks-prod \
  --query "{clusterIdentity:identity, kubeletIdentity:identityProfile.kubeletidentity}"

# 授予kubelet从ACR拉取镜像的权限
az role assignment create \
  --assignee <kubelet-principalId> \
  --role AcrPull \
  --scope /subscriptions/<sub>/resourceGroups/rg-acr/providers/Microsoft.ContainerRegistry/registries/acrprod

二、工作负载标识:Pod访问Azure资源的推荐方式

Pod里的应用要访问Key Vault读取密钥,传统做法是把连接字符串或服务主体密钥塞进Secret,存在泄露与轮换困难的问题。工作负载标识(Workload Identity)通过联邦身份凭据把Kubernetes ServiceAccount与Microsoft Entra ID中的应用注册或用户分配托管标识绑定,Pod用投影的ServiceAccount令牌向Entra ID换取访问令牌,全程无需在集群中保存长期密钥。

启用工作负载标识需要三步:在集群上开启 --enable-oidc-issuer 与 --enable-workload-identity;创建用户分配的托管标识并授予目标资源角色;建立联邦凭据,把OIDC颁发者URL、命名空间、ServiceAccount名称三者绑定。之后在Pod的ServiceAccount上标注 azure.workload.identity/client-id,并在Pod模板上加标签 azure.workload.identity/use: "true",SDK即可自动完成令牌交换。

# 建立联邦凭据:把K8s ServiceAccount映射到托管标识
az identity federated-credential create \
  --name fed-aks-demo \
  --identity-name id-demo \
  --resource-group rg-aks \
  --issuer $(az aks show -g rg-aks -n aks-prod --query oidcIssuerProfile.issuerUrl -o tsv) \
  --subject system:serviceaccount:demo:sa-demo \
  --audience api://AzureADTokenExchange

这里的 subject 必须与命名空间和ServiceAccount完全一致,任何拼写差异都会导致令牌交换失败,表现为Pod日志中的 AADSTS70021 或 no matching federated identity record。排查时先确认OIDC颁发者URL可公开访问,再核对subject字符串。

三、Azure RBAC for Kubernetes与Entra ID集成

AKS支持两种授权模式:Kubernetes原生RBAC(用RoleBinding绑定Entra ID用户或组)和Azure RBAC for Kubernetes(用Azure角色分配控制Kubernetes资源访问)。启用Azure RBAC后,Entra ID用户或组通过 az aks get-credentials 获取kubeconfig,访问请求由AKS的授权Webhook转发给Azure RBAC判定,角色如 Azure Kubernetes Service RBAC Reader、Writer、Cluster Admin 分别对应不同范围的Kubernetes操作。

两种模式的核心差异在于管理面:Azure RBAC统一在Azure门户和CLI中审计,适合已有Azure权限体系的团队;Kubernetes原生RBAC更贴近Kubernetes生态,适合需要精细到自定义资源(CRD)的场景。二者可以共存,但同一主体可能被双重授权,建议明确主授权路径,避免权限放大。

AKS 身份与权限信任链 运维 / 开发者 Microsoft Entra ID 登录 授权判定 Azure RBAC for K8s / 原生 RBAC Kubernetes API Server kubectl / 客户端请求 Pod 工作负载 ServiceAccount 令牌 (投影卷) Entra ID 令牌交换 联邦身份凭据校验 OIDC Issuer + Subject Azure 资源 Key Vault / Storage / SQL 按托管标识角色授权 AKS 控制平面 用户/系统托管标识 管理 LB、磁盘、网络 节点池 kubelet 标识 拉取 ACR 镜像 挂载 Azure 磁盘 Azure 平台服务 ACR / 负载均衡 / 监控 按集群身份角色授权 人 → 集群(授权) 工作负载 → Azure 资源(令牌交换) 集群/节点 → Azure 平台(托管标识) 关键区分: 控制平面身份 ≠ kubelet 身份 ≠ 工作负载标识,三者授权对象与作用范围互不相同。 工作负载标识依赖 OIDC Issuer + 命名空间 + ServiceAccount 三元组精确匹配,任一不符即令牌交换失败。

四、实践中的判断与排障

当Pod访问Key Vault报403时,按以下顺序判断:先确认Pod是否带 azure.workload.identity/use: "true" 标签;再确认ServiceAccount是否标注了正确的client-id;然后检查联邦凭据的subject是否与命名空间、ServiceAccount完全一致;最后确认托管标识在Key Vault上是否拥有 Key Vault Secrets User 角色。这四步覆盖了绝大多数工作负载标识故障。

当用户执行kubectl报 Forbidden 时,先确认kubeconfig中的用户是否属于被授权的Entra ID组,再检查Azure角色分配的作用域是否覆盖目标命名空间。Azure RBAC for Kubernetes的角色分配作用域可以是整个集群、某个命名空间甚至某个资源,作用域越窄权限越精确。若同时启用了原生RBAC,还需检查RoleBinding是否与Azure角色分配冲突。

建议为每个环境(dev/staging/prod)使用独立的用户分配托管标识和联邦凭据,避免跨环境权限串用。工作负载标识的联邦凭据subject中命名空间应体现环境,例如 system:serviceaccount:prod:sa-app。
不要在Pod中挂载服务主体密钥或存储连接字符串来替代工作负载标识。长期密钥一旦泄露,轮换成本高且难以审计。工作负载标识的令牌是短期、自动轮换的,应作为访问Azure资源的默认方式。

总结来看,AKS身份体系可以归纳为三条独立又协作的信任链:人经Entra ID登录后由Azure RBAC或原生RBAC授权访问集群;Pod经工作负载标识联邦换取令牌访问Azure资源;集群与节点经托管标识管理Azure平台资源。把这三条链的主体、凭据类型、授权位置和排障入口分别记清,就能在配置权限时快速定位该改哪里、该查什么。