使用ack-agent-gateway实现Agent2Agent(A2A)流量治理与认证

为了让 AI 智能体应用快速具备对外服务能力,可基于Gateway API安装ack-agent-gateway扩展,实现Agent2Agent(A2A)协议流量的精准管理。

适用范围

  • ACK托管集群版本在1.32及以上。

  • 已在集群中安装Gateway API,且版本在1.3.0及以上。

安装ack-agent-gateway

ack-agent-gateway 是一个实现了 Gateway API 标准的网关组件。它利用Gateway API 这套标准化的流量管理模型,可便捷地配置和管理面向 AI 智能体场景的服务流量。

重要

该组件当前处于测试阶段,如需在生产环境中使用请先进行充分的测试。

  1. ACK集群列表页面,单击目标集群名称,在集群详情页左侧导航栏,选择应用 > Helm

  2. Helm页面,单击创建,在Chart区域搜索并选中ack-agent-gateway,其他设置保持默认,然后单击下一步

    组件默认安装在ack-agent-gateway命名空间,并以组件名称发布应用。
  3. 参数页面中,选择最新的Chart版本,然后单击确定

  4. 安装完成后,可在Helm页面查看组件,状态为已部署

步骤一:部署示例 A2A 服务

此步骤旨在部署一个简单的、支持 A2A 协议的智能体服务作为后端,用于后续的网关路由测试。

  1. 使用以下内容,创建名为 a2a-server.yaml 的文件。该文件定义了一个 Deployment 和一个用于在集群内部暴露该服务的 Service。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: demo-a2a
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/name: demo-a2a
      template:
        metadata:
          labels:
            app.kubernetes.io/name: demo-a2a
        spec:
          containers:
            - image: registry-cn-hangzhou.ack.aliyuncs.com/dev/sample-a2a-agent-helloworld:v0.1.0
              imagePullPolicy: IfNotPresent
              name: agent
              ports:
                - containerPort: 9999
                  name: server
                  protocol: TCP
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: demo-a2a-agent-server
    spec:
      ports:
        - name: server
          port: 9999
          protocol: TCP
          targetPort: 9999
      selector:
        app.kubernetes.io/name: demo-a2a
      sessionAffinity: None
      type: ClusterIP
  2. 部署示例 A2A 服务。

    kubectl apply -f a2a-server.yaml
  3. 检查服务的 Pod 状态。

    kubectl get pod -l app.kubernetes.io/name=demo-a2a

    预期输出:请确保 Pod 处于 Running 状态。

    NAME                        READY   STATUS    RESTARTS   AGE
    demo-a2a-77dd75ddcf-qn9jx   1/1     Running   0          13s

步骤二:创建 Gateway 和路由规则

此步骤旨在创建一个网关实例,并定义一条路由规则,将外部流量引导至上一步部署的 A2A 服务。

  1. 使用以下内容,创建名为 a2a-gateway.yaml 的文件。

    ---
    # 自定义 Backend 资源,定义后端 A2A 服务
    apiVersion: agentgateway.alibabacloud.com/v1alpha1
    kind: Backend
    metadata:
      name: test-a2a
    spec:
      type: A2A
      a2a:
        targets:
          - name: a2a-target
            static:
              # 指向步骤一中创建的 Service
              host: demo-a2a-agent-server
              port: 9999
    ---
    # Gateway 资源,定义流量入口
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: test-a2a-gateway
    spec:
      # 指定 ack-agent-gateway 作为此 Gateway 的实现者
      gatewayClassName: ack-agent-gateway
      listeners:
        - name: http
          # 网关对外暴露的端口
          port: 80
          protocol: HTTP
          allowedRoutes:
            namespaces:
              # 仅允许在相同命名空间下的 HTTPRoute 绑定到此 Listener
              from: Same
    ---
    # HTTPRoute 资源,定义路由规则
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: route-for-a2a-backend
    spec:
      parentRefs:
        # 将此 HTTPRoute 绑定到名为 test-a2a-gateway 的 Gateway 上
        - name: test-a2a-gateway
      rules:
        - backendRefs:
            # 引用自定义的 Backend 资源作为后端
            - group: agentgateway.alibabacloud.com
              kind: Backend
              name: test-a2a
  2. 执行以下命令,创建网关及相关资源。

    kubectl apply -f a2a-gateway.yaml
  3. 执行以下命令,获取网关的公网访问地址。

    kubectl get gateway test-a2a-gateway

    ADDRESS 字段即为该网关关联的 CLB 实例的公网 IP 地址。请记录此 IP,后续步骤将使用它。

    NAME               CLASS               ADDRESS        PROGRAMMED   AGE
    test-a2a-gateway   ack-agent-gateway   8.136.xx.xx    True         4m36s

步骤三:测试服务连通性

此步骤旨在使用一个 A2A 客户端工具,通过上一步创建的网关访问后端服务,以验证路由配置是否生效。

  1. 安装Git工具。下载 A2A 协议的官方示例代码。

    此处 git checkout 一个特定的提交(commit)是为了确保示例代码与本文档的兼容性。实际项目中,建议检出(checkout)一个稳定的发布标签(tag)。
    git clone https://github.com/a2aproject/a2a-samples.git && \
    cd a2a-samples && git checkout d4fa006438e52 && \
    cd samples/python/hosts/cli
  2. 请确保本地已安装Python环境。使用uv工具安装客户端程序的依赖。

    uv sync
  3. 通过网关访问 A2A 服务。请将命令中的 <GATEWAY_IP> 替换为上一步获取的网关地址(ADDRESS)。

    uv run . --agent http://<GATEWAY_IP>

    预期输出:连接成功后,打印出智能体的信息卡(Agent Card),然后继续等待输入信息。

    Will use headers: {}
    ======= Agent Card ========
    {"capabilities":{"streaming":true},"defaultInputModes":["text"],"defaultOutputModes":["text"],"description":"Just a hello world agent","name":"Hello World Agent",...}
    =========  starting a new task ========
    
    What do you want to send to the agent? (:q or quit to exit):
  4. 在提示符后输入 hello 并按回车,客户端会将消息发送给后端服务,然后根据提示操作,会收到 Hello World 的回复。

    What do you want to send to the agent? (:q or quit to exit): hello
    Select a file path to attach? (press enter to skip):
    stream event => {"kind":"message","messageId":"...","parts":[{"kind":"text","text":"Hello World"}],"role":"agent"}
    
    {"kind":"message","messageId":"...","parts":[{"kind":"text","text":"Hello World"}],"role":"agent"}
  5. 输入 quit 退出客户端程序。

步骤四:为服务增加 API Key 认证(可选)

本步骤将演示如何在不修改任何业务代码的前提下,通过 TrafficPolicy 资源为智能体服务增加 API Key 认证能力。

  • TrafficPolicy (CRD):这是 ack-agent-gateway 提供的一个自定义资源,用于为路由规则附加高级功能。这是一种策略附着(Policy Attachment)的实现,可以将认证、限流等策略与 HTTPRoute 解耦。

  • Secret:用于安全地存储 API Key 凭证。

API Key 认证是一种简单的认证方式。凭证若被泄露,可能被滥用,请注意凭证的管理与保护。
  1. 使用以下内容,创建名为 a2a-api-key.yaml 的文件。 此 YAML 文件定义了一个包含两个 API Key 的 Secret,以及一个TrafficPolicy,用于将 API Key 认证策略附加到 HTTPRoute

    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: a2a-api-key
    stringData:
      # key(如 key1)仅作标识;value(如 key-value-foo)是客户端需提供的实际凭证
      key1: 'key-value-foo'
      key2: 'key-value-bar'
    ---
    apiVersion: agentgateway.alibabacloud.com/v1alpha1
    kind: TrafficPolicy
    metadata:
      name: test-a2a-apikey-auth
    spec:
      targetRefs:                              # 策略附加的目标
        - group: gateway.networking.k8s.io
          kind: HTTPRoute
          name: route-for-a2a-backend          # 附加到之前创建的 HTTPRoute
      traffic:
        authentication:
          apiKeyAuth:
            secretRef:
              name: a2a-api-key                # 引用存储凭证的 Secret
  2. 应用认证策略。

    kubectl apply -f a2a-api-key.yaml
  3. 测试认证效果。

    1. 首先,尝试不带任何凭证再次访问服务。请将 <GATEWAY_IP> 替换为实际的网关地址。

      uv run . --agent http://<GATEWAY_IP>

      预期输出:由于缺少有效的 API Key,请求将被网关拒绝,程序会因收到 401 Unauthorized 错误而启动失败。

      a2a.client.errors.A2AClientHTTPError: HTTP Error 401: Failed to fetch agent card from http://8.136.xx.xx/.well-known/agent-card.json: Client error '401 Unauthorized' ...
    2. 接下来,使用 --bearer-token 参数携带正确的 API Key(如key-value-foo)再次访问。

      uv run . --bearer-token 'key-value-foo' --agent http://<GATEWAY_IP>

      预期输出:请求头中会包含 Authorization: Bearer key-value-foo。网关验证凭证通过后,会将请求转发至后端服务,程序成功启动。

      Will use headers: {'Authorization': 'Bearer key-value-foo'}
      ======= Agent Card ========
      {"capabilities":{"streaming":true},"defaultInputModes":["text"],"defaultOutputModes":["text"],"description":"Just a hello world agent","name":"Hello World Agent",...}
      =========  starting a new task ========
      
      What do you want to send to the agent? (:q or quit to exit):

清理资源

为避免产生不必要的费用,请在完成实验后删除本教程创建的所有 Kubernetes 资源和云资源。

  1. 删除本教程中创建的所有 Kubernetes 资源。

    # 如果执行了可选的步骤四,请先删除认证相关的资源
    kubectl delete -f a2a-api-key.yaml
    
    # 删除网关和路由规则
    kubectl delete -f a2a-gateway.yaml
    
    # 删除后端的示例服务
    kubectl delete -f a2a-server.yaml
  2. 确认 CLB 实例已释放。 删除 Gateway 资源后,会自动删除其关联的 CLB 实例。可登录到负载均衡控制台,确认对应的实例已被删除。