Google Remote Procedure Call (gRPC) is developed based on the HTTP/2 protocol and
the Protocol Buffers serialization mechanism. gRPC supports various programming languages,
multiplexing, header compression, and load balancing. Google gRPC greatly improves
the communication efficiency between clients and servers. This topic describes how
to use an Ingress controller provided by Container Service for Kubernetes (ACK) to
access gRPC services.
Background information
gRPC is an open-source, high-performance Remote Procedure Call (RPC) framework provided
by Google. gRPC uses
Protocol Buffers as its Interface Definition Language (IDL). Protocol Buffers are supported by various
programming language. gRPC is developed based on the HTTP/2 protocol and supports
multiplexing, header compression, and load balancing. gRPC greatly improves the communication
efficiency between clients and servers.
In gRPC, a client application can directly call a method on a server application on
a different machine the same as the client application calls a local method. This
makes it easier for you to create distributed applications and services. Similar to
other RPC frameworks, gRPC defines a service interface to specify the methods that
can be called remotely and the return types. On the server side, the server implements
the service interface and runs a gRPC server to process client requests.
Examples of gRPC services
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 Hello World.
Descriptions
In the NGINX Ingress controller, gRPC services run only on HTTPS ports. The default
HTTPS port for gRPC services is port 443. Therefore, you must configure a domain name
and an SSL certificate for the gRPC service in the production environment. In this
example, the domain name grpc.example.com
and a self-signed SSL certificate are used.
In this example, the version of the ACK cluster is 1.20.4-aliyun and the version of
the NGINX Ingress controller is v0.44.0.3-8e83e7dc6-aliyun.
If you already have a gRPC service, proceed to Step 3: Create an Ingress.
Step 1: Apply for an SSL certificate
If you want to use an Ingress to distribute requests to the gRPC service, you must
configure an SSL certificate for the gRPC service and use the TLS protocol to communicate
with the gRPC service.
You can go to SSL Certificates Service console and purchase an SSL certificate. You can also apply for a free SSL certificate on
third-party platforms such as Let's Encrypt.
In this example, a self-signed SSL certificate is generated by using OpenSSL.
- 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
- 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"
- 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 TLS Secret named grpc-secret to the cluster.
You can also add the TLS Secret to the cluster in the ACK console. For more information,
see
Create a Secret.
kubectl create secret tls grpc-secret --key grpc.key --cert grpc.crt
Step 2: Create resources for the gRPC service
Create a backend service that uses the gRPC protocol. In this example, the registry.cn-hangzhou.aliyuncs.com/acs-sample/grpc-server
image is used to create the gRPC service.
- 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
- Run the following command to create a Deployment and a Service for gRPC:
kubectl apply -f grpc.yaml
Expected output:
deployment.apps/grpc-service created
service/grpc-service created
- Run the following command to query the pod:
kubectl get pod
Expected output:
NAME READY STATUS RESTARTS AGE
grpc-service-57884679-2bkbr 1/1 Running 0 98s
The output indicates that the pod
grpc-service-57884679-2bkbr is in the
Running state.
Step 3: Create an Ingress
- Create a file named grpc-ingress.yaml and copy the following content to the file:
Notice
- In the annotation field of the Ingress that is used to deploy the gRPC service, you must add the
nginx.ingress.kubernetes.io/backend-protocol
annotation and set the value to GRPC.
- In this example, the domain name
grpc.example.com
is used. You can modify the domain name as needed.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grpc-ingress
annotations:
# Note: You must specify the gRPC service as the backend service.
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
spec:
# The certificate.
tls:
- hosts:
- grpc.example.com
secretName: grpc-secret
rules:
# The domain name of the gRPC service.
- host: grpc.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
# The gRPC service.
name: grpc-service
port:
number: 50051
- Run the following command to create the Ingress:
kubectl apply -f grpc-ingress.yaml
Expected output:
ingress.networking.k8s.io/grpc-ingress created
Verify the result
After gRPCurl is installed on your on-premises machine, enter grpcurl <domain name>:443 list
to check whether requests are distributed to the backend gRPC service.
In this example, the domain name grpc.example.com
and a self-signed certificate are used. Run the following command to check whether
requests are distributed to the backend gRPC service:
grpcurl -insecure -authority grpc.example.com <ip_address>:443 list
Note ip_address specifies the external IP address of the Service provisioned for the NGINX Ingress
controller. You can run the kubectl get ingress
command to query the IP address.
Expected output:
grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter
The output indicates that requests are distributed to the backend gRPC service.
What to do next
For more information about how to perform canary releases for a gRPC service by using
an Ingress controller, see Use Ingresses to implement canary releases and blue-green releases.
Notice Due to the grpc_pass limit of NGINX, you cannot configure service-weight for gRPC
services.