You are browsing documentation for an older version. See the latest documentation here.
gRPC
Overview
This guide walks through deploying a Service that listens for gRPC connections and exposes this service outside of the cluster using Kong Gateway.
For this example, you need to:
- Deploy a gRPC test application.
- Route gRPC traffic to it using GRPCRoute or Ingress.
To make gRPC
requests, you need a client that can invoke gRPC requests. You can use grpcurl
as the client. Ensure that you have it installed on your local system.
Prerequisites: Install Kong Ingress Controller with Gateway API support in your Kubernetes cluster and connect to Kong.
Prerequisites
Install the Gateway APIs
-
Install the Gateway API CRDs before installing Kong Ingress Controller.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
-
Install the experimental Gateway API CRDs to test this feature.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/experimental-install.yaml
-
Create a
Gateway
andGatewayClass
instance to use.echo " --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: kong annotations: konghq.com/gatewayclass-unmanaged: 'true' spec: controllerName: konghq.com/kic-gateway-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: kong spec: gatewayClassName: kong listeners: - name: proxy port: 80 protocol: HTTP allowedRoutes: namespaces: from: All " | kubectl apply -f -
The results should look like this:
gatewayclass.gateway.networking.k8s.io/kong created gateway.gateway.networking.k8s.io/kong created
Install Kong
You can install Kong in your Kubernetes cluster using Helm.
-
Add the Kong Helm charts:
helm repo add kong https://charts.konghq.com helm repo update
-
Install Kong Ingress Controller and Kong Gateway with Helm:
helm install kong kong/ingress -n kong --create-namespace
-
Enable the Gateway API Alpha feature gate:
kubectl set env -n kong deployment/kong-controller CONTROLLER_FEATURE_GATES="GatewayAlpha=true" -c ingress-controller
The results should look like this:
deployment.apps/kong-controller env updated
Test connectivity to Kong
Kubernetes exposes the proxy through a Kubernetes service. Run the following commands to store the load balancer IP address in a variable named PROXY_IP
:
-
Populate
$PROXY_IP
for future commands:export PROXY_IP=$(kubectl get svc --namespace kong kong-gateway-proxy -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo $PROXY_IP
-
Ensure that you can call the proxy IP:
curl -i $PROXY_IP
The results should look like this:
HTTP/1.1 404 Not Found Content-Type: application/json; charset=utf-8 Connection: keep-alive Content-Length: 48 X-Kong-Response-Latency: 0 Server: kong/3.0.0 {"message":"no Route matched with those values"}
Deploy a gRPC test application
echo "---
apiVersion: v1
kind: Service
metadata:
name: grpcbin
labels:
app: grpcbin
spec:
ports:
- name: plaintext
port: 9000
targetPort: 9000
- name: tls
port: 9001
targetPort: 9001
selector:
app: grpcbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpcbin
spec:
replicas: 1
selector:
matchLabels:
app: grpcbin
template:
metadata:
labels:
app: grpcbin
spec:
containers:
- image: kong/grpcbin
name: grpcbin
ports:
- containerPort: 9000
- containerPort: 9001
" | kubectl apply -f -
The results should look like this:
deployment.apps/grpcbin created
service/grpcbin created
Create a GRPCRoute
gRPC over HTTPS
All services are assumed to be either HTTP or HTTPS by default. We need to update the service to specify gRPC as the protocol by adding a konghq.com/protocol
annotation.
The annotation grpcs
informs Kong that this service is a gRPC (with TLS) service and not a HTTP service.
kubectl annotate service grpcbin 'konghq.com/protocol=grpcs'
The results should look like this:
service/grpcbin annotated
Create a certificate
-
Create a test certificate for the
example.com
hostname.The results should look like this:
Older OpenSSL versions, including the version provided with OS X Monterey, require using the alternative version of this command.
-
Create a Secret containing the certificate.
kubectl create secret tls example.com --cert=./server.crt --key=./server.key
The results should look like this:
secret/example.com created
Route gRPC traffic
Now that the test application is running, you can create GRPC routing configuration that proxies traffic to the application:
Test the configuration
Use grpcurl
to send a gRPC request through the proxy:
grpcurl -d '{"greeting": "Kong"}' -authority example.com -insecure $PROXY_IP:443 hello.HelloService.SayHello
The results should look like this:
{
"reply": "hello Kong"
}
gRPC over HTTP
All services are assumed to be either HTTP or HTTPS by default. We need to update the service to specify gRPC as the protocol by adding a konghq.com/protocol
annotation.
The annotation grpc
informs Kong that this service is a gRPC (with TLS) service and not a HTTP service.
kubectl annotate service grpcbin 'konghq.com/protocol=grpc'
Now that the test application is running, you can create GRPC routing configuration that proxies traffic to the application:
For gRPC over HTTP (plaintext without TLS), configuration of Kong Gateway needs to be adjusted. By default Kong Gateway
accepts HTTP/2 traffic with TLS on port 443
. And HTTP/1.1 traffic on port 80
. To accept HTTP/2 (which is required by gRPC standard)
traffic without TLS on port 80
, the configuration has to be adjusted.
kubectl set env deployment/kong-gateway -n kong 'KONG_PROXY_LISTEN=0.0.0.0:8000 http2, 0.0.0.0:8443 http2 ssl'
Caveat: Currently, Kong Gateway doesn’t offer simultaneous support of HTTP/1.1 and HTTP/2 without TLS on a single TCP socket. Hence
it’s not possible to connect with HTTP/1.1 protocol, requests will be rejected. For HTTP/2 with TLS everything works seamlessly (connections
are handled transparently). You may configure an alternative HTTP/2 port (e.g. 8080
) if you require HTTP/1.1 traffic on port 80.
Route gRPC traffic
Test the configuration
Use grpcurl
to send a gRPC request through the proxy:
grpcurl -plaintext -d '{"greeting": "Kong"}' -authority example.com $PROXY_IP:80 hello.HelloService.SayHello
The results should look like this:
{
"reply": "hello Kong"
}