How to configure Ingress file of Helm chart to deploy a gRPC service?

8/16/2019

I want to deploy a gRPC service to Azure Kubernetes Service. I have already depoyed RESTful services using Helm charts but gRPC service is throwing "connection timed out" error.

I have already tried everything said in the NGINX and HELM documentation but nothing worked. The certificate is self signed. I have tried all permutation and combination of annotations :p

Service.yaml

apiVersion: v1
kind: Service
metadata:
  name: {{ template "fullname" . }}
  labels:
    app: {{ template "fullname" . }}
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    release: "{{ .Release.Name }}"
    heritage: "{{ .Release.Service }}"
spec:
  ports:
  - port: 50051
    protocol: TCP
    targetPort: 50051
    name: grpc
  selector:
    app: {{ template "fullname" . }}
  type: NodePort

ingress.yaml

{{ if .Values.ingress.enabled }}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ template "fullname" . }} 
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/grpc-backend: "true"
    nginx.org/grpc-services: {{ template "fullname" . }}
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  tls:
    secretName: aks-ingress-tls
  rules:
  - http:
      proto: h2
      paths:
      - backend:
          serviceName: {{ template "fullname" . }}
          servicePort: grpc
          proto: h2
        path: /{servicename}-grpc(/|$)(.*)
{{ end }}

Tried this also- still not working-

{{ if .Values.ingress.enabled }}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ template "fullname" . }} 
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  tls:
  - secretName: aks-ingress-tls
  rules:
  - http:
      paths:
      - backend:
          serviceName: {{ template "fullname" . }}
          servicePort: 50051
        path: /servicename-grpc(/|$)(.*)
{{ end }}
-- Aniket Prashar
kubernetes
kubernetes-helm

1 Answer

8/16/2019

It looks like you are missing an annotation on your ingress.

ingress.yaml - snippet

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    # This annotation matters!
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"

According to this snippet from the official Kubernetes nginx ingress documentation:

Backend Protocol

Using backend-protocol annotations is possible to indicate how NGINX should communicate with the backend service. (Replaces secure-backends in older versions) Valid Values: HTTP, HTTPS, GRPC, GRPCS and AJP

By default NGINX uses HTTP.

Example:

nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"

As an aside, there's a chance you might need to specify GRPCS instead of GRPC since it appears you are using SSL.

Another thing to call out is that the docs mention that this annotation replaces 'secure-backends' in older versions, which could be where you found the grpc-backend annotation you are currently using.

-- Bwvolleyball
Source: StackOverflow