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

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

重要

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

先决条件

  • 阅读使用外部身份提供者对 AKS 进行身份验证的 概念性概述。
  • 如果希望在本地运行 CLI 引用命令,install 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。 若要在本地计算机上安装或更新Azure CLI,请参阅 安装 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
      
    • 使用aks-preview命令验证你是否具有所需的扩展版本az extension show。

      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 插件,请按照 kubelogin 安装指南中的说明安装该插件。

设置环境变量。

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

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

注册JWTAuthenticatorPreview功能

  1. 使用JWTAuthenticatorPreview命令注册az feature register功能。

    az feature register --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService
    
  2. 使用 az feature show 命令检查功能的注册状态。

    az feature show --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService
    
  3. 当状态显示Registered时,请使用Microsoft.ContainerService命令刷新az provider register资源提供程序注册。

    az provider register --namespace Microsoft.ContainerService
    

设置 GitHub Actions OIDC 身份验证

  1. 确保GitHub Actions工作流具有所需的权限。

  2. 在 id-token: write 工作流文件中配置权限。 例如:

    permissions:
      id-token: write
      contents: read
    
  3. 为 OIDC 令牌访问设置适当的存储库和组织设置。 为令牌使用情况配置 存储库 OIDC 设置 和组织安全策略。

为 GitHub Actions OIDC 创建 JWT 验证器配置

  • 创建包含以下配置的文件 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'"
          }
      ]
    }
    

JWT 验证器配置元素

JWT 验证器配置包括以下关键元素: issuer、 claimValidationRules、 claimMappings和 userValidationRules。 每个元素在定义 AKS 如何从外部标识提供者验证和处理 JWT 令牌时提供特定用途。

发行者配置

下表描述了配置的关键元素 issuer :

颁发者配置元素 说明
url OIDC 颁发者 URL 必须与 JWT 中的 iss 声明匹配。
audiences 必须为哪些受众签发 JWT 的列表(根据 aud 声明进行检查)。

声明验证规则配置

下表描述了配置的关键元素 claimValidationRules :

声明验证规则元素 说明
expression 定义要应用于 JWT 声明的验证逻辑的 CEL 表达式。 表达式的判断结果必须为 true,令牌才能被接受。
message 验证规则失败时返回的错误消息。

声明映射配置

下表描述了配置的关键元素 claimMappings :

声明映射元素 说明
username 定义如何从 JWT 声明构造 Kubernetes 用户名的 CEL 表达式。 必须包含 aks:jwt: 前缀以防止与其他身份验证方法冲突。
groups 定义如何从 JWT 声明构造 Kubernetes 组成员身份的 CEL 表达式。 必须包含 aks:jwt: 前缀以防止与其他身份验证方法冲突。
uid 定义用户唯一标识符的可选 CEL 表达式。
extra 可选的附加用户属性映射,由 CEL 表达式定义。

用户验证规则配置

下表描述了配置的关键元素 userValidationRules :

用户验证规则元素 说明
expression 定义要应用于最终映射用户信息的附加验证逻辑的 CEL 表达式。 表达式必须计算为 true,用户才能被接受。
message 当用户验证规则失败时返回的错误消息。

创建 JWT 验证器

  • 使用 az aks jwtauthenticator add 命令将 JWT 验证器添加到 AKS 群集。

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

管理 JWT 验证器

列出所有 JWT 验证器

  • 使用 az aks jwtauthenticator list 命令列出群集上的所有 JWT 验证器。

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

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

  • 使用 az aks jwtauthenticator show 命令获取特定 JWT 验证器的详细信息。

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

使用 GitHub Actions OIDC 进行认证

  1. 在GitHub存储库中创建环境变量并设置以下必需的存储库机密:

    • AKS_SERVER_URL:AKS 群集的 API 服务器 URL。
    • AKS_CA_DATA:AKS 群集的 Base64 编码证书颁发机构数据。
  2. 创建一个工作流,用于获取 OIDC 令牌,并使用它对 AKS 群集进行身份验证。 以下示例工作流获取群集上运行的所有 Pod:

    注释

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

    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
    

获取 JWT 验证器配置的群集信息

  1. 使用 az aks show 命令获取群集的 API 服务器 URL。

    az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "fqdn" -o tsv | \
      awk '{print "https://" $0 ":443"}'
    
  2. 使用 az aks get-credentials 命令获取群集的 base64 编码证书颁发机构数据。

    # 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}'
    

测试身份验证

  1. 通过 推送到主分支 或 从存储库中的“操作”选项卡手动触发工作流 。

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

    Role-Based 访问控制 (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 Role-Based 访问控制 (RBAC)

为外部用户创建适当的 RBAC 绑定,并使用群集管理员凭据应用这些配置。

  1. 创建一个名为 rbac-config.yaml 为外部用户配置 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
    
  2. 使用 kubectl apply 以下命令应用 RBAC 配置:

    kubectl apply -f rbac-config.yaml
    

使用 RBAC 验证访问权限

  • 验证外部用户现在可以根据使用命令kubectl get nodeskubectl get pods和标志--user配置的RBAC权限访问资源。 例如:

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

删除 JWT 验证器

  • 不再需要 JWT 验证器时,请使用 az aks jwtauthenticator delete 命令将其从 AKS 群集中删除。

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