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. 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: gcr.io/solo-public/docs/test-a2a-agent:latest
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
-
As a user, send a request to the A2A server. As an assistant, the agent echoes back the message that you sent.
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