gRPC is ideal for communication between microservices. gRPC has performance advantages through the Protobuf message structure. gRPC is intended for internal systems due to its limited low browser support. Therefore very suitable to use within Kubernetes. It’s the recommended way from Microsoft to build RPC services using .NET.
.NET Core supports gRPC services with a special project type in Visual Studio 2022. Since .NET 6 there are many performance improvements and other features.
Running a gRPC .NET Core 6 service in Kubernetes, which can be accessed using Traefik needs some specific configuration.
The problem
After creating a Helm chart and configuring the values file with the obvious configuration and installing the chart, you are able to access the gRPC service. You will get an exception: 500 Internal Server Error. Despite the error, the pod is actually working. When you execute a port-forward to the Service or Pod, you will be able to call the gRPC service from your local machine.
So it has to do with ingress. Traefik is not able to pass the request because of TLS requirements that gRPC requires. So we have to configure Traefik to make sure that the calls after Traefik are using HTTP.
I’m used to configure Ingress using annotations on the Ingress. But the catch this time is that the annotation is needed on the Service.
The solution
Make sure the service has the following annotation:
traefik.ingress.kubernetes.io/service.serversscheme: h2c
The yaml for the service and ingress looks like this:
apiVersion: v1
kind: Service
metadata:
name: grpcdemo-service
annotations:
traefik.ingress.kubernetes.io/service.serversscheme: h2c
spec:
ports:
- port: 80
selector:
app.kubernetes.io/name: grpcdemo
app.kubernetes.io/instance: grpcdemo
type: ClusterIP
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grpcdemo-ingress
annotations:
ingress.kubernetes.io/protocol: https
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- grpcdemo.mydomain.com
secretName: grpcdemo-tls
rules:
- host: grpcdemo.mydomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grpcdemo-service
port:
number: 80