Agent-to-agent (A2A)
With agentgateway, you can route to agent-to-agent (A2A) servers and expose their tools securely.
Before you begin
-
Follow the Get started guide to install kgateway with agentgateway enabled.
-
Make sure that agentgateway is enabled in kgateway.
helm get values kgateway -n kgateway-system -o yaml
Example output:
agentgateway: enabled: true
Step 1: Deploy an A2A server
Deploy an A2A server that you want agentgateway to proxy traffic to.
-
Clone the kgateway repository.
git clone https://github.com/kgateway-dev/kgateway.git
-
From the root directory, build the sample A2A server.
VERSION=2.1.0-main make test-a2a-agent-docker
-
Load the image into your cluster. The following
make
command assumes that you are using a local Kind cluster.CLUSTER_NAME=<your-cluster-name> VERSION=2.1.0-main make kind-load-test-a2a-agent
-
Deploy the A2A server. Notice that the Service uses the
appProtocol: kgateway.dev/a2a
setting. This way, kgateway configures the agentgateway proxy to use the A2A protocol.kubectl apply -f- <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: a2a-agent labels: app: a2a-agent spec: selector: matchLabels: app: a2a-agent template: metadata: labels: app: a2a-agent spec: containers: - name: a2a-agent image: ghcr.io/kgateway-dev/test-a2a-agent:2.1.0-main ports: - containerPort: 9090 --- apiVersion: v1 kind: Service metadata: name: a2a-agent spec: selector: app: a2a-agent type: ClusterIP ports: - protocol: TCP port: 9090 targetPort: 9090 appProtocol: kgateway.dev/a2a EOF
Step 2: Route with agentgateway
Route to the A2A server with agentgateway.
-
Create a Gateway resource that uses the
agentgateway
GatewayClass. Kgateway automatically creates an agentgateway proxy for you.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: agentgateway spec: gatewayClassName: agentgateway listeners: - protocol: HTTP port: 8080 name: http EOF
-
Verify that the Gateway is created successfully. You can also review the external address that is assigned to the Gateway. Note that depending on your environment it might take a few minutes for the load balancer service to be assigned an external address. If you are using a local Kind cluster without a load balancer such as
metallb
, you might not have an external address.kubectl get gateway agentgateway
Example output:
NAME CLASS ADDRESS PROGRAMMED AGE agentgateway agentgateway 1234567890.us-east-2.elb.amazonaws.com True 93s
-
Create an HTTPRoute resource that routes incoming traffic to the A2A server.
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: a2a spec: parentRefs: - name: agentgateway namespace: default rules: - backendRefs: - name: a2a-agent port: 9090 EOF
Step 3: Verify the connection
-
Get the agentgateway address.
export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway -o=jsonpath="{.status.addresses[0].value}") echo $INGRESS_GW_ADDRESS
kubectl port-forward deployment/agentgateway 8080:8080
-
Send a request to the A2A server.
curl -X POST http://$INGRESS_GW_ADDRESS:8080/ \ -H "Content-Type: application/json" \ -v \ -d '{ "jsonrpc": "2.0", "id": "1", "method": "tasks/send", "params": { "id": "1", "message": { "role": "user", "parts": [ { "type": "text", "text": "hello gateway!" } ] } } }'
curl -X POST http://localhost:8080/ \ -H "Content-Type: application/json" \ -v \ -d '{ "jsonrpc": "2.0", "id": "1", "method": "tasks/send", "params": { "id": "1", "message": { "role": "user", "parts": [ { "type": "text", "text": "hello gateway!" } ] } } }'
Example output:
{ "jsonrpc": "2.0", "id": "1", "result": { "id": "1", "message": { "role": "assistant", "parts": [ { "type": "text", "text": "hello gateway!" } ] } } }
Cleanup
You can remove the resources that you created in this guide.kubectl delete Deployment a2a-agent
kubectl delete Service a2a-agent
kubectl delete Gateway agentgateway
kubectl delete HTTPRoute a2a