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