Docs
Ingress ControllerManage traffic and APIsTraffic ManagementProxy gRPC Traffic

Proxy gRPC Traffic

Configure APISIX or API7 Ingress Controller to proxy gRPC traffic to a Kubernetes gRPC service.

Applies to:API7 Ingress Controller (drives API7 Gateway)APISIX Ingress Controller (drives Apache APISIX)

Goal

Route gRPC requests through the gateway to a Kubernetes gRPC service using a Gateway API GRPCRoute or an APISIX CRD route.

Before you begin

  • Complete Set Up Ingress Controller and Gateway.
  • Install gRPCurl to verify gRPC traffic proxying.
  • Download the helloworld.proto file and save it as helloworld.proto.
  • You have kubectl configured against the cluster used in the setup guide.
  • Choose free ports for the gRPC upstream and the gateway HTTP/2 listener. The examples use 50051 and 9081.

Set the variables this guide uses:

export UPSTREAM_GRPC_PORT="50051"
export GATEWAY_SERVICE_NAME="apisix-gateway"   # your gateway's Service name in namespace aic
export GATEWAY_H2_PORT="9081"
export FORWARD_PORT="9081"                     # local port for the gateway port-forward
export GRPC_SERVICE="helloworld.Greeter"
export GRPC_METHOD="helloworld.Greeter.SayHello"
export GRPC_REQUEST='{"name":"World"}'
export PROTO_FILE="helloworld.proto"

Steps

Step 1: Deploy the example gRPC upstream

Create a manifest for the gRPC server deployment and service in the aic namespace:

grpc-server.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: aic
  name: grpc-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grpc-service
  template:
    metadata:
      labels:
        app: grpc-service
    spec:
      containers:
        - name: grpc-service
          image: api7/grpc-server-example:1.0.0
          ports:
            - containerPort: 50051
---
apiVersion: v1
kind: Service
metadata:
  namespace: aic
  name: grpc-service
spec:
  type: ClusterIP
  selector:
    app: grpc-service
  ports:
    - name: grpc
      port: 50051
      targetPort: 50051

Apply the manifest and wait for the Pod to become ready:

kubectl apply -f grpc-server.yaml
kubectl wait --for=condition=ready pod -l app=grpc-service -n aic --timeout=120s

Forward the upstream port to your local machine and verify the gRPC services are available:

kubectl port-forward -n aic "svc/grpc-service" "${UPSTREAM_GRPC_PORT}:${UPSTREAM_GRPC_PORT}" &
grpcurl -plaintext "127.0.0.1:${UPSTREAM_GRPC_PORT}" list

Expected output:

grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter
helloworld.TestImport

List the methods of helloworld.Greeter:

grpcurl -plaintext "127.0.0.1:${UPSTREAM_GRPC_PORT}" list "${GRPC_SERVICE}"

Expected output includes helloworld.Greeter.SayHello.

Step 2: Create the gRPC route

Create a manifest for a GRPCRoute that routes SayHello to the gRPC service:

grpc-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  namespace: aic
  name: grpc-route
spec:
  parentRefs:
  - name: apisix
  rules:
  - matches:
    - method:
        service: helloworld.Greeter
        method: SayHello
    backendRefs:
    - name: grpc-service
      port: 50051

Apply the manifest:

kubectl apply -f grpc-route.yaml

Step 3: Enable HTTP/2 on the gateway

By default, the gateway supports TLS-encrypted HTTP/2 on port 9443. For non-encrypted HTTP/2, add an extra port to the gateway configuration.

Export the current Helm values:

helm get values -n aic apisix --all > values.yaml

In values.yaml, add 9081 as an additional HTTP/2 port:

values.yaml
service:
  http:
    containerPort: 9080
    enabled: true
    servicePort: 80
    additionalContainerPorts:
      - port: 9081
        enable_http2: true

Upgrade the release:

helm upgrade -n aic apisix apisix/apisix -f values.yaml

Validate

Forward the gateway HTTP/2 port to your local machine:

kubectl port-forward -n aic "svc/${GATEWAY_SERVICE_NAME}" "${FORWARD_PORT}:${GATEWAY_H2_PORT}" &

Send a gRPC request to the route using helloworld.proto:

grpcurl -plaintext \
  -proto "${PROTO_FILE}" \
  -d "${GRPC_REQUEST}" \
  "127.0.0.1:${FORWARD_PORT}" \
  "${GRPC_METHOD}"

Expected output:

{
  "message": "Hello World"
}

Roll back / Clean up

Delete the manifests created in this guide:

kubectl delete -f grpc-route.yaml
kubectl delete -f grpc-server.yaml

Stop the local port-forward processes if they are still running:

kill %1 2>/dev/null || true

To remove the additional HTTP/2 port from the gateway, re-run the Helm upgrade without the additionalContainerPorts entry, or re-apply the original values file.

Troubleshoot

SymptomCauseFix
grpcurl cannot list the upstream services.The gRPC Pod is not ready or the upstream port-forward is not running.Verify the Pod status and that UPSTREAM_GRPC_PORT is forwarded.
grpcurl returns Unavailable for the gateway route.The route is not accepted, or HTTP/2 is not enabled on the gateway port.Check the GRPCRoute/ApisixRoute status, confirm enable_http2: true on GATEWAY_H2_PORT, and verify the port-forward targets GATEWAY_SERVICE_NAME.
The gateway responds with plain HTTP instead of gRPC.The gateway listener is using HTTP/1.1, or the client did not use plaintext HTTP/2.Confirm additionalContainerPorts for GATEWAY_H2_PORT sets enable_http2: true and use grpcurl -plaintext with the local FORWARD_PORT.