Accessing gRPC Services through Container Service for Kubernetes Ingress Controller

gRPC is an open-source high-performance remote procedure call (RPC) communication framework developed by Google. It uses Protocol Buffers as its interface definition language (IDL), and therefore can be used on platforms developed using different languages. It is implemented based on HTTP/2 to provide features such as connection multiplexing, header compression, and throttling. It greatly improves communication efficiency between clients and servers.

In gRPC, a client application can directly call methods on a server application from a different server as if it was calling local methods, making it easier for you to create distributed applications and services. As in many RPC frameworks, gRPC also needs to define a service interface and at the same time specify the methods that can be called remotely with their return types. On the server side, the server implements this interface and runs a gRPC server to handle client requests. On the client side, the client has a stub that provides the same methods as the server.

In this article, we will show you how you can grant access to gRPC services through Alibaba Cloud Container Service for Kubernetes Ingress Controller.

Preparing the Environment

  1. Apply for a Kubernetes cluster on the Container Service console.
  2. Install the grpcurl tool. For more information, click here.
  3. Ensure that the version of the Kubernetes Ingress Controller is 0.15.0–1 or later to support gRPC access.

gRPC Service Example

We define a SayHello service interface, through which clients can call 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 test examples, click here.

Deploy Example Services

Deploy gRPC services.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grpc-service
spec:
replicas: 1
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
kubectl apply -f grpc-service.yml
deployment "grpc-service" created
service "grpc-service" created

Create an SSL certificate.

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=grpc.example.com/O=grpc.example.com"
kubectl create secret tls grpc-secret --key tls.key --cert tls.crt
secret "grpc-secret" created

Configure Ingress routing rules.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: grpc-ingress
annotations:
# Note that gRPC services must be specified as backend services.
nginx.ingress.kubernetes.io/grpc-backend: "true"
spec:
tls:
- hosts:
# Certificate domain name
- grpc.example.com
secretName: grpc-secret
rules:
# gRPC service domain name
- host: grpc.example.com
http:
paths:
- path: /
backend:
serviceName: grpc-service
servicePort: 50051
kubectl apply -f grpc-ingress.yml
ingress "grpc-ingress" created

Test the access to gRPC services. To do this, perform the following steps:

  1. Check all services provided by the gRPC server.
  • grpcurl -insecure grpc.example.com:443 list grpc.reflection.v1alpha.ServerReflection helloworld.Greeter
  1. We can see that the server provides the helloworld.Greeter service.
  2. Check the interface for calling the helloworld.Greeter service.
  • grpcurl -insecure grpc.example.com:443 list helloworld.Greeter SayHello
  1. We can see that the helloworld.Greeter service can be called through the SayHello interface.
  2. Query the description of specific protocol parameters of the SayHello interface.
  • grpcurl -insecure grpc.example.com:443 describe helloworld.Greeter.SayHello helloworld.Greeter.SayHello is a method: { "name": "SayHello", "inputType": ".helloworld.HelloRequest", "outputType": ".helloworld.HelloReply", "options": { } }
  1. Call the SayHello interface and specify the name parameter.
  • grpcurl -insecure -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter.SayHello { "message": "Hello gRPC" } grpcurl -insecure -d '{"name": "world"}' grpc.example.com:443 helloworld.Greeter.SayHello { "message": "Hello world" }

Phased Release of gRPC Services

Alibaba Cloud supports the phased release of gRPC services.

Note: Due to nginx grpc_pass constraints, gRPC services currently do not support the service-weight configuration.

Deploy new-version gRPC services.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: grpc-service-2
spec:
replicas: 1
template:
metadata:
labels:
run: grpc-service-2
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/acs-sample/grpc-server:latest-2
imagePullPolicy: Always
name: grpc-service-2
ports:
- containerPort: 50051
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: grpc-service-2
spec:
ports:
- port: 50051
protocol: TCP
targetPort: 50051
selector:
run: grpc-service-2
sessionAffinity: None
type: NodePort
kubectl apply -f grpc-service-2.yml
deployment "grpc-service-2" created
service "grpc-service-2" created

Modify Ingress routing rules.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: grpc-ingress
annotations:
# Note that gRPC services must be specified as backend services.
nginx.ingress.kubernetes.io/grpc-backend: "true"
# Forward requests that contain foo=bar in the request header to the grpc-service-2 service.
nginx.ingress.kubernetes.io/service-match: 'grpc-service-2: header("foo", "bar")'
spec:
tls:
- hosts:
# Certificate domain name
- grpc.example.com
secretName: grpc-secret
rules:
# gRPC service domain name
- host: grpc.example.com
http:
paths:
- path: /
backend:
serviceName: grpc-service
servicePort: 50051
- path: /
backend:
serviceName: grpc-service-2
servicePort: 50051
kubectl apply -f grpc-ingress-2.yml
ingress "grpc-ingress" configured

Test the access to gRPC services.

## Access requests that do not contain foo=bar in the request header
grpcurl -insecure -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter.SayHello
{
"message": "Hello gRPC"
}
## Access requests that contain foo=bar in the request header
grpcurl -insecure -rpc-header 'foo: bar' -d '{"name": "gRPC"}' grpc.example.com:443 helloworld.Greeter.SayHello
{
"message": "Hello2 gRPC"
}

To learn more about Alibaba Cloud Container Service for Kubernetes, visit https://www.alibabacloud.com/product/kubernetes

Reference:https://www.alibabacloud.com/blog/accessing-grpc-services-through-container-service-for-kubernetes-ingress-controller_594315?spm=a2c41.12451273.0.0

Written by

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store