在 AKS 中将 Kubernetes RBAC 与 Microsoft Entra ID 配合使用

可将 Azure Kubernetes Service (AKS) 配置为使用 Microsoft Entra ID 进行用户身份验证。 在此配置中,你使用 Microsoft Entra 身份验证令牌登录到 AKS 群集。 进行身份验证后,可以使用内置的 Kubernetes 基于角色的访问控制(RBAC)根据用户的标识或组成员身份管理对命名空间和群集资源的访问权限。

本文介绍如何:

  • 根据 Microsoft Entra 组成员身份使用 AKS 群集中的 Kubernetes RBAC 来控制访问权限。

  • 在 Microsoft Entra ID 中创建示例组和用户。

  • 在 AKS 群集中创建角色和 RoleBindings,授予相应的权限,例如创建和查看资源。

先决条件

  • 你有一个已启用 Microsoft Entra 集成的现有 AKS 群集。 如果需要具有此配置的 AKS 群集,请参阅将 Microsoft Entra ID 与 AKS 集成

  • 默认情况下,在 AKS 群集创建期间启用 Kubernetes RBAC。 若要使用 Microsoft Entra 集成和 Kubernetes RBAC 升级现有群集,请参阅 在现有 AKS 群集上启用Microsoft Entra 集成

  • 确保安装并配置了 Azure CLI 2.0.61 或更高版本。 若要查找版本,请运行 az --version。 若要安装或升级,请参阅安装 Azure CLI

  • 如果使用 Terraform,请安装 Terraform 2.99.0 或更高版本。

使用 Azure 门户或 Azure CLI 验证是否启用了 Microsoft Entra 与 Kubernetes RBAC 的集成。

若要使用 Azure 门户验证,请执行以下操作:

  1. 登录到 Azure 门户 并导航到 AKS 群集资源。
  2. 在服务菜单中的“设置”下,选择“安全配置”。
  3. 在“身份验证和授权”部分下,验证是否选择了“使用 Kubernetes RBAC 的 Microsoft Entra 身份验证”选项

在 Microsoft Entra ID 中创建组

本部分介绍如何创建两个用户角色,以显示 Kubernetes RBAC 和 Microsoft Entra ID 控制访问群集资源的方式。 以下两个示例角色包括:

  • 应用程序开发人员

    • 属于 appdev 组的名为 aksdev 的用户。
  • 站点可靠性工程师 (SRE)

    • 属于 opssre 组的名为 akssre 的用户。

在生产环境中,可以使用 Microsoft Entra 租户中的现有用户和组。

  1. 首先,使用 az aks show 命令获取 AKS 群集的资源 ID。 然后,将该资源 ID 分配到名为 AKS_ID 的变量,以便可以在其他命令中引用它。

    AKS_ID=$(az aks show \
        --resource-group myResourceGroup \
        --name myAKSCluster \
        --query id -o tsv)
    
  2. 使用 az ad group create 命令在 Microsoft Entra ID 中为应用程序开发人员创建第一个示例组。 以下示例创建名为 appdev 的组:

    APPDEV_ID=$(az ad group create --display-name appdev --mail-nickname appdev --query id -o tsv)
    
  3. 使用 命令为 appdev 组创建 Azure 角色分配。 此分配可为该组的任何成员授予“Azure Kubernetes 服务群集用户”角色,因此可让其使用 kubectl 与 AKS 群集交互。

    az role assignment create \
      --assignee $APPDEV_ID \
      --role "Azure Kubernetes Service Cluster User Role" \
      --scope $AKS_ID
    

    提示

    如果出现类似于 Principal 35bfec9328bd4d8d9b54dea6dac57b82 doesn't exist in the directory a5443dcd-cd0e-494d-a387-3039b419f0d5. 的错误,请等待几秒,让 Microsoft Entra 组对象 ID 传播到整个目录,然后重试 az role assignment create 命令。

在 Microsoft Entra ID 中创建用户

为应用程序开发人员和 SRE 创建示例Microsoft Entra ID 组后,下一步是创建两个相应的用户帐户。 这些用户用于登录到 AKS 群集,并验证本文后面所述的 Kubernetes RBAC 集成。

在开始之前,必须为应用程序开发人员设置用户主体名称(UPN)和密码。 UPN 必须包含租户的已验证域名。 例如,应用程序开发者用户aksdev@contoso.com。 为了识别或设置租户中的已验证域名,请参阅 管理 Microsoft Entra ID 中的自定义域名

以下命令提示你输入 UPN 并将其设置为“AAD_DEV_UPN”,以便在以后的命令中使用:

echo "Please enter the UPN for application developers: " && read AAD_DEV_UPN

以下命令提示你输入密码并将其设置为“AAD_DEV_PW”,以便在以后的命令中使用:

echo "Please enter the secure password for application developers: " && read AAD_DEV_PW

创建用户帐户

  1. 使用 az ad user create 命令在 Microsoft Entra ID 中创建第一个用户帐户。 以下示例使用AAD_DEV_UPNAAD_DEV_PW中的值创建显示名称 AKS Dev、UPN 和安全密码的用户:

    AKSDEV_ID=$(az ad user create \
      --display-name "AKS Dev" \
      --user-principal-name $AAD_DEV_UPN \
      --password $AAD_DEV_PW \
      --query id -o tsv)
    
  2. 使用命令将用户添加到在上一节中创建的az ad group member add组。

    az ad group member add --group appdev --member-id $AKSDEV_ID
    

创建 AKS 群集资源

我们创建了 Microsoft Entra 组、用户和 Azure 角色分配。 现在,将 AKS 群集配置为允许这些不同的组访问特定资源。

  1. 使用 az aks get-credentials 命令获取群集管理员凭据。 在以下某个部分中,你将获得普通用户群集凭据,以查看 Microsoft Entra 身份验证流的运作方式。

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --admin
    
  2. 使用 kubectl create namespace 命令在 AKS 群集中创建一个命名空间。 以下示例创建名为 dev 的命名空间:

    kubectl create namespace dev
    

    注意

    在 Kubernetes 中,角色定义要授予的权限,角色绑定将这些权限应用到所需的用户或组。 这些分配可应用于特定命名空间或整个群集。 有关详细信息,请参阅使用 Kubernetes RBAC 授权

    如果授予 Kubernetes RBAC 绑定的用户位于同一Microsoft Entra 租户中,请根据 UPN 分配权限。 如果该用户位于不同的 Microsoft Entra 租户中,请查询并改用 objectId 属性。

  3. 为 dev 命名空间创建一个 Role,以便授予对该命名空间的完全权限。 在生产环境中,可为不同的用户或组指定更精细的权限。 创建名为 role-dev-namespace.yaml 的文件并粘贴以下 YAML 清单:

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: dev-user-full-access
      namespace: dev
    rules:
    - apiGroups: ["", "extensions", "apps"]
      resources: ["*"]
      verbs: ["*"]
    - apiGroups: ["batch"]
      resources:
      - jobs
      - cronjobs
      verbs: ["*"]
    
  4. 使用 kubectl apply 命令创建 Role,并指定 YAML 清单的文件名。

    kubectl apply -f role-dev-namespace.yaml
    
  5. 使用 az ad group show 命令获取 appdev 组的资源 ID。 此组将设置为在下一步骤中创建的角色绑定的使用者。

    az ad group show --group appdev --query id -o tsv
    
  6. 为 appdev 组创建 RoleBinding,以使用前面创建的 Role 来访问命名空间。 创建名为 rolebinding-dev-namespace.yaml 的文件并粘贴以下 YAML 清单。 在最后一行中,将“groupObjectId”替换为上一命令的组对象 ID 输出。

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: dev-user-access
      namespace: dev
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: dev-user-full-access
    subjects:
    - kind: Group
      namespace: dev
      name: groupObjectId
    

    提示

    如果要为单个用户创建 RoleBinding,请指定 类型:用户 并将 groupObjectId 替换为上一示例中的 UPN。

  7. 使用 kubectl apply 命令创建角色绑定,并指定 YAML 清单的文件名:

    kubectl apply -f rolebinding-dev-namespace.yaml
    

使用 Microsoft Entra 标识访问 AKS 群集资源

现在,测试在 AKS 群集中创建和管理资源时的预期权限是否有效。 在这些示例中,你将在用户指定的命名空间中调度和查看 Pod,并尝试在指定的命名空间之外调度和查看 Pod。

  1. 使用 命令重置 kubeconfig 上下文。 在上一部分,你已使用群集管理员凭据设置了上下文。 管理员用户会绕过 Microsoft Entra 登录提示。 如果没有 --admin 参数,应用的用户上下文将要求使用 Microsoft Entra ID 对所有请求进行身份验证。

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --overwrite-existing
    
  2. kubectl run命名空间中,使用命令调度一个基本的 NGINX Pod:

    kubectl run nginx-dev --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace dev
    
  3. 在登录提示符下输入 appdev 组帐户的凭据(输入 自己的 凭据)。 成功登录后,帐户令牌将会缓存,供将来的 kubectl 命令使用。 NGINX 已成功调度,如以下示例输出所示:

    $ kubectl run nginx-dev --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace dev
    
    To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code B24ZD6FP8 to authenticate.
    
    pod/nginx-dev created
    
  4. 使用kubectl get pods命令查看dev命名空间中的Pod:

    kubectl get pods --namespace dev
    
  5. 确保 NGINX pod 的状态为“正在运行”。 输出如下所示:

    $ kubectl get pods --namespace dev
    
    NAME        READY   STATUS    RESTARTS   AGE
    nginx-dev   1/1     Running   0          4m
    

测试对 AKS 群集资源的 SRE 访问

若要确认Microsoft Entra 组成员身份和 Kubernetes RBAC 在不同用户和组之间正常工作,请在以 akssre 用户身份登录时尝试上述命令。

  1. 使用 命令重置 kubeconfig 上下文,以清除前面为 aksdev 用户缓存的身份验证令牌。

    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --overwrite-existing
    
  2. 在分配的 SRE 命名空间中计划和查看 Pod。 出现提示时,请使用 opssre 组帐户凭据登录(输入 自己的 凭据)。

    kubectl run nginx-sre --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace sre
    kubectl get pods --namespace sre
    

    如以下示例输出中所示,可以成功创建和查看 pod:

    $ kubectl run nginx-sre --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace sre
    
  3. 若要登录,请使用 Web 浏览器打开页面 https://microsoft.com/devicelogin 并输入代码BM4RHP3FD进行身份验证。

    pod/nginx-sre created
    
    $ kubectl get pods --namespace sre
    
    NAME        READY   STATUS    RESTARTS   AGE
    nginx-sre   1/1     Running   0
    
  4. 尝试在分配的 SRE 命名空间外部查看或计划 Pod。

    kubectl get pods --all-namespaces
    kubectl run nginx-sre --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace dev
    

    如以下示例输出中所示,这些 kubectl 命令失败: 用户的组成员身份和 Kubernetes Role 与 RoleBinding 无法授予在其他命名空间中创建或管理资源的权限。

    $ kubectl get pods --all-namespaces
    Error from server (Forbidden): pods is forbidden: User "akssre@contoso.com" cannot list pods at the cluster scope
    
    $ kubectl run nginx-sre --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace dev
    Error from server (Forbidden): pods is forbidden: User "akssre@contoso.com" cannot create pods in the namespace "dev"
    

在分配的命名空间外部创建和查看群集资源

查看 dev 命名空间外部的 Pod。 kubectl get pods使用以下命令:--all-namespaces

kubectl get pods --all-namespaces

该用户的组成员身份不具备允许此操作的 Kubernetes Role,如以下示例输出所示:

Error from server (Forbidden): pods is forbidden: User "aksdev@contoso.com" cannot list resource "pods" in API group "" at the cluster scope

同样,可以在不同的命名空间(例如 SRE 命名空间)中调度 Pod。 该用户的组成员身份与 Kubernetes Role 和 RoleBinding 不相符,无法授予这些权限,如以下示例输出所示:

$ kubectl run nginx-dev --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace sre

Error from server (Forbidden): pods is forbidden: User "akssre@contoso.com" cannot create resource "pods" in API group "" in the namespace "sre"

清理群集资源

若要清理所有资源,请运行以下命令:

# Get the admin kubeconfig context to delete the necessary cluster resources.

az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --admin

# Delete the dev and SRE namespaces. This also deletes the pods, Roles, and RoleBindings.

kubectl delete namespace dev
kubectl delete namespace sre

# Delete the Azure AD user accounts for aksdev and akssre.

az ad user delete --upn-or-object-id $AKSDEV_ID
az ad user delete --upn-or-object-id $AKSSRE_ID

# Delete the Azure AD groups for appdev and opssre. This also deletes the Azure role assignments.

az ad group delete --group appdev
az ad group delete --group opssre

后续步骤