Use gRPC services
Following this guide, it is possible to release an already existent gRPC service to Kubernetes using the Mia-Platform Console.
gRPC is a modern and open source high performance Remote Procedure Call (RPC) framework incubating by CNCF. The site of gRPC contains all the documentation on what it is, why it should be used and how to start to create your first gRPC service (SDK are available in multiple language).
Prerequisite:
- a Console project with at least one environment (follow this guide if you want to create it)
- a service using gRPC. In the following use case we use as example YAGES (yet another gRPC echo server)
- a Kubernetes cluster with installed Traefik ingress (the default ingress used in Mia-Platform PaaS)
Let's start!
Add the service
In Console, go to the Microservices section and create a new service from Docker image. Insert grpc-service
as name and the docker image of the selected gRPC service.
Once created, modify this information:
- API documentation path: remove the default path to avoid to fetch the documentation (since the fetch use http API);
- remove the probes path from the Runtime section (both Readiness and Liveness)
- remove all the Environment Variables except the
HTTP_PORT
env var, and set as value the port exposed by the service
Probes in gRPC can use this tool if you use Kubernetes at version less than 1.24, otherwise it is possible to add the newly supported specific probe. Those configuration cannot be done with Console at the moment, but if necessary you can always transform the service to advanced and set it manually.
Use inside the cluster
Deploy
Go to the Deploy section and deploy the branch just edited. Once the deploy is successfull, verify that all pods are running (including the grpc-service
) from the Runtime section of the Console.
Test with port-forward
This step is possible only if your user has the permission on the Kubernetes cluster to port-forward in the specified namespace.
Prerequisite to this step are kubectl and grpcurl installed.
Copy the following command and change MY_NAMESPACE
with the namespace where you have deployed the project.
kubectl -n MY_NAMESPACE port-forward svc/grpc-service 9000:80
Once the grpc-service is exposed locally, you can contact it with the grpcurl
grpcurl --plaintext localhost:9000 yages.Echo.Ping
and you should obtain the response
{
"text": "pong"
}
From outside the cluster
With Envoy as Api Gateway and Traefik as ingress
Configure envoy
To expose the server with the Envoy API Gateway, you can create an endpoint on /
which point to the grpc-service
microservice, and pick the container port that binds the gRPC controller.
Make sure that the Use downstream protocol flag (in the Endpoint settings Advanced tab) is flagged, this ensures that the HTTP
protocol version is inferred from the incoming request, allowing the protocol HTTP/2 to be used effectively.
When using Envoy, the endpoint accepts also requests with HTTP/2 protocol, allowing to use gRPC clients.
It is possible to expose a specific endpoint pointing to the correct microservice.
To contact the API, the client must have the .proto
file loaded. Otherwise, the client try to contact the reflection method of the server, but it use a specific endpoint.
To expose an endpoint, remember that it is created from the method called. So, if we call the method yages.Echo.Ping
, the path colled will be /yages.Echo/Ping
. It is possible from the Console to expose an endpoint with basePath set to /yages.Echo
and the rewritePath to /yages.Echo
, and it works.
It is now possible to test it using the port forward configuration method as showed in the test with port-forward section.
You should only change the port-forward command (if your API Gateway is created from Mia-Platform marketplace and the name of the service is api-gateway
):
kubectl -n MY_NAMESPACE port-forward svc/api-gateway 8080:80
Configure Traefik
To expose a gRPC endpoint from the cluster with traefik, it is necessary to add the scheme h2c to the IngressRoute resource.
In the following example, the match is to the host MY_HOST
. Under the services field, note that the scheme is set to h2c. This is the configuration required to make the gRPC call works.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: default-ingress
labels:
app.kubernetes.io/instance: "ingress-controller"
spec:
entryPoints:
- websecure
routes:
- match: Host(`MY_HOST`)
middlewares:
- name: "ingress-controller-hsts-headers"
namespace: mia-platform
kind: Rule
services:
- name: api-gateway
port: 8080
scheme: h2c
tls:
options:
name: ingress-controller-intermediate-tls
namespace: mia-platform
secretName: default-cert
It is possible to test the connection (sobstitute MY_HOST with your host, remember to add the default port 443 if not already set a port in MY_HOST):
grpcurl MY_HOST yages.Echo.Ping
The scheme h2c works with envoy also with rest API