Proxy gRPC Traffic
Google Remote Procedure Call (gRPC) is an open-source high-performance Remote Procedure Call (RPC) framework based on HTTP/2 protocol. It uses Protocol Buffers (protobuf) as the Interface Description Language (IDL). API7 Enterprise provides crucial functionalities such as protocol conversion, load balancing, authentication, and authorization, enhancing the potential of gRPC.
This guide shows how to use API7 Enterprise to proxy traffic for gRPC services.
Prerequisites
- Install API7 Enterprise.
- Install gRPCurl to send requests to gRPC services for validation.
Deploy an Example gRPC Server
API7 provides an example gRPC service for testing. You can start the service in Docker or Kubernetes, depending on your API7 installation.
Start a Server
- Docker
- Kubernetes
Start an example gRPC server in Docker listening on port 50051
:
docker run -d \
--name grpc-service \
-p 50051:50051 \
--restart always api7/grpc-server-example:1.0.0
Start an example gRPC server listening on port 50051
:
kubectl run grpc-service \
--image=api7/grpc-server-example:1.0.0 \
--port=50051 \
--restart=Always
You should see a pod/grpc-service created
response.
Verify Installation
- Docker
- Kubernetes
Expose the application's port 50051
through a service:
kubectl expose pod grpc-service --port 50051
You should see a service/grpc-service exposed
response.
Port forward 50051
of the service to localhost:
kubectl port-forward svc/grpc-service 50051:50051 &
Verify whether the gRPC server starts successfully by listing all available gRPC services and methods:
grpcurl -plaintext 127.0.0.1:50051 list
You should see the following output:
grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter
helloworld.TestImport
List all the available methods for the helloworld.Greeter
service:
grpcurl -plaintext 127.0.0.1:50051 list helloworld.Greeter
You should see the following output:
helloworld.Greeter.GetErrResp
helloworld.Greeter.Plus
helloworld.Greeter.SayHello
helloworld.Greeter.SayHelloAfterDelay
helloworld.Greeter.SayHelloBidirectionalStream
helloworld.Greeter.SayHelloClientStream
helloworld.Greeter.SayHelloServerStream
Create a Service and a Route
In this section, you will be creating a service with a route that proxies traffic to the example gRPC service.
- Dashboard
- Ingress Controller
- Go to your target gateway group.
- Select Published Services from the side navigation bar and then click Add Service.
- Select Add Manually.
- From the Add Service dialog box, do the following:
- In the Service Type field, choose
HTTP(Layer 7 Proxy)
. - In the Name field, enter
grpc-example
. - In the Upstream Scheme field, choose
gRPC
. - In the How to find the upstream field, choose
Use Nodes
. - Click Add Node.
- From the Add Node dialog box, do the following:
- In the Host field, enter
127.0.0.1
. - In the Port field, enter
50051
. - In the Weight field, use the default value
100
.
- In the Host field, enter
- In the Service Type field, choose
- Click Add.
- Inside the service that you just created in the previous step and then click Add Route.
- From the Add Route dialog box, do the following:
- In the Name field, enter
helloworld.Greeter
. - In the Path field, enter
/helloworld.Greeter/SayHello
. - In the Methods field, choose
GET
andPOST
.
- In the Name field, enter
- Click Add.
Create a Kubernetes manifest file to configure a route to the gRPC service using the ApisixRoute custom resource:
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: grpc-route
# namespace: api7 # replace with your namespace
spec:
http:
- name: helloworld-greeter
match:
paths:
- /helloworld.Greeter/SayHello
methods:
- GET
- POST
backends:
- serviceName: grpc-service
servicePort: 50051
Apply the configuration to your cluster:
kubectl apply -f grpc-route.yaml
Verify Configurations
Download the helloworld.proto
file here.
This example uses the helloworld.proto
file to ensure the gRPCurl CLI tool aligns the request and response format with the gRPC service definition.
grpcurl -plaintext \
-proto helloworld.proto \
-d '{"name":"apisix"}' \
127.0.0.1:50051 \
helloworld.Greeter.SayHello
You should see the following output:
{
"message": "Hello apisix"
}