All Products
Search
Document Center

Container Service for Kubernetes:Configure a gRPC service for Nginx Ingress

Last Updated:Mar 26, 2026

To expose a gRPC application in an ACK cluster to external clients, configure an NGINX Ingress with the nginx.ingress.kubernetes.io/backend-protocol: "GRPC" annotation. Because gRPC runs over HTTP/2, TLS is required on the Ingress.

Prerequisites

Before you begin, ensure that you have:

  • An ACK cluster with the NGINX Ingress Controller installed

  • kubectl configured to connect to the cluster. See Connect to an ACK cluster via kubectl

  • A domain name for gRPC traffic (this tutorial uses grpc.example.com)

  • A TLS certificate for that domain (purchased from a Certificate Authority (CA) or self-signed for testing)

How it works

When a client sends a gRPC request to the Ingress endpoint, NGINX:

  1. Terminates TLS and decrypts the traffic.

  2. Forwards the decrypted gRPC traffic (over HTTP/2) to the backend pod on port 50051.

  3. Returns the gRPC response to the client.

The key configuration is the backend-protocol: "GRPC" annotation, which tells the Ingress controller to use gRPC instead of HTTP when proxying to the backend:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: grpc-ingress
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"  # Proxy traffic as gRPC (HTTP/2)
spec:
  tls:
  - hosts:
    - grpc.example.com          # Replace with your domain
    secretName: nginx-ingress-tls
  rules:
  - host: grpc.example.com      # Replace with your domain
  # ...

Step 1: Deploy a sample gRPC application

Console

  1. On the Clusters page, click the name of your cluster. In the left navigation pane, click Workloads > Deployments.

  2. On the Deployments page, click Create from YAML, copy the following content to the template editor, and then click Create.

    Sample application YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: grpc-service
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: grpc-service
      template:
        metadata:
          labels:
            run: grpc-service
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/grpc-server:latest
            imagePullPolicy: Always
            name: grpc-service
            ports:
            - containerPort: 50051
              protocol: TCP
          restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: grpc-service
    spec:
      ports:
      - port: 50051
        protocol: TCP
        targetPort: 50051
      selector:
        run: grpc-service
      sessionAffinity: None
      type: NodePort
  3. In the pop-up window, find the target stateless application, click View , and verify that the Pod is Running

kubectl

  1. Create a file named grpc.yaml with the following content:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: grpc-service
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: grpc-service
      template:
        metadata:
          labels:
            run: grpc-service
        spec:
          containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs-sample/grpc-server:latest
            imagePullPolicy: Always
            name: grpc-service
            ports:
            - containerPort: 50051
              protocol: TCP
          restartPolicy: Always
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: grpc-service
    spec:
      ports:
      - port: 50051
        protocol: TCP
        targetPort: 50051
      selector:
        run: grpc-service
      type: NodePort
  2. Deploy the application:

    kubectl apply -f grpc.yaml

The sample application implements the following proto interface. The Greeter service exposes a single unary RPC method, SayHello:

gRPC sample application interface definition

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

For more information, see gRPC service examples.

Step 2: Store the TLS certificate as a Secret

gRPC runs over HTTP/2, which requires TLS on the Ingress. Store your certificate and private key in a Kubernetes Secret so the Ingress controller can use them.

  1. Get a TLS certificate for your domain:

  2. Create a Secret named nginx-ingress-tls to store the certificate and private key.

    Console

    1. Log on to the ACK console. In the left navigation pane, click Clusters.

    2. On the Clusters page, click the name of your cluster. In the left navigation pane, click Configurations > Secrets.

    3. On the Secrets page, select the default namespace and click Create in the upper-left corner. In the panel that appears, configure the new Secret and click OK.

      Namenginx-ingress-tls
      TypeTLS Certificate

      Under + Add, enter the certificate and private key:

      • Certificates: Full content of the certificate file (.crt or .pem).

      • Key: Full content of the private key file (.key).

    kubectl

    Replace <PUBLIC_CERT> and <PRIVATE_KEY> with the paths to your certificate and private key files:

    # --cert: certificate file (.crt or .pem)
    # --key:  private key file (.key)
    kubectl create secret tls nginx-ingress-tls --cert <PUBLIC_CERT> --key <PRIVATE_KEY>

Step 3: Configure the Ingress to expose the service

  1. Log on to the ACK console and click the cluster name. In the left navigation pane, choose Add-ons.

  2. Search for NGINX Ingress Controller and click Install or Upgrade on the add-on card.

  3. Configure the Ingress to route gRPC traffic to the backend service.

    Console

    1. In the left navigation pane, choose Network > Ingresses. Select the default namespace and click Create Ingress.

    2. Configure the Ingress with the following settings, then click OK:

      Gateway TypeNginx Ingress
      Namegrpc-ingress
      Domain Namegrpc.example.com

      Under Mappings, set:

      Mappings/
      Match RulePrefix (Prefix-based match)
      Servicegrpc-service
      Port50051

      Under TLS settings, enable the option and set:

      Domain Namegrpc.example.com
      Secretsnginx-ingress-tls

      Under Annotations, add:

      nginx.ingress.kubernetes.io/backend-protocolGRPC
    3. On the Ingresses page, find the new Ingress and note its Endpoint.

      It takes about 10 seconds for the NGINX Ingress to take effect. If the endpoint is not shown yet, wait and click refresh. If it still doesn't appear, click the Ingress name and check the Events tab to troubleshoot issues.

    kubectl

    1. Create a file named grpc-ingress.yaml:

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: grpc-ingress
        annotations:
          # Proxy traffic as gRPC (HTTP/2) to the backend
          nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
      spec:
        ingressClassName: nginx
        tls:
        - hosts:
          - grpc.example.com             # Replace with your domain
          secretName: nginx-ingress-tls  # The Secret created in the previous step
        rules:
        - host: grpc.example.com         # Replace with your domain
          http:
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: grpc-service
                  port:
                    number: 50051
    2. Apply the Ingress:

      kubectl apply -f grpc-ingress.yaml
    3. Get the Endpoint address. If no address is returned, wait 10 seconds and retry:

      ADDRESS=$(kubectl get ingress grpc-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
      echo $ADDRESS

Step 4: Verify the setup

  1. Add an entry to your local hosts file to resolve the sample domain to the Ingress IP address: Append the following line, replacing <ADDRESS> with the actual IP:

    • macOS/Linux: Edit /etc/hosts with sudo vi /etc/hosts

    • Windows: Open C:\Windows\System32\drivers\etc\hosts in Notepad (run as administrator)

    <ADDRESS> grpc.example.com
  2. Install grpcurl, then call the SayHello method:

    grpcurl -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter/SayHello

    Expected response:

    {
      "message": "Hello gRPC"
    }

Limitations

Weight-based routing is not supported for gRPC. Due to gRPC's long-lived connections, NGINX Ingress does not support service-weight routing (service-weight) for gRPC backends.

FAQ

How do I generate a self-signed certificate for testing?

Use openssl to generate a self-signed certificate and private key valid for 365 days:

openssl req -x509 -newkey rsa:2048 -keyout grpc.key -out grpc.crt -days 365 -nodes \
  -subj "/CN=grpc.example.com" \
  -addext "subjectAltName=DNS:grpc.example.com"
Important

Self-signed certificates are not trusted by browsers or gRPC clients by default. Do not use self-signed certificates in production.

What is the difference between SSL and TLS?

Transport Layer Security (TLS) is the modern replacement for the older, deprecated Secure Sockets Layer (SSL) protocol. In practice, "SSL certificate" is used colloquially to mean a TLS certificate.

What's next