为 GKE 代理请求代理身份

您在 Google Kubernetes Engine (GKE) 集群上部署的代理工作负载通常需要以代理自身的身份或代表最终用户访问外部工具和服务。安全管理员和平台管理员还想知道已部署的代理在 Google Cloud服务中执行的操作。本文档介绍了如何通过为 Pod 请求代理身份来为代理工作负载配置身份验证。借助此代理身份,您可以配置身份验证,而无需手动管理不同工作流的凭据,并可将 GKE 代理与 Gemini Enterprise Agent Platform 集成。本文档适用于在 GKE 集群上构建和运行代理工作负载的应用开发者。

您应该已经熟悉以下主题:

价格

在 GKE 中,使用代理身份无需额外付费。

限制

  • 您只能在代理注册表中自动注册部署。 其他工作负载控制器和静态 Pod 不支持自动注册。虽然您可以为所有工作负载类型请求代理身份,但通过在代理注册表中注册,您可以将这些身份与代理平台集成。
  • 绑定代理身份访问令牌仅使用 https://www.googleapis.com/auth/cloud-platform OAuth 范围。您无法为绑定访问令牌指定其他范围。

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。如果您之前安装了 gcloud CLI,请通过运行 gcloud components update 命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
  • 启用 Agent Registry API(如果尚未启用):

    启用 API 所需的角色

    如需启用 API,您需要拥有 serviceusage.services.enable 权限。如果您创建了项目,则可能已经通过 Owner 角色 (roles/owner) 拥有此权限。否则,您可以通过 Service Usage Admin 角色 (roles/serviceusage.serviceUsageAdmin) 获取此权限。了解如何授予角色。

    gcloud services enable agentregistry.googleapis.com

  • 验证您是否拥有已启用 Workload Identity Federation for GKE 且运行 GKE 1.37.0-gke.3503000 版或更高版本的现有 Autopilot 集群或 Standard 集群。

  • 验证您是否有足够的配额来执行令牌交换操作。此配额的名称为每个区域每分钟的 Workload Identity 令牌交换请求数。如需了解详情,请参阅配额和限制。

所需的角色

如需获得请求代理身份和部署工作负载所需的权限,请让您的管理员为您授予 Google Cloud 项目的 Kubernetes Engine Developer (roles/container.developer) IAM 角色。 如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

为工作负载请求代理身份

如需为 Pod 获取代理身份,请向 Pod 规范添加注释,以请求工作负载的 SPIFFE ID 并将 X.509 证书捆绑包注入每个 Pod。对于由 Deployment 管理的 Pod,您还应添加注解和标签,以在 Agent Registry 中注册代理。 虽然注册是可选的,但只有已注册的代理才能使用 Agent Gateway 等代理平台服务。如需详细了解特定注释和标签,请参阅工作负载级配置。

以下步骤展示了如何创建请求代理身份的 Deployment 示例:

  1. 查找您的组织 ID。如果您的项目不属于任何组织,请跳过此步骤,改为查找项目编号。

    gcloud projects get-ancestors PROJECT_ID
    

    将 PROJECT_ID 替换为集群项目 ID。

    输出类似于以下内容:

    ID: my-project
    TYPE: project
    ID: 811159889184
    TYPE: folder
    ID: 301928500920
    TYPE: organization
    

    记下 organization 资源的 ID 字段中的值。

  2. 连接到集群:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    替换以下内容:

    • CLUSTER_NAME:您的集群的名称。
    • CONTROL_PLANE_LOCATION:集群控制平面所在的区域或可用区。
  3. 创建一个命名空间来运行示例 Deployment:

    kubectl create namespace NAMESPACE_NAME
    

    将 NAMESPACE_NAME 替换为命名空间的名称。

  4. 为 Deployment 创建 Kubernetes ServiceAccount:

    kubectl create serviceaccount SERVICEACCOUNT_NAME \
        --namespace=NAMESPACE_NAME
    

    将 SERVICEACCOUNT_NAME 替换为 ServiceAccount 的名称。

  5. 将以下 Deployment 清单保存为 agent-identity-deployment.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: agent-identity-deployment
      namespace: NAMESPACE_NAME
      # Add the agent to Agent Registry
      labels:
        registry.gke.io/functional-type: "AGENT"
      annotations:
        # A2A protocol metadata annotation for automated Agent Card discovery
        a2a-protocol.org/agent-card: |
          card:
            endpoint: /.well-known/agent-card.json
            protocol: HTTP
            port: 8080
    spec:
      replicas: 2
      selector:
        matchLabels:
          workload-type: agent
      template:
        metadata:
          name: agent-identity-pod
          annotations:
            iam.gke.io/identity: "spiffe://TRUST_DOMAIN/*" # The trust domain from which to assign SPIFFE IDs.
            iam.gke.io/inject-podcertificates: "true" # Inject X.509 certificates and per-Pod private key into each Pod.
            iam.gke.io/spiffe-identity-type: "agent-identity" # Required for Agent Registry registration.
          labels:
            workload-type: agent
        spec:
          serviceAccountName: SERVICEACCOUNT_NAME
          containers:
          - name: agent
            image: python:3.11-slim
            command: ["sleep","infinity"]
    

    将 TRUST_DOMAIN 替换为为项目中的代理颁发身份的信任域。此值必须使用以下语法之一,具体取决于您的项目是否位于组织中:

    • 组织中的项目:agents.global.org-ORGANIZATION_ID.system.id.goog,其中 ORGANIZATION_ID 是组织的 ID。
    • 不属于组织的项目:agents.global.proj-PROJECT_NUMBER.system.id.goog,其中 PROJECT_NUMBER 是集群项目的项目编号。

    此部署会为工作负载请求代理身份,将每个 Pod 的 X.509 证书添加到 Pod,并在代理注册表中注册代理。

  6. 创建 Deployment:

    kubectl apply -f agent-identity-deployment.yaml
    
  7. 验证 pod 是否正在运行:

    kubectl get pods -l workload-type=agent -n NAMESPACE_NAME
    

检查分配的代理身份

部署请求代理身份的工作负载后,您可以通过检查 X.509 证书来验证身份。如果您停用证书注入,则可以从 GKE 元数据服务器获取未绑定的身份令牌,以检查主题字段,如向 Google Cloud API 进行身份验证中所述。

如需读取 Pod 中的 X.509 证书,请按以下步骤操作:

  1. 检查 Pod 是否有权访问 X.509 证书和私钥:

    kubectl get pod POD_NAME -n NAMESPACE_NAME \
        -o=jsonpath='{range .spec.volumes[*]}{.name}{"\n"}{end}'
    

    将 POD_NAME 替换为使用代理身份的 Pod 的名称。

    输出类似于以下内容:

    kube-api-access-bx86g
    gke-workload-spiffe-credentials
    

    在此输出中,gke-workload-spiffe-credentials 卷是注入证书的位置。如果您没有看到此卷,请验证 Pod 规范中的 iam.gke.io/inject-podcertificates 注解是否设置为 true 值。

  2. 在 Pod 中创建交互式 shell 会话:

    kubectl exec -n NAMESPACE_NAME -it POD_NAME -- /bin/bash
    
  3. 在 shell 会话中,列出 gke-workload-spiffe-credentials 卷中的凭据:

    ls -1 /var/run/secrets/workload-spiffe-credentials/
    

    输出类似于以下内容:

    x509.credential-bundle.private-key.pem
    TRUST_DOMAIN.spiffe-trust-bundle.pem
    

    输出会显示以下文件:

    • x509.credential-bundle.private-key.pem:代理身份凭据软件包,其中包括 X.509 证书链和 Pod 特有的私钥。此凭据包用于请求访问令牌和 ID 令牌,以及通过使用 mTLS 向 Google CloudAPI 进行身份验证。
    • TRUST_DOMAIN.spiffe-trust-bundle.pem:根 CA 信任软件包,其中包含构成代理身份凭据信任锚点的自签名证书。此信任包主要用于在 mTLS 握手期间验证来自其他工作负载的 TLS 证书。
  4. 如需获取与 Pod 关联的 SPIFFE ID,请读取 X.509 证书:

    openssl x509 -in /var/run/secrets/workload-spiffe-credentials/x509.credential-bundle.private-key.pem -text -noout
    

    输出类似于以下内容:

    Certificate:
        Data:
        # Multiple lines are omitted here
            X509v3 extensions:
                # Multiple lines are omitted here
                X509v3 Subject Alternative Name: critical
                    URI:spiffe://agents.global.org-301928500920.system.id.goog/resources/container/projects/729788050015/locations/us-central1/clusters/cluster-2/ns/agent-identity-ns/sa/agent-identity-sa
        # Multiple lines are omitted here
    

    在此输出中,X509v3 Subject Alternative Name 字段的 URI 字段中的值是代理的 SPIFFE ID。

如果您的代理 Pod 已分配 SPIFFE ID,则您对代理身份的请求成功。您可以使用分配的身份向各种工具和服务进行身份验证。

后续步骤