All Products
Search
Document Center

Container Service for Kubernetes:Deploy gRPC services on the backend of the NGINX Ingress controller

Last Updated:Aug 21, 2024

If your service uses a distributed architecture, you can use the Google Remote Procedure Call (gRPC) protocol to improve the communication efficiency between clients and servers. When you deploy a service that uses the gRPC protocol on the backend of the NGINX Ingress controller, you must configure the Ingress resource accordingly.

Background information

gRPC is developed based on the HTTP/2 protocol and the Protocol Buffers (ProtoBuf) serialization protocol. It is an open-source Remote Procedure Call (RPC) framework provided by Google and works on platforms developed by various programming languages. Due to its efficiency, flexibility, and support for multiple programming languages, gRPC is suitable for distributed systems and environments in which microservices are deployed, such as inter-service calls, communication between Internet of Things (IoT) devices, and remote API services of complex data structures.

An example of a gRPC service

Use the following code to define a gRPC service. Clients can call the SAYHello interface of the helloworld.Greeter service.

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

For more information about the source code of the gRPC service, see grpc-go.

Prerequisites

Step 1: Save an SSL certificate as a Secret in the cluster

In the NGINX Ingress controller, gRPC services run only on HTTPS ports. The default port for gRPC services is port 443. Therefore, you must configure an SSL certificate as a Secret in the cluster.

(Optional) Generate a self-signed certificate

If you do not have a certificate, you can generate a self-signed certificate by performing the following steps. In this example, grpc.example.com is used as the domain name of the certificate.

Important

Due to the lack of reliable CA authentication, self-signed certificates are not trusted by default in browsers and clients, which results in security warnings when customers access the service. The self-signed certificate generated in this topic is for reference only and should not be used in a production environment.

  1. Create and copy the following content to the /tmp/openssl.cnf file:

    [ req ]
    #default_bits           = 2048
    #default_md             = sha256
    #default_keyfile        = privkey.pem
    distinguished_name      = req_distinguished_name
    attributes              = req_attributes
    req_extensions          = v3_req
    
    [ req_distinguished_name ]
    countryName                     = Country Name (2 letter code)
    countryName_min                 = 2
    countryName_max                 = 2
    stateOrProvinceName             = State or Province Name (full name)
    localityName                    = Locality Name (eg, city)
    0.organizationName              = Organization Name (eg, company)
    organizationalUnitName          = Organizational Unit Name (eg, section)
    commonName                      = Common Name (eg, fully qualified host name)
    commonName_max                  = 64
    emailAddress                    = Email Address
    emailAddress_max                = 64
    
    [ req_attributes ]
    challengePassword               = A challenge password
    challengePassword_min           = 4
    challengePassword_max           = 20
    
    [v3_req]
    # Extensions to add to a certificate request
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName = @alt_names
    
    [alt_names]
    DNS.1 = grpc.example.com
  2. Run the following command to generate a certificate signing request:

    openssl req -new -nodes -keyout grpc.key -out grpc.csr -config /tmp/openssl.cnf -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=AlibabaCloud/OU=ContainerService/CN=grpc.example.com"
  3. Run the following command to sign the certificate:

    openssl x509 -req -days 3650 -in grpc.csr -signkey grpc.key -out grpc.crt -extensions v3_req -extfile /tmp/openssl.cnf

    After the command is executed, the certificate file grpc.crt and the private key file grpc.key are generated.

Run the following command to add the certificate to the cluster through grpc-secret:

kubectl create secret tls grpc-secret --key grpc.key --cert grpc.crt # Replace grpc.key with your certificate file and grpc.crt with your private key file

Step 2: Create a gRPC service

  1. Create a file named grpc.yaml and copy the following content to the file:

    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
  2. Run the following command to create the gRPC service:

    kubectl apply -f grpc.yaml

    Expected output:

    deployment.apps/grpc-service created
    service/grpc-service created

Step 3: Create an Ingress

  1. Create a file named grpc-ingress.yaml and copy the following content to the file:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: grpc-ingress
      annotations:
        # Must specify that the backend service is a gRPC service
        nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
    spec:
      # Specify the SSL certificate saved through Secret
      tls:
      - hosts:
        - grpc.example.com
        secretName: grpc-secret
      rules:
      - host: grpc.example.com # gRPC service domain name, replace with your domain name
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                # gRPC service
                name: grpc-service
                port:
                  number: 50051
    Important

    Due to the grpc_pass limit of NGINX, you cannot configure service-weight for gRPC services.

  2. Run the following command to create the Ingress:

    kubectl apply -f grpc-ingress.yaml

    Expected output:

    ingress.networking.k8s.io/grpc-ingress created

Step 4: Verify the result

  1. Run the following command to view the Ingress information:

    kubectl get ingress

    Expected output:

    NAME           CLASS   HOSTS              ADDRESS         PORTS     AGE
    grpc-ingress   nginx   grpc.example.com   139.196.*****   80, 443   3m51s

    Record the IP address in the ADDRESS column.

  2. Use grpcurl to connect to the service.

    grpcurl -insecure -authority grpc.example.com <IP_ADDRESS>:443 list # Replace <IP_ADDRESS> with the IP address recorded in the previous step

    The output indicates that the Ingress distributes requests to the backend gRPC service:

    grpc.reflection.v1alpha.ServerReflection
    helloworld.Greeter

References