Google Cloud Serverless Platform Highlights Series — Episode 2: Cloud Run gRPC Triggering

Yu-hua Yang
7 min readMay 19, 2023

Hello Everyone,

In this episode, we will go into the gRPC triggers of Cloud Run, the serverless container platform on Google Cloud. This post is intended to let others understand that HTTP requests are not the only way to invoke Cloud Run endpoints.

Photo by Growtika on Unsplash

What is Cloud Run

Cloud Run is a serverless compute platform that allows you to run stateless containers that are invocable via various triggers. Cloud Run is serverless, which means that you don’t have to worry about managing servers or infrastructure. Cloud Run also scales automatically, so you don’t have to worry about provisioning or managing capacity.

Cloud Run is a great choice for a variety of workloads, including:

  • Web applications: Cloud Run can be used to run web applications that are invocable via various triggers. This makes it a great choice for building APIs, microservices, and other web-based applications.
  • Batch processing: Cloud Run can be used to run batch processing jobs. This makes it a great choice for processing large amounts of data or for running long-running tasks.
  • Event-driven applications: Cloud Run can be used to build event-driven applications. This makes it a great choice for responding to events in real time, such as changes to data or the occurrence of an error.

Cloud Run is a powerful and versatile platform that can be used to build a wide range of applications. If you are looking for a serverless platform that is scalable, reliable, and cost-effective, then Cloud Run is a great option.

Here are some of the key features of Cloud Run:

  • Serverless: Cloud Run is a serverless platform, which means that you don’t have to worry about managing servers or infrastructure.
  • Invocable via triggers: Cloud Run containers are invocable via different types of triggers. This makes it easy to integrate Cloud Run with other services and applications.
  • Scalable: Cloud Run automatically scales your containers up or down based on demand. This ensures that you only pay for the resources that you use.
  • Reliable: Cloud Run is a reliable platform that is designed to run your containers 24/7.
  • Cost-effective: Cloud Run is a cost-effective platform that only charges you for the resources that you use.

If you are looking for a serverless platform that is scalable, reliable, and cost-effective, then Cloud Run is a great option.

gRPC Triggering

Cloud Run is a serverless compute platform that allows you to run stateless containers that are invocable via HTTP requests. gRPC is a high-performance, open-source remote procedure call (RPC) framework that can be used to build efficient, scalable, and reliable microservices.

Cloud Run and gRPC can be used together to build event-driven applications that respond to events in real time. For example, you could use Cloud Run to create a gRPC service that receives events from a database and then triggers other services to take action.

Possible use cases for integrating Cloud Run and gRPC include:

  • Communication between internal microservices. gRPC is a great way to connect microservices that are running on different hosts or in different environments.
  • High loads of data. gRPC uses protocol buffers, which are a binary serialization format that can be up to seven times faster than REST calls. This makes gRPC a good choice for applications that need to handle large amounts of data.
  • Simple service definition. gRPC services can be defined using a simple proto file. This makes it easy to create and deploy gRPC services.
  • Streaming gRPC. gRPC supports streaming, which allows you to send and receive large amounts of data without having to open and close connections. This makes gRPC a good choice for applications that need to stream data in real time.

To integrate Cloud Run and gRPC, you need to do the following:

  1. Configure your service to use HTTP/2. HTTP/2 is the transport method for gRPC streaming. To configure your service to use HTTP/2, you need to add the following annotation to your service’s YAML file:
  2. Define the request messages and responses in a proto file and compile them. To define the request messages and responses in a proto file, you can use the gRPC protocol buffers language. Once you have defined the messages, you can compile them using the gRPC compiler.
  3. Create a gRPC server to handle requests and return responses. The gRPC server is responsible for handling requests and returning responses. To create a gRPC server, you can use any gRPC framework or language.
  4. Create a client that sends requests and handles responses from the gRPC server. The gRPC client is responsible for sending requests and handling responses from the gRPC server. To create a gRPC client, you can use any gRPC framework or language.
  5. Optionally, add authentication. You can optionally add authentication to your gRPC service. To do this, you need to configure your service to use a Google Cloud Identity and Access Management (IAM) service account.
  6. Build and deploy your service. Once you have completed the steps above, you can build and deploy your service. To build your service, you can use the gRPC compiler or the gRPC client library. To deploy your service, you can use the Cloud Run CLI or the Cloud Run API.

Listening for gRPC requests in Cloud Run

This is fairly straightforward, check out the code snippet below

func main() {
log.Printf("grpc-ping: starting server...")
        port := os.Getenv("PORT")
if port == "" {
port = "8080"
log.Printf("Defaulting to port %s", port)
}
listener, err := net.Listen("tcp", ":"+port)
if err != nil {
log.Fatalf("net.Listen: %v", err)
}
grpcServer := grpc.NewServer()
pb.RegisterPingServiceServer(grpcServer, &pingService{})
if err = grpcServer.Serve(listener); err != nil {
log.Fatal(err)
}
}

Opening a gRPC connection

To open a gRPC connection to a service, you need to specify the following:

  • The host domain, which is the URL of the Cloud Run service or the custom domain mapped to that service.
  • The port 443, which is the port expected to be used by gRPC.

Check out the code snippet below

import (
"crypto/tls"
"crypto/x509"
        "google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// NewConn creates a new gRPC connection.
// host should be of the form domain:port, e.g., example.com:443
func NewConn(host string, insecure bool) (*grpc.ClientConn, error) {
var opts []grpc.DialOption
if host != "" {
opts = append(opts, grpc.WithAuthority(host))
}
if insecure {
opts = append(opts, grpc.WithInsecure())
} else {
// Note: On the Windows platform, use of x509.SystemCertPool() requires
// go version 1.18 or higher.
systemRoots, err := x509.SystemCertPool()
if err != nil {
return nil, err
}
cred := credentials.NewTLS(&tls.Config{
RootCAs: systemRoots,
})
opts = append(opts, grpc.WithTransportCredentials(cred))
}
return grpc.Dial(host, opts...)
}

Sending gRPC requests without auth

When sending requests without any authentication, you can infer from the code snippet below:

import (
"context"
"time"
        pb "github.com/GoogleCloudPlatform/golang-samples/run/grpc-ping/pkg/api/v1"
"google.golang.org/grpc"
)
// pingRequest sends a new gRPC ping request to the server configured in the connection.
func pingRequest(conn *grpc.ClientConn, p *pb.Request) (*pb.Response, error) {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
client := pb.NewPingServiceClient(conn)
return client.Send(ctx, p)
}

Sending gRPC requests with Auth

The following code snippet shows how to use authentication between services when the calling service has invoker permission to the receiving service. Notice that the code creates an authorization header that has the proper identity token. This is required. The required permissions and the authorization header are described in detail in the service-to-service authentication documentation.

import (
"context"
"fmt"
"time"
        "google.golang.org/api/idtoken"
"google.golang.org/grpc"
grpcMetadata "google.golang.org/grpc/metadata"
pb "github.com/GoogleCloudPlatform/golang-samples/run/grpc-ping/pkg/api/v1"
)
// pingRequestWithAuth mints a new Identity Token for each request.
// This token has a 1 hour expiry and should be reused.
// audience must be the auto-assigned URL of a Cloud Run service or HTTP Cloud Function without port number.
func pingRequestWithAuth(conn *grpc.ClientConn, p *pb.Request, audience string) (*pb.Response, error) {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// Create an identity token.
// With a global TokenSource tokens would be reused and auto-refreshed at need.
// A given TokenSource is specific to the audience.
tokenSource, err := idtoken.NewTokenSource(ctx, audience)
if err != nil {
return nil, fmt.Errorf("idtoken.NewTokenSource: %v", err)
}
token, err := tokenSource.Token()
if err != nil {
return nil, fmt.Errorf("TokenSource.Token: %v", err)
}
// Add token to gRPC Request.
ctx = grpcMetadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+token.AccessToken)
// Send the request.
client := pb.NewPingServiceClient(conn)
return client.Send(ctx, p)
}

Cloud Run is a serverless compute platform that allows you to run stateless containers that are invocable via HTTP requests. However, Cloud Run is not limited to just HTTP requests. You can also use gRPC triggers to invoke your Cloud Run services.

gRPC is a high-performance, open-source remote procedure call (RPC) framework that can be used to build efficient, scalable, and reliable microservices. gRPC uses protocol buffers, which are a binary serialization format that can be up to seven times faster than REST calls.

By using gRPC triggers, you can take advantage of the performance and reliability benefits of gRPC while still using the scalability and flexibility of Cloud Run.

Here are some of the benefits of using gRPC triggers with Cloud Run:

  • Performance: gRPC is a high-performance RPC framework that can be up to seven times faster than REST calls. This can improve the performance of your applications.
  • Reliability: gRPC is a reliable RPC framework that can help to ensure that your applications are reliable.
  • Scalability: Cloud Run is a scalable compute platform that can help you to scale your applications.
  • Flexibility: Cloud Run is a flexible compute platform that can help you to deploy your applications in a variety of environments.

If you are looking for a high-performance, reliable, scalable, and flexible way to invoke your Cloud Run services, then you should consider using gRPC triggers.

--

--