在 Azure Kubernetes 服务中使用 Kubernetes 基于角色的访问控制和 Azure Active Directory 标识来控制对群集资源的访问Control access to cluster resources using Kubernetes role-based access control and Azure Active Directory identities in Azure Kubernetes Service

可将 Azure Kubernetes Service (AKS) 配置为使用 Azure Active Directory (AD) 进行用户身份验证。Azure Kubernetes Service (AKS) can be configured to use Azure Active Directory (AD) for user authentication. 在此配置中,可以使用 Azure AD 身份验证令牌登录到 AKS 群集。In this configuration, you sign in to an AKS cluster using an Azure AD authentication token. 还可以根据用户标识或目录组成员身份配置 Kubernetes 基于角色的访问控制 (Kubernetes RBAC),以限制对群集资源的访问。You can also configure Kubernetes role-based access control (Kubernetes RBAC) to limit access to cluster resources based a user's identity or group membership.

本文介绍如何使用 Azure AD 组成员身份在 AKS 群集中通过 Kubernetes RBAC 来控制对命名空间和群集资源的访问。This article shows you how to use Azure AD group membership to control access to namespaces and cluster resources using Kubernetes RBAC in an AKS cluster. 将在 Azure AD 中创建示例组和用户,然后在 AKS 群集中创建角色和角色绑定,以授予创建和查看资源的相应权限。Example groups and users are created in Azure AD, then Roles and RoleBindings are created in the AKS cluster to grant the appropriate permissions to create and view resources.

准备阶段Before you begin

本文假设已有一个启用了 Azure AD 集成的现有 AKS 群集。This article assumes that you have an existing AKS cluster enabled with Azure AD integration. 如需 AKS 群集,请参阅将 Azure Active Directory 与 AKS 集成If you need an AKS cluster, see Integrate Azure Active Directory with AKS.

需要安装并配置 Azure CLI 2.0.61 或更高版本。You need the Azure CLI version 2.0.61 or later installed and configured. 运行 az --version 即可查找版本。Run az --version to find the version. 如果需要进行安装或升级,请参阅安装 Azure CLIIf you need to install or upgrade, see Install Azure CLI.

在 Azure AD 中创建演示组Create demo groups in Azure AD

本文将会创建两个用户角色用于演示 Kubernetes RBAC 和 Azure AD 如何控制对群集资源的访问。In this article, let's create two user roles that can be used to show how Kubernetes RBAC and Azure AD control access to cluster resources. 将使用以下两个示例角色:The following two example roles are used:

  • 应用程序开发人员Application developer
    • 属于 appdev 组的名为 aksdev 的用户。A user named aksdev that is part of the appdev group.
  • 站点可靠性工程师Site reliability engineer
    • 属于 opssre 组的名为 akssre 的用户。A user named akssre that is part of the opssre group.

在生产环境中,可以使用 Azure AD 租户中的现有用户和组。In production environments, you can use existing users and groups within an Azure AD tenant.

首先,使用 az aks show 命令获取 AKS 群集的资源 ID。First, get the resource ID of your AKS cluster using the az aks show command. 将该资源 ID 分配到名为 AKS_ID 的变量,以便可以在其他命令中引用它。Assign the resource ID to a variable named AKS_ID so that it can be referenced in additional commands.

AKS_ID=$(az aks show \
    --resource-group myResourceGroup \
    --name myAKSCluster \
    --query id -o tsv)

使用 az ad group create 命令在 Azure AD 中为应用程序开发人员创建第一个示例组。Create the first example group in Azure AD for the application developers using the az ad group create command. 以下示例创建名为 appdev 的组:The following example creates a group named appdev:

APPDEV_ID=$(az ad group create --display-name appdev --mail-nickname appdev --query objectId -o tsv)

现在,使用 az role assignment create 命令为 appdev 组创建 Azure 角色分配。Now, create an Azure role assignment for the appdev group using the az role assignment create command. 此分配可为该组的任何成员授予 Azure Kubernetes 服务群集用户角色,因此可让他们使用 kubectl 来与 AKS 群集交互。This assignment lets any member of the group use kubectl to interact with an AKS cluster by granting them the Azure Kubernetes Service Cluster User Role.

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

提示

如果出现类似于 Principal 35bfec9328bd4d8d9b54dea6dac57b82 does not exist in the directory a5443dcd-cd0e-494d-a387-3039b419f0d5. 的错误,请等待几秒,让 Azure AD 组对象 ID 传播到整个目录,然后重试 az role assignment create 命令。If you receive an error such as Principal 35bfec9328bd4d8d9b54dea6dac57b82 does not exist in the directory a5443dcd-cd0e-494d-a387-3039b419f0d5., wait a few seconds for the Azure AD group object ID to propagate through the directory then try the az role assignment create command again.

为名为 opssre 的 SRE 创建第二个示例组。Create a second example group, this one for SREs named opssre:

OPSSRE_ID=$(az ad group create --display-name opssre --mail-nickname opssre --query objectId -o tsv)

同样,请创建 Azure 角色分配,以便为该组的成员授予 Azure Kubernetes 服务群集用户角色:Again, create an Azure role assignment to grant members of the group the Azure Kubernetes Service Cluster User Role:

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

在 Azure AD 中创建演示用户Create demo users in Azure AD

在 Azure AD 中为应用程序开发人员和 SRE 创建两个示例组后,接下来让我们创建两个示例用户。With two example groups created in Azure AD for our application developers and SREs, now lets create two example users. 在本文结束时若要测试 Kubernetes RBAC 集成,需要使用这些帐户登录到 AKS 群集。To test the Kubernetes RBAC integration at the end of the article, you sign in to the AKS cluster with these accounts.

使用 az ad user create 命令在 Azure AD 中创建第一个用户帐户。Create the first user account in Azure AD using the az ad user create command.

以下示例使用显示名称 AKS Dev 和用户主体名称 (UPN) aksdev@contoso.com 创建一个用户。The following example creates a user with the display name AKS Dev and the user principal name (UPN) of aksdev@contoso.com. 请更新该 UPN 以包含 Azure AD 租户的验证域(请将 contoso.com 替换为你自己的域),并提供自己的安全 --password 凭据:Update the UPN to include a verified domain for your Azure AD tenant (replace contoso.com with your own domain), and provide your own secure --password credential:

AKSDEV_ID=$(az ad user create \
  --display-name "AKS Dev" \
  --user-principal-name aksdev@contoso.com \
  --password P@ssw0rd1 \
  --query objectId -o tsv)

现在,使用 az ad group member add 命令将该用户添加到在上一部分创建的 appdev 组:Now add the user to the appdev group created in the previous section using the az ad group member add command:

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

创建第二个用户帐户。Create a second user account. 以下示例使用显示名称 AKS SRE 和用户主体名称 (UPN) akssre@contoso.com 创建一个用户。The following example creates a user with the display name AKS SRE and the user principal name (UPN) of akssre@contoso.com. 同样,请更新该 UPN 以包含 Azure AD 租户的验证域(请将 contoso.com 替换为你自己的域),并提供自己的安全 --password 凭据:Again, update the UPN to include a verified domain for your Azure AD tenant (replace contoso.com with your own domain), and provide your own secure --password credential:

# Create a user for the SRE role
AKSSRE_ID=$(az ad user create \
  --display-name "AKS SRE" \
  --user-principal-name akssre@contoso.com \
  --password P@ssw0rd1 \
  --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 群集资源Create the AKS cluster resources for app devs

现在创建 Azure AD 组和用户。The Azure AD groups and users are now created. 之前已经为组成员创建了 Azure 角色分配,使他们能够以普通用户的身份连接到 AKS 群集。Azure role assignments were created for the group members to connect to an AKS cluster as a regular user. 现在,让我们配置 AKS 群集,以允许这些不同的组访问特定的资源。Now, let's configure the AKS cluster to allow these different groups access to specific resources.

首先使用 az aks get-credentials 命令获取群集管理员凭据。First, get the cluster admin credentials using the az aks get-credentials command. 在以下部分之一,你将获取普通用户群集凭据,以查看 Azure AD 身份验证流的运作方式。In one of the following sections, you get the regular user cluster credentials to see the Azure AD authentication flow in action.

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

使用 kubectl create namespace 命令在 AKS 群集中创建一个命名空间。Create a namespace in the AKS cluster using the kubectl create namespace command. 以下示例创建名为 dev 的命名空间:The following example creates a namespace name dev:

kubectl create namespace dev

在 Kubernetes 中,角色定义要授予的权限,角色绑定将这些权限应用到所需的用户或组。 In Kubernetes, Roles define the permissions to grant, and RoleBindings apply them to desired users or groups. 这些分配可应用于特定命名空间或整个群集。These assignments can be applied to a given namespace, or across the entire cluster. 有关详细信息,请参阅使用 Kubernetes RBAC 授权For more information, see Using Kubernetes RBAC authorization.

首先,为 dev 命名空间创建一个角色。First, create a Role for the dev namespace. 此角色授予对命名空间的完全权限。This role grants full permissions to the namespace. 在生产环境中,可为不同的用户或组指定更精细的权限。In production environments, you can specify more granular permissions for different users or groups.

创建名为 role-dev-namespace.yaml 的文件并粘贴以下 YAML 清单:Create a file named role-dev-namespace.yaml and paste the following YAML manifest:

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: ["*"]

使用 kubectl apply 命令创建角色,并指定 YAML 清单的文件名:Create the Role using the kubectl apply command and specify the filename of your YAML manifest:

kubectl apply -f role-dev-namespace.yaml

接下来,使用 az ad group show 命令获取 appdev 组的资源 ID。Next, get the resource ID for the appdev group using the az ad group show command. 此组将设置为在下一步骤中创建的角色绑定的使用者。This group is set as the subject of a RoleBinding in the next step.

az ad group show --group appdev --query objectId -o tsv

现在,为 appdev 组创建角色绑定,以使用前面创建的角色来访问命名空间。Now, create a RoleBinding for the appdev group to use the previously created Role for namespace access. 创建名为 rolebinding-dev-namespace.yaml 的文件并粘贴以下 YAML 清单。Create a file named rolebinding-dev-namespace.yaml and paste the following YAML manifest. 在最后一行中,请将 groupObjectId 替换为前一命令的组对象 ID 输出:On the last line, replace groupObjectId with the group object ID output from the previous command:

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

使用 kubectl apply 命令创建角色绑定,并指定 YAML 清单的文件名:Create the RoleBinding using the kubectl apply command and specify the filename of your YAML manifest:

kubectl apply -f rolebinding-dev-namespace.yaml

为 SRE 创建 AKS 群集资源Create the AKS cluster resources for SREs

现在请重复上述步骤,为 SRE 创建命名空间、角色和角色绑定。Now, repeat the previous steps to create a namespace, Role, and RoleBinding for the SREs.

首先,使用 kubectl create namespace 命令为 sre 创建一个命名空间:First, create a namespace for sre using the kubectl create namespace command:

kubectl create namespace sre

创建名为 role-sre-namespace.yaml 的文件并粘贴以下 YAML 清单:Create a file named role-sre-namespace.yaml and paste the following YAML manifest:

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: ["*"]

使用 kubectl apply 命令创建角色,并指定 YAML 清单的文件名:Create the Role using the kubectl apply command and specify the filename of your YAML manifest:

kubectl apply -f role-sre-namespace.yaml

使用 az ad group show 命令获取 opssre 组的资源 ID:Get the resource ID for the opssre group using the az ad group show command:

az ad group show --group opssre --query objectId -o tsv

opssre 组创建角色绑定,以使用前面创建的角色来访问命名空间。Create a RoleBinding for the opssre group to use the previously created Role for namespace access. 创建名为 rolebinding-sre-namespace.yaml 的文件并粘贴以下 YAML 清单。Create a file named rolebinding-sre-namespace.yaml and paste the following YAML manifest. 在最后一行中,请将 groupObjectId 替换为前一命令的组对象 ID 输出:On the last line, replace groupObjectId with the group object ID output from the previous command:

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

使用 kubectl apply 命令创建角色绑定,并指定 YAML 清单的文件名:Create the RoleBinding using the kubectl apply command and specify the filename of your YAML manifest:

kubectl apply -f rolebinding-sre-namespace.yaml

使用 Azure AD 标识来与群集资源交互Interact with cluster resources using Azure AD identities

现在,让我们通过在 AKS 群集中创建和管理资源,来测试权限是否按预期方式工作。Now, let's test the expected permissions work when you create and manage resources in an AKS cluster. 在这些示例中,你将在用户的分配命名空间中计划和查看 pod。In these examples, you schedule and view pods in the user's assigned namespace. 然后,尝试在分配的命名空间外部计划和查看 pod。Then, you try to schedule and view pods outside of the assigned namespace.

首先,使用 az aks get-credentials 命令重置 kubeconfig 上下文。First, reset the kubeconfig context using the az aks get-credentials command. 在上一部分,你已使用群集管理员凭据设置了上下文。In a previous section, you set the context using the cluster admin credentials. 管理员用户将绕过 Azure AD 登录提示。The admin user bypasses Azure AD sign in prompts. 如果未指定 --admin 参数,应用的用户上下文将要求使用 Azure AD 对所有请求进行身份验证。Without the --admin parameter, the user context is applied that requires all requests to be authenticated using Azure AD.

az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --overwrite-existing

在 dev 命名空间中使用 kubectl run 命令计划一个基本的 NGINX Pod:Schedule a basic NGINX pod using the kubectl run command in the dev namespace:

kubectl run nginx-dev --image=nginx --namespace dev

根据登录提示,输入在本文开头部分创建的 appdev@contoso.com 帐户的凭据。As the sign in prompt, enter the credentials for your own appdev@contoso.com account created at the start of the article. 成功登录后,帐户令牌将会缓存,供将来的 kubectl 命令使用。Once you are successfully signed in, the account token is cached for future kubectl commands. 如以下示例输出中所示,现已成功计划 NGINX:The NGINX is successfully schedule, as shown in the following example output:

$ kubectl run nginx-dev --image=nginx --namespace dev

To sign in, use a web browser to open the page https://aka.ms/deviceloginchina and enter the code B24ZD6FP8 to authenticate.

pod/nginx-dev created

现在,请在 dev 命名空间中使用 kubectl get pods 命令查看 Pod。Now use the kubectl get pods command to view pods in the dev namespace.

kubectl get pods --namespace dev

如以下示例输出中所示,NGINX pod 已成功运行:As shown in the following example output, the NGINX pod is successfully Running:

$ kubectl get pods --namespace dev

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

在分配的命名空间外部创建和查看群集资源Create and view cluster resources outside of the assigned namespace

现在请尝试在 dev 命名空间外部查看 pod。Now try to view pods outside of the dev namespace. 再次使用 kubectl get pod 命令,但这次会看到 --all-namespaces,如下所示:Use the kubectl get pods command again, this time to see --all-namespaces as follows:

kubectl get pods --all-namespaces

该用户的组成员身份不具备允许此操作的 Kubernetes 角色,如以下示例输出中所示:The user's group membership does not have a Kubernetes Role that allows this action, as shown in the following example output:

$ kubectl get pods --all-namespaces

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

同样,尝试在不同的命名空间(例如 sre 命名空间)中计划 pod。In the same way, try to schedule a pod in different namespace, such as the sre namespace. 该用户的组成员身份与 Kubernetes 角色和角色绑定不相符,无法授予这些权限,如以下示例输出中所示:The user's group membership does not align with a Kubernetes Role and RoleBinding to grant these permissions, as shown in the following example output:

$ kubectl run nginx-dev --image=nginx --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 群集资源的访问Test the SRE access to the AKS cluster resources

若要确认 Azure AD 组成员身份和 Kubernetes RBAC 是否可在不同的用户和组之间正常运行,请在以 opssre 用户身份登录后尝试运行前面的命令。To confirm that our Azure AD group membership and Kubernetes RBAC work correctly between different users and groups, try the previous commands when signed in as the opssre user.

使用 az aks get-credentials 命令重置 kubeconfig 上下文,以清除前面为 aksdev 用户缓存的身份验证令牌:Reset the kubeconfig context using the az aks get-credentials command that clears the previously cached authentication token for the aksdev user:

az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --overwrite-existing

尝试分配的 sre 命名空间中计划和查看 pod。Try to schedule and view pods in the assigned sre namespace. 出现提示时,请使用在本文开头部分创建的 opssre@contoso.com 凭据登录:When prompted, sign in with your own opssre@contoso.com credentials created at the start of the article:

kubectl run nginx-sre --image=nginx --namespace sre
kubectl get pods --namespace sre

如以下示例输出中所示,可以成功创建和查看 pod:As shown in the following example output, you can successfully create and view the pods:

$ kubectl run nginx-sre --image=nginx --namespace sre

To sign in, use a web browser to open the page https://aka.ms/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

现在,请尝试在分配的 SRE 命名空间外部查看或计划 pod:Now, try to view or schedule pods outside of assigned SRE namespace:

kubectl get pods --all-namespaces
kubectl run nginx-sre --image=nginx --namespace dev

如以下示例输出中所示,这些 kubectl 命令失败:These kubectl commands fail, as shown in the following example output. 用户的组成员身份和 Kubernetes 角色与角色绑定无法授予在其他命名空间中创建或管理资源的权限:The user's group membership and Kubernetes Role and RoleBindings don't grant permissions to create or manager resources in other namespaces:

$ 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=nginx --namespace dev
Error from server (Forbidden): pods is forbidden: User "akssre@contoso.com" cannot create pods in the namespace "dev"

清理资源Clean up resources

在本文中,你已在 AKS 群集中创建了资源,并在 Azure AD 中创建了用户和组。In this article, you created resources in the AKS cluster and users and groups in Azure AD. 若要清理所有这些资源,请运行以下命令:To clean up all these resources, run the following commands:

# 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

后续步骤Next steps

有关如何保护 Kubernetes 群集的详细信息,请参阅 AKS 的访问和标识选项For more information about how to secure Kubernetes clusters, see Access and identity options for AKS).

有关标识和资源控制的最佳做法,请参阅有关 AKS 中的身份验证和授权的最佳做法For best practices on identity and resource control, see Best practices for authentication and authorization in AKS.