使用 AKS 结构化身份验证配置外部标识提供者(预览版)

本文介绍如何使用结构化身份验证为 Azure Kubernetes 服务(AKS)控制平面身份验证配置外部标识提供者。 了解如何创建 JSON Web 令牌(JWT)验证器、配置声明验证和映射,以及测试身份验证流。

重要

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

先决条件

  • 如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI

    • 如果使用的是本地安装,请使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录

    • 出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展的详细信息,请参阅 将扩展与 Azure CLI 配合使用

    • 运行az version命令,以查看已安装的版本和依赖库。 若要升级到最新版本,请运行az upgrade

  • 本文需要 2.77.0 或更高版本的 Azure CLI。
  • 需要安装 aks-preview Azure CLI 扩展版本 18.0.0b41 或更高版本才能使用结构化身份验证功能。
    • 如果还没有 aks-preview 扩展,请使用 az extension add 以下命令安装它:
      az extension add --name aks-preview
      
    • 如果已有 aks-preview 扩展,请更新该扩展,以确保使用 az extension update 以下命令获得最新版本:
      az extension update --name aks-preview
      
    • 验证是否具有所需的版本:
      az extension show --name aks-preview --query version
      
  • 运行 Kubernetes 1.30 或更高版本的 AKS 群集。 若要创建 AKS 群集,请参阅 快速入门:使用 Azure CLI 部署 Azure Kubernetes 服务 (AKS) 群集
  • kubectl 用于与 Kubernetes 群集交互的命令行工具。 若要在本地安装 kubectl,请使用 az aks install-cli 命令。
    az aks install-cli
    
  • 支持 OpenID Connect(OIDC)的外部标识提供者。
  • 从群集节点到标识提供者的网络连接。
  • 如果打算使用kubelogin插件,请使用这些安装说明安装该插件

设置环境变量。

为资源组和群集名称设置以下环境变量:

export RESOURCE_GROUP="<your-resource-group-name>"
export CLUSTER_NAME="<your-cluster-name>"

注册预览功能

如果您正在使用一个未注册功能的订阅,请注册该功能JWTAuthenticatorPreview

az feature register --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService

检查注册状态:

az feature show --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService

当状态显示 Registered 时,刷新资源提供者注册:

az provider register --namespace Microsoft.ContainerService

设置身份提供者

配置外部标识提供者以支持 OIDC 身份验证。 选择身份提供商以查看具体设置说明。

GitHub Actions OIDC 设置

  1. 确保 GitHub Actions 工作流具有必要的权限。
  2. id-token: write 工作流文件中配置权限:
    permissions:
      id-token: write
      contents: read
    
  3. 为 OIDC 令牌访问设置适当的存储库和组织设置。 为令牌使用情况配置 存储库 OIDC 设置 和组织安全策略。

创建 JWT 验证器配置

创建一个 JSON 配置文件,用于定义如何验证和处理来自身份提供商的令牌。 选择您的身份提供者以获取具体配置示例:

GitHub 配置

对于 GitHub Actions OIDC,请创建一个名为 jwt-config.json 以下配置的文件:

{
  "issuer": {
      "url": "https://token.actions.githubusercontent.com",
      "audiences": [
          "my-api"
      ]
  },
  "claimValidationRules": [
      {
          "expression": "has(claims.sub)",
          "message": "must have sub claim"
      }
  ],
  "claimMappings": {
      "username": {
          "expression": "'aks:jwt:github:' + claims.sub"
      }
  },
  "userValidationRules": [
      {
          "expression": "has(user.username)",
          "message": "must have username"
      },
      {
          "expression": "!user.username.startsWith('aks:jwt:github:system')",
          "message": "username must not start with 'aks:jwt:github:system'"
      }
  ]
}

配置元素

  • 发布者:OIDC 发布者配置。
    • url:OIDC 颁发者 URL,必须与 JWT 中的 iss 声明匹配。
    • 访问群体:必须颁发 JWT 的受众列表(根据 aud 声明进行检查)。
    • certificateAuthority:传输层安全性(TLS)验证的可选 base64 编码根证书捆绑包。
  • claimValidationRules:使用 CEL 表达式验证 JWT 声明的验证规则数组。
    • 表达式:必须计算结果为 true 的 CEL 表达式。
    • 消息:验证失败时显示的错误消息。
  • claimMappings:定义如何将 JWT 声明映射到 Kubernetes 用户信息。
    • username:定义如何从声明构造用户名的 CEL 表达式。
    • groups:定义如何从声明构造组成员身份的 CEL 表达式。
    • uid:用户标识符的可选 CEL 表达式。
    • extra:可选的更多用户属性映射。
  • userValidationRules:应用于最终用户信息的验证规则数组。
    • 表达式:必须为映射的用户计算结果为 true 的 CEL 表达式。
    • 消息:用户验证失败时显示的错误消息。

重要

所有用户名和组映射都必须包含 aks:jwt: 前缀,以防止与其他身份验证方法冲突。

创建 JWT 验证器

将 JWT 验证器添加到 AKS 群集:

az aks jwtauthenticator add \
    --resource-group $RESOURCE_GROUP \
    --cluster-name $CLUSTER_NAME \
    --name external-auth \
    --config-file jwt-config.json

验证验证器

列出群集上的所有 JWT 验证器:

az aks jwtauthenticator list \
    --resource-group $RESOURCE_GROUP \
    --cluster-name $CLUSTER_NAME

获取特定验证器的详细信息:

az aks jwtauthenticator show \
    --resource-group $RESOURCE_GROUP \
    --cluster-name $CLUSTER_NAME \
    --name external-auth

设置用于身份验证的客户端

将客户端配置为使用外部标识提供者进行身份验证。 为特定配置选择身份提供者:

GitHub Actions 工作流身份验证

对于 GitHub Actions OIDC,请创建一个工作流,该工作流获取 OIDC 令牌,并使用它向 AKS 群集进行身份验证。 下面是获取群集上运行的所有 Pod 的示例工作流:

name: AKS Access with GitHub OIDC
on:
  workflow_dispatch:
  push:
    branches: [main]

permissions:
  id-token: write
  contents: read

jobs:
  aks-access:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install kubectl
        uses: azure/setup-kubectl@v3
        with:
          version: 'latest'

      - name: Get GitHub OIDC token
        id: get_token
        run: |
          TOKEN=$(curl -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
            "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=my-api" | \
            jq -r '.value')
          echo "::add-mask::$TOKEN"
          echo "oidc_token=$TOKEN" >> $GITHUB_OUTPUT

      - name: Create kubeconfig with OIDC token
        run: |
          cat <<EOF > kubeconfig
          apiVersion: v1
          kind: Config
          clusters:
          - cluster:
              certificate-authority-data: ${{ secrets.AKS_CA_DATA }}
              server: ${{ secrets.AKS_SERVER_URL }}
            name: aks-cluster
          contexts:
          - context:
              cluster: aks-cluster
              user: github-oidc-user
            name: aks-context
          current-context: aks-context
          users:
          - name: github-oidc-user
            user:
              token: ${{ steps.get_token.outputs.oidc_token }}
          EOF

      - name: List all pods in the cluster
        run: |
          export KUBECONFIG=./kubeconfig
          kubectl get pods --all-namespaces

所需的存储库机密和变量

在 GitHub 存储库中设置这些机密:

秘密:

  • AKS_SERVER_URL:AKS 群集的 API 服务器 URL。
  • AKS_CA_DATA:AKS 群集的 Base64 编码证书颁发机构数据。

注释

访问群体值 my-api 应与 JWT 验证器配置中配置的受众匹配。

获取 AKS 群集信息

若要获取所需的群集信息,请运行:

# Get cluster info
az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "fqdn" -o tsv | \
  awk '{print "https://" $0 ":443"}'

# Get CA data (base64 encoded)
az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --file - --format exec | \
  grep certificate-authority-data | awk '{print $2}'

方法 2:使用静态令牌

如果有 JWT 令牌,可以直接使用它:

users:
- name: external-user
  user:
    token: eyJhbGciOiJSUzI1NiIs...

测试身份验证

可以通过以下方式触发工作流:

  • 推送到主分支
  • 从存储库中的“作”选项卡手动触发它

在“作”选项卡中监视工作流执行,验证身份验证是否正常工作。

基于角色的访问控制(RBAC)配置前初次设置的预期的输出:

Error from server (Forbidden): nodes is forbidden: User "aks:jwt:github:your-sub" cannot list resource "nodes" in API group "" at the cluster scope

此错误表示身份验证成功,但缺少授权。

配置 Kubernetes 基于角色的访问控制(RBAC)

为外部用户创建适当的 RBAC 绑定。 使用群集管理员凭据应用这些配置。 选择您的身份提供商以获取提供商特定的示例:

创建示例角色和绑定

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-user-role
rules:
- apiGroups: [""]
  resources: ["pods", "services", "nodes"]
  verbs: ["get", "list"]
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-user-binding
subjects:
- kind: User
  # This matches the username expression in claim mappings for GitHub; example of GitHub subject is "repo:<organization-name>/<repository-name>:ref:refs/heads/main"
  name: aks:jwt:github:your-github-sub
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: external-user-role
  apiGroup: rbac.authorization.k8s.io

应用 RBAC 配置:

kubectl apply -f rbac-config.yaml

验证访问权限

测试外部用户现在可以访问资源:

kubectl get nodes --user external-user
kubectl get pods --user external-user

删除 JWT 验证器

不再需要身份验证器时,请删除验证器:

az aks jwtauthenticator delete \
    --resource-group $RESOURCE_GROUP \
    --cluster-name $CLUSTER_NAME \
    --name external-auth

后续步骤