在 Azure Kubernetes 服务中将 Kubernetes 基于角色的访问控制与 Microsoft Entra ID 配合使用

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

本文介绍如何:

  • 根据 Microsoft Entra 组成员身份使用 AKS 群集中的 Kubernetes RBAC 来控制访问权限。
  • 在 Microsoft Entra ID 中创建示例组和用户。
  • 在 AKS 群集中创建 Role 和 RoleBinding,以授予创建和查看资源的相应权限。

开始之前

  • 你有一个已启用 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 门户验证,请执行以下操作:

  • 在浏览器中,登录到 Azure 门户
  • 导航到 Kubernetes 服务,然后从左侧窗格中选择“群集配置”。
  • 在“身份验证和授权”部分下,验证是否选择了“使用 Kubernetes RBAC 的 Microsoft Entra 身份验证”选项

Example of AKS Authentication and Authorization page in Azure portal.

在 Microsoft Entra ID 中创建演示组

在本文中,我们将创建两个用户角色,用于演示 Kubernetes RBAC 和 Microsoft Entra ID 如何控制对群集资源的访问。 将使用以下两个示例角色:

  • 应用程序开发人员
    • 属于 appdev 组的名为 aksdev 的用户。
  • 站点可靠性工程师
    • 属于 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. 使用 az role assignment create 命令为 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 命令。

  1. 为名为 opssre 的 SRE 创建另一个示例组。

    OPSSRE_ID=$(az ad group create --display-name opssre --mail-nickname opssre --query id -o tsv)
    
  2. 创建 Azure 角色分配,以便为该组的成员授予“Azure Kubernetes 服务群集用户”角色。

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

在 Microsoft Entra ID 中创建演示用户

在 Microsoft Entra ID 中为应用程序开发人员和 SRE 创建两个示例组后,接下来我们将创建两个示例用户。 若要在本文结束时测试 Kubernetes RBAC 集成,需要使用这些帐户登录到 AKS 群集。

为应用程序开发人员设置用户主体名称和密码

为应用程序开发人员设置用户主体名称 (UPN) 和密码。 该 UPN 必须包含租户的已验证域名,例如 aksdev@contoso.com

以下命令提示你输入 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 中创建第一个用户帐户。 以下示例通过显示名称 AKS Dev 以及 UPN 和安全密码(使用 AAD_DEV_UPN 和 AAD_DEV_PW 中的值)创建用户 :
AKSDEV_ID=$(az ad user create \
  --display-name "AKS Dev" \
  --user-principal-name $AAD_DEV_UPN \
  --password $AAD_DEV_PW \
  --query objectId -o tsv)
  1. 使用 az ad group member add 命令将用户添加到在上一部分创建的 appdev 组。
az ad group member add --group appdev --member-id $AKSDEV_ID
  1. 为 SRE 设置 UPN 和密码。 该 UPN 必须包含租户的已验证域名,例如 akssre@contoso.com。 以下命令提示你输入 UPN 并将其设置为“AAD_SRE_UPN”,以便在以后的命令中使用:
echo "Please enter the UPN for SREs: " && read AAD_SRE_UPN
  1. 以下命令提示你输入密码并将其设置为“AAD_SRE_PW”,以便在以后的命令中使用:
echo "Please enter the secure password for SREs: " && read AAD_SRE_PW
  1. 创建第二个用户帐户。 以下示例通过显示名称 AKS SRE 以及 UPN 和安全密码(使用 AAD_SRE_UPN 和 AAD_SRE_PW 中的值)创建用户 :
# Create a user for the SRE role
AKSSRE_ID=$(az ad user create \
  --display-name "AKS SRE" \
  --user-principal-name $AAD_SRE_UPN \
  --password $AAD_SRE_PW \
  --query objectId -o tsv)

# Add the user to the opssre Azure AD group
az ad group member add --group opssre --member-id $AKSSRE_ID

为应用开发人员创建 AKS 群集资源

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

  1. 使用 az aks get-credentials 命令获取群集管理员凭据。 在以下某个部分中,你将获得普通用户群集凭据,以查看 Microsoft Entra 身份验证流的运作方式。
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --admin
  1. 使用 kubectl create namespace 命令在 AKS 群集中创建一个命名空间。 以下示例创建名为 dev 的命名空间:
kubectl create namespace dev

注意

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

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

  1. 为 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: ["*"]
  1. 使用 kubectl apply 命令创建 Role,并指定 YAML 清单的文件名。
kubectl apply -f role-dev-namespace.yaml
  1. 使用 az ad group showaz ad group show 命令获取 appdev 组的资源 ID。 此组将设置为在下一步骤中创建的角色绑定的使用者。
az ad group show --group appdev --query id -o tsv
  1. 为 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,请指定“kind: User”并将“groupObjectId”替换为上述示例中的用户主体名称 (UPN)。

  1. 使用 kubectl apply 命令创建角色绑定,并指定 YAML 清单的文件名:
kubectl apply -f rolebinding-dev-namespace.yaml

为 SRE 创建 AKS 群集资源

现在,我们将重复上述步骤,为 SRE 创建命名空间、Role 和 RoleBinding。

  1. 使用 kubectl create namespace 命令为 sre 创建名称空间。
kubectl create namespace sre
  1. 创建名为 role-sre-namespace.yaml 的文件并粘贴以下 YAML 清单:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: sre-user-full-access
  namespace: sre
rules:
- apiGroups: ["", "extensions", "apps"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["batch"]
  resources:
  - jobs
  - cronjobs
  verbs: ["*"]
  1. 使用 kubectl apply 命令创建 Role,并指定 YAML 清单的文件名。
kubectl apply -f role-sre-namespace.yaml
  1. 使用 az ad group show 命令获取 opssre 组的资源 ID。
az ad group show --group opssre --query id -o tsv
  1. opssre 组创建角色绑定,以使用前面创建的角色来访问命名空间。 创建名为 rolebinding-sre-namespace.yaml 的文件并粘贴以下 YAML 清单。 在最后一行中,将“groupObjectId”替换为上一命令的组对象 ID 输出。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: sre-user-access
  namespace: sre
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: sre-user-full-access
subjects:
- kind: Group
  namespace: sre
  name: groupObjectId
  1. 使用 kubectl apply 命令创建 RoleBinding,并指定 YAML 清单的文件名。
kubectl apply -f rolebinding-sre-namespace.yaml

使用 Microsoft Entra 标识与群集资源交互

现在,我们将测试在 AKS 群集中创建和管理资源时预期的权限是否有效。 在这些示例中,我们将在用户的已分配命名空间中计划和查看 Pod,并尝试在已分配命名空间之外计划和查看 Pod。

  1. 使用 az aks get-credentials 命令重置 kubeconfig 上下文。 在上一部分,你已使用群集管理员凭据设置了上下文。 管理员用户会绕过 Microsoft Entra 登录提示。 如果没有 --admin 参数,应用的用户上下文将要求使用 Microsoft Entra ID 对所有请求进行身份验证。
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --overwrite-existing
  1. 在 dev 命名空间中使用 kubectl run 命令计划一个基本的 NGINX Pod。
kubectl run nginx-dev --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace dev
  1. 在出现登录提示时,输入在本文开头创建的你自己的 appdev@contoso.com 帐户的凭据。 成功登录后,帐户令牌将会缓存,供将来的 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/deviceloginchina and enter the code B24ZD6FP8 to authenticate.

pod/nginx-dev created
  1. 在 dev 命名空间中使用 kubectl get pods 命令查看 Pod。
kubectl get pods --namespace dev
  1. 确保 NGINX pod 的状态为“正在运行”。 输出将与以下输出类似:
$ kubectl get pods --namespace dev

NAME        READY   STATUS    RESTARTS   AGE
nginx-dev   1/1     Running   0          4m

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

尝试在 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 "aksdev@contoso.com" cannot create resource "pods" in API group "" in the namespace "sre"

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

要确认我们的 Microsoft Entra 组成员身份和 Kubernetes RBAC 能否在不同的用户和组之间正常运行,请在以 opssre 用户身份登录后尝试运行前面的命令。

  1. 使用 az aks get-credentials 命令重置 kubeconfig 上下文,以清除前面为 aksdev 用户缓存的身份验证令牌。
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --overwrite-existing
  1. 尝试分配的 sre 命名空间中计划和查看 pod。 出现提示时,请使用在本文开头创建的你自己的 opssre@contoso.com 凭据登录。
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. To sign in, use a web browser to open the page https://microsoft.com/deviceloginchina and enter the code BM4RHP3FD to authenticate.

pod/nginx-sre created

$ kubectl get pods --namespace sre

NAME        READY   STATUS    RESTARTS   AGE
nginx-sre   1/1     Running   0
  1. 尝试在分配的 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"

清理资源

在本文中,你在 AKS 群集中创建了资源,并在 Microsoft Entra ID 中创建了用户和组。 若要清理所有资源,请运行以下命令:

# 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

后续步骤