Implementing an application that receives gRPC traffic with Kubernetes Service
search cancel

Implementing an application that receives gRPC traffic with Kubernetes Service

book

Article ID: 392683

calendar_today

Updated On: 04-04-2025

Products

VMware Tanzu Kubernetes Grid Management

Issue/Introduction

When sending gRPC traffic to an applications service manually - it arrives successfully.

However when sending through Contour/Envoy Ingress the application does not recognize the traffic.

A workaround is required so that the application receives gRPC traffic as it is an not converted.

Environment

TKGm 2.5.2

Cause

Contour by default configures Envoy to automatically convert gRPC-Web HTTP/1 requests to gRPC over HTTP/2 RPC calls to an upstream service.

There is an open issue for this as found here - 'projectcontour/contour' GitHub. and hence a workaround is required.

This can be done with a Kubernetes Service as per below Resolution.

Resolution

You have attempt Contour Specific solution where service has an added annotation but this does not work as required.

Contour Specific -  where Contour Ingress handles, simply add annotation projectcontour.io/upstream-protocol.h2c: "4317" to the Service similar to below.
As per guided on projectcontour.io here.

Service:
apiVersion: v1
kind: Service
metadata:
  annotations:
    projectcontour.io/upstream-protocol.h2c: "4317"
  name: myworkloadservice
  namespace: open-telemetry-myworkload
spec:
  ports:
  - protocol: TCP
    port: 4317
    targetPort: grpc


Workaround:

Kubernetes Specific - where the annotation from above is removed and the appProtocol: kubernetes.io/h2c is added to the Service similar to below.
 
Service:

apiVersion: v1
kind: Service
metadata:
  name: myworkloadservice
  namespace: open-telemetry-myworkload
spec:
  ports:
  - appProtocol: kubernetes.io/h2c
      name: otlp
      port: 4317
      protocol: TCP
      targetPort: 4317



Note for both above the Ingress below was used:

Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app.kubernetes.io/name: opentelemetry-collector
  name: myworkload
  namespace: open-telemetry-myworkload
spec:
  rules:
  - host: my-workload-mydomain.com
    http:
      paths:
      - backend:
          service:
            name: myworkloadservice
            port:
              number: 4317
        path: /
        pathType: Prefix