使用 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

      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] 命令注册该功能。

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

    az feature show --name JWTAuthenticatorPreview --namespace Microsoft.ContainerService
    
  3. 当状态显示 Registered 时,请使用 [Microsoft.ContainerService][az-provider-register] 命令刷新 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 验证器配置包括以下关键元素: issuerclaimValidationRulesclaimMappingsuserValidationRules。 每个元素在定义 AKS 如何从外部标识提供者验证和处理 JWT 令牌时提供特定用途。

发行者配置

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

颁发者配置元素 说明
url OIDC 颁发者 URL 必须与 JWT 中的 iss 声明匹配。
audiences 必须为哪些受众签发 JWT 的列表(根据 aud 声明进行检查)。
certificateAuthority 连接到颁发者 URL 时,用于传输层安全(TLS)验证的可选 base64 编码的根证书包。

声明验证规则配置

下表描述了配置的关键元素 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][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][az-aks-jwtauthenticator-list] 命令列出群集上的所有 JWT 验证器。

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

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

  • 使用 [az aks jwtauthenticator show][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][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][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][az-aks-jwtauthenticator-delete] 命令将其从 AKS 群集中删除。

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