在 Azure Kubernetes 服务 (AKS) 中对 Kubernetes API 使用 Microsoft Entra ID 授权

适用于:✔️ AKS Automatic ✔️ AKS Standard

本文介绍如何使用Microsoft Entra ID标识授权对 Azure Kubernetes 服务 (AKS) 中的 Kubernetes API 的调用。 Microsoft Entra ID Kubernetes API 的授权使用 Azure RBAC 角色分配来授予对 Kubernetes 资源的访问权限。 对于内置的 Kubernetes 资源,请在群集或命名空间范围分配其中一个 AKS 内置角色(如 Azure Kubernetes 服务 RBAC 读取器)。 对于自定义资源(CRD),请使用 Azure ABAC 条件分配自定义角色,该条件指定可访问的 CRD 组或类型。 这两个角色分配组成:一个授予对标准 Kubernetes 资源的访问权限,另一个角色分配授予对特定自定义资源的条件访问。

有关 AKS 中可用 Kubernetes API 授权选项的概念概述,请参阅 群集授权概念

注释

Microsoft Entra ID 和 AKS 之间使用集成身份验证时,可以使用 Microsoft Entra 用户、组或服务主体作为 Kubernetes 基于角色的访问控制(Kubernetes RBAC)中的主体。 通过使用Microsoft Entra ID授权,无需单独管理 Kubernetes 的用户标识和凭据。 但是你仍然需要分别设置和管理 Microsoft Entra ID 角色分配以及任何 Kubernetes RBAC 绑定。

先决条件

  • 需要安装并配置 Azure CLI 2.24.0 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI
  • 需要 kubectl至少版本 1.18.3
  • 需要在群集上启用托管Microsoft Entra集成,然后才能为 Kubernetes API 添加Microsoft Entra ID授权。 如果需要启用托管的 Microsoft Entra 集成,请参阅 在 AKS 中使用 Microsoft Entra ID
  • 新角色分配可能需要最多 5 分钟完成传播并由授权服务器更新。
  • Kubernetes API 的 Microsoft Entra ID 授权要求,为身份验证配置的 Microsoft Entra 租户与包含 AKS 群集的订阅所属的租户相同。

创建使用托管的 Microsoft Entra 集成和 Microsoft Entra ID 授权的新 AKS 群集

  1. 使用 az group create 命令创建 Azure 资源组。

    export RESOURCE_GROUP=<resource-group-name>
    export LOCATION=<azure-region>
    
    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  2. 使用az aks create命令创建具有托管Microsoft Entra集成和Microsoft Entra ID授权的 AKS 标准群集。

    export CLUSTER_NAME=<cluster-name>
    
    az aks create \
        --resource-group $RESOURCE_GROUP \
        --name $CLUSTER_NAME \
        --enable-aad \
        --enable-azure-rbac \
        --generate-ssh-keys
    

    输出应类似于以下示例输出:

    "AADProfile": {
        "adminGroupObjectIds": null,
        "clientAppId": null,
        "enableAzureRbac": true,
        "managed": true,
        "serverAppId": null,
        "serverAppSecret": null,
        "tenantId": "****-****-****-****-****"
    }
    

在现有 AKS 群集上启用Microsoft Entra ID授权

对于现有的 AKS Standard 群集,请使用带有 az aks update 标志的 --enable-azure-rbac 命令为 Kubernetes API 启用 Microsoft Entra ID 授权。

# Set environment variables
export RESOURCE_GROUP=<resource-group-name>
export CLUSTER_NAME=<cluster-name>

# Enable Microsoft Entra ID authorization for the Kubernetes API
az aks update --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --enable-azure-rbac

AKS 内置角色

AKS 提供以下内置角色:

角色 Description
Azure Kubernetes 服务 RBAC 读取器 允许进行只读访问并查看命名空间中的大多数对象。 不允许查看角色或角色绑定。 此角色不允许查看 Secrets,因为读取 Secrets 的内容可访问命名空间中的 ServiceAccount 凭据,这将允许 API 以命名空间内任何 ServiceAccount 的身份进行访问(这是一种特权升级形式)。
Azure Kubernetes 服务 RBAC 编写器 允许对命名空间中的大多数对象进行读/写访问。 此角色不允许查看或修改角色或角色绑定。 但是,此角色允许以命名空间中的任何 ServiceAccount 身份访问 Secrets 和运行 Pod,因此可用于获取命名空间中任何 ServiceAccount 的 API 访问级别。
Azure Kubernetes 服务 RBAC 管理员 允许要在命名空间内授予的管理员访问权限。 允许对命名空间(或群集范围)中的大多数资源进行读/写访问,包括在命名空间内创建角色和角色绑定。 此角色不允许对资源配额或命名空间本身进行写入访问。
Azure Kubernetes 服务 RBAC 群集管理员 允许超级用户访问权限(对任何资源执行任何操作)。 它可以完全控制群集和所有命名空间中的每个资源。

为群集访问创建角色分配

  1. 使用 az aks show 命令获取 AKS 资源 ID。

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
  2. 使用 az role assignment create 命令创建角色分配。 <AAD-ENTITY-ID> 可以是服务主体的用户名或客户端 ID。 以下示例为 Azure Kubernetes 服务 RBAC 管理员角色创建角色分配。

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
    # Create a role assignment for the Azure Kubernetes Service RBAC Admin role
    az role assignment create --role "Azure Kubernetes Service RBAC Admin" --assignee <AAD-ENTITY-ID> --scope $AKS_ID
    

    注释

    可以使用命令创建 Azure Kubernetes 服务 RBAC 读取器和 Azure Kubernetes 服务 RBAC 编写器角色分配,该分配范围限定在群集az role assignment create中的特定命名空间,并将范围设置为所需的命名空间。

    az role assignment create --role "Azure Kubernetes Service RBAC Reader" --assignee <AAD-ENTITY-ID> --scope $AKS_ID/namespaces/<namespace-name>
    

创建自定义角色定义

对于内置的 Kubernetes 资源,自定义角色定义引用 Microsoft.ContainerService/managedClusters/ 下的相应 API 组操作。 以下示例仅允许用户读取部署,无法执行其他任何操作。 有关可能操作的完整列表,请参阅 Microsoft.ContainerService 操作。 若要筛选对特定自定义资源(CRD)组或类型的访问,请参阅本文后面的 ABAC 条件限制自定义资源访问

  1. 若要创建自定义角色定义,请复制以下文件,替换为 <YOUR-SUBSCRIPTION-ID> 自己的订阅 ID,然后将其另存为 deploy-view.json

    {
        "Name": "AKS Deployment Reader",
        "Description": "Lets you view all deployments in cluster/namespace.",
        "Actions": [],
        "NotActions": [],
        "DataActions": [
            "Microsoft.ContainerService/managedClusters/apps/deployments/read"
        ],
        "NotDataActions": [],
        "assignableScopes": [
            "/subscriptions/<YOUR-SUBSCRIPTION-ID>"
        ]
    }
    
  2. 使用az role definition create命令创建角色定义,并将--role-definition设置为在上一步中创建的deploy-view.json文件。

    az role definition create --role-definition @deploy-view.json 
    
  3. 使用 az role assignment create 命令将角色定义分配给用户或其他标识。

        # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
    # Create a role assignment for the AKS Deployment Reader role
    az role assignment create --role "AKS Deployment Reader" --assignee <AAD-ENTITY-ID> --scope $AKS_ID
    

使用 ABAC 条件限制自定义资源访问(预览版)

Important

AKS 预览功能可在自助服务和自愿选择的基础上启用。 预览版按“现状”和“视供应情况”提供,它们不包括在服务级别协议和有限保证范围内。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:

ABAC 条件使您能够将 Entra ID 角色分配过滤到特定的自定义资源 (CRD) 组和类型,这一切集中管理于 Microsoft Entra ID,无需为每个集群编写 Kubernetes RBAC RoleRoleBinding 清单。 有关 Azure ABAC 的背景信息,请参阅 什么是 Azure 角色分配条件?

何时使用 ABAC 条件

当您想要使用此功能时:

  • 限制被分配者可以列出或获取的 CRD 组或类型。
  • 集中实施来自 Microsoft Entra ID 的自定义资源访问边界,而无需在每个群集上管理 Kubernetes RBAC RoleRoleBinding 对象。
  • 区分由不同运算符发布的 CRD(例如,允许secrets-store.csi.x-k8s.io,而阻止security.istio.io)。

可用条件属性

在 AKS 群集上创作 Kubernetes API 的条件时,可以使用以下请求属性:

Attribute Description
Microsoft.ContainerService/managedClusters/customResources:group 正在访问的自定义资源的 API 组(例如 secrets-store.csi.x-k8s.io)。
Microsoft.ContainerService/managedClusters/customResources:kind 要访问的自定义资源的类型(例如 secretproviderclasses)。

将 ABAC 条件添加到角色分配

以下示例创建一个 AKS CRD 读取者自定义角色,该角色授予对自定义资源的读取访问权限。 然后,它分配该角色,并附加一个条件:仅允许访问 secretproviderclasses 组中的 secrets-store.csi.x-k8s.io(这是 Azure 密钥保管库 提供程序为 Secrets Store CSI Driver 使用的 CRD)。

  1. 将以下角色定义保存到名为 crd-reader.json的文件,并将其 <YOUR-SUBSCRIPTION-ID> 替换为自己的订阅 ID。

    {
        "Name": "AKS CRD Reader",
        "Description": "Lets you read custom resources in the cluster.",
        "Actions": [],
        "NotActions": [],
        "DataActions": [
            "Microsoft.ContainerService/managedClusters/customresources/read"
        ],
        "NotDataActions": [],
        "assignableScopes": [
            "/subscriptions/<YOUR-SUBSCRIPTION-ID>"
        ]
    }
    
  2. 使用 az role definition create 命令创建角色定义。

    az role definition create --role-definition @crd-reader.json
    
  3. 将以下条件保存到名为abac-condition.txt的文件。 条件允许非自定义资源读取传递不变,并将自定义资源读取限制为特定组和类型。

    (
     (
      !(ActionMatches{'Microsoft.ContainerService/managedClusters/customresources/read'})
     )
     OR
     (
      @Request[Microsoft.ContainerService/managedClusters/customResources:group] StringEqualsIgnoreCase 'secrets-store.csi.x-k8s.io'
      AND
      @Request[Microsoft.ContainerService/managedClusters/customResources:kind] StringEqualsIgnoreCase 'secretproviderclasses'
     )
    )
    
  4. 使用 az role assignment create 命令创建具有条件的角色分配。

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
    # Create a role assignment for the AKS CRD Reader role with an ABAC condition
    az role assignment create \
        --role "AKS CRD Reader" \
        --assignee <AAD-ENTITY-ID> \
        --scope $AKS_ID \
        --condition "$(cat abac-condition.txt)" \
        --condition-version "2.0" \
        --description "Allow reads on SecretProviderClass resources only"
    

还可以通过 Azure 门户添加条件。 在 “添加角色分配 ”页上,选择“ 条件 ”选项卡,然后选择 “添加条件 ”并使用视觉编辑器生成表达式。

验证条件

角色分配传播之后(可能需要五分钟),以获分配者的身份登录,确认他们能够读取指定的 CRD,但无法读取其他 CRD。

  1. 使用 az aks get-credentials 命令获取群集凭据。

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the cluster credentials
    az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME
    
  2. secretproviderclasses该组列出secrets-store.csi.x-k8s.io,条件允许。 该命令应成功并返回现有资源或空列表(如果未在群集上安装 CRD,则返回未找到的错误)。

    kubectl get secretproviderclasses.secrets-store.csi.x-k8s.io --all-namespaces
    
  3. 由条件阻挡的 Istio 组authorizationpolicies 的列表security.istio.io。 该命令应因来自 Microsoft Entra ID 授权 webhook 的 Forbidden 错误而失败(前提是集群中已安装 Istio CRD;否则,kubectl 会在 API 服务器到达授权 webhook 之前返回“未找到”错误)。

    kubectl get authorizationpolicies.security.istio.io --all-namespaces
    

清理资源

禁用 Microsoft Entra ID 授权

使用带有 az aks update 标志的 --disable-azure-rbac 命令删除 Microsoft Entra ID 授权。

# Set environment variables
export RESOURCE_GROUP=<resource-group-name>
export CLUSTER_NAME=<cluster-name>

# Disable Microsoft Entra ID authorization for the Kubernetes API
az aks update --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --disable-azure-rbac

删除角色分配

  1. 使用 az role assignment list 命令列出角色分配。

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
    # List role assignments for the AKS cluster
    az role assignment list --scope $AKS_ID --query [].id --output tsv
    
  2. 使用 az role assignment delete 命令删除角色分配。

    az role assignment delete --ids <LIST OF ASSIGNMENT IDS>
    

删除角色定义

使用 az role definition delete 命令删除自定义角色定义。

az role definition delete --name "AKS Deployment Reader"

删除资源组和 AKS 群集

使用 az group delete 命令删除资源组(及其包含的 AKS 群集)。

# Set environment variables
export RESOURCE_GROUP=<resource-group-name>

# Delete the resource group and all resources in it
az group delete --name $RESOURCE_GROUP --yes --no-wait

若要了解有关 AKS 的详细信息,请参阅以下文章: