Say Hello to Serverless Containers with Cloud Run

Stephanie Wong
The Startup

--

Serverless technology has been turning heads for its ability to give developers back what they love: It lets them focus on code while the platform takes care of the infrastructure and auto-scaling (even back down to zero so their wallets thank them). What’s all the fuss about? To fully understand its value, let’s take a trip down memory lane at Google…

A brief history of serverless

We’ve seen waves in serverless tech at Google, starting with the tried and true App Engine released in 2008. App Engine is a fully managed, serverless platform for developing and hosting web applications at scale. You can choose from several popular languages, libraries, and frameworks to develop your apps, then let App Engine take care of provisioning servers and scaling your app instances based on demand. It lets you host a traditional application — if you need multiple pieces of functionality in a single place and want to deploy your entire app, look to App Engine. On the other hand, if you don’t need a stateful application and prefer to invoke events using functions, Google Cloud Functions is a great choice and the next release in GCP’s serverless portfolio.

In 2017, Google released Cloud Functions, an event-driven serverless platform. As opposed to deploying an application made up of one or more services, you deploy code as functions. They can be called via HTTP requests, or set to trigger based on background events. This makes them great for running code that responds to real-time events, or for serving requests without containers.

There has now been a clear trend away from monolithic and towards microservices architectures because of the scalability, flexibility, and productivity it gives developers. And with it, developers have been looking for serverless tools that go beyond simple functions and support containerized environments. They’ve rallied for a flourishing ecosystem around microservices infrastructure management (like serverless) simply because microservices have introduced more complexity. Microservices logic requires tying together APIs, services, domain logic, data models, and data access. Rolling out changes often requires the entire system to be tested and redeployed.

The next step: Cloud Run

As Google Cloud anticipated these woes, they quickly released the latest of their serverless offerings, which now supports containerized workloads. Cloud Run was released at Google Cloud Next 2019, and is a managed compute platform that enables you to run stateless containers that are invocable via web requests or Cloud Pub/Sub events. It abstracts away all infrastructure management, so you can focus on what matters most — building great applications. Cloud Run is built from Knative, letting you choose to run your containers either fully managed with Cloud Run, or in your Google Kubernetes Engine (GKE) cluster with Cloud Run for Anthos.

When to use Cloud Run

Unlike Cloud Functions, Cloud Run lets you package your code in a stateless Docker image, then invoke it via HTTP requests versus event-driven functions as the main unit of deployment. And unlike App Engine, it supports any number of programming languages, libraries, or system binaries. If you already package code in Docker containers or are running a Kubernetes cluster, consider Cloud Run or Knative for your serverless workloads.

Cloud Run comes in two flavors: fully managed Cloud Run, and Cloud Run for Anthos and deployed on GKE.

Fully managed Cloud Run gives you the best of serverless and container technology: velocity and portability. You have usage-based pricing, auto-scaling, and no infrastructure management. You simply package your code into a container image, upload the container image to Container Registry, and then deploy the container image to Cloud Run.

Cloud Run for Anthos deployed on GKE lets you run containers on GKE as serverless code. Instead of fully managed infrastructure, you can deploy your code on an existing GKE cluster that you’ve created. This is perfect if are already running a Kubernetes cluster and want to configure hardware requirements for your serverless containers.

BONUS: Port anywhere

As I mentioned, Cloud Run is built using Knative, an open source project to run serverless workloads that Google launched in 2018. It’s an open API and runtime environment that lets you run your serverless workloads anywhere you choose — on GCP, on your GKE cluster, or on your own self-managed Kubernetes cluster. This is worth restating: You can run your containers on any Kubernetes cluster running Knative! With this portability, you can easily run serverless workloads with tools you already use to package and run containers on Google Cloud.

Deploy Open Office as a stateless, serverless container!

Let’s walk through a tutorial of the demo I showed above. That way, you can get a feel for how portable and easy to use Cloud Run and Knative really are:

We’re going to deploy Open Office via two flavors of Cloud Run: fully managed Cloud Run and Cloud Run for Anthos. Then we’ll deploy the same container image on IBM Cloud, running a Kubernetes Cluster with Knative enabled.

Set up

  1. Authorize the gcloud command-line tool to access your project:
gcloud auth login

2. Configure your project for the gcloud tool, where [PROJECT_ID] is your GCP project ID:

gcloud config set project [PROJECT_ID]

Preparing source files

You’ll need some sample source code to build. Here, you’ll pull the source code and Dockerfile from a Github repository.

  1. Git clone https://github.com/as-a-service/pdf.git

You can see you get source code (to-pdf.py) and a Dockerfile.

2. Navigate to pdf/

3. Run the following command to make quickstart.sh executable:

chmod +x to-pdf.py

Build using Dockerfile

Cloud Build allows you to build a Docker image using a Dockerfile. Cloud Build is a service that executes your builds on Google Cloud Platform infrastructure. Cloud Build can import source code from Google Cloud Storage, Cloud Source Repositories, GitHub, or Bitbucket, execute a build to your specifications, and produce artifacts like Docker containers or Java archives. You don’t need a separate build config file.

  1. First, enable the Container Registry, Cloud Build, and Cloud Run APIs:
gcloud services enable containerregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com

2. Update installed gcloud components:

gcloud components update

3. Install the gcloud beta components:

gcloud components install beta

4. Install the kubectl command-line tool:

gcloud components update

5. Run the following command from the directory containing to-pdf.py and the Dockerfile, where [PROJECT_ID] is your GCP project ID:

gcloud builds submit --tag gcr.io/[PROJECT_ID]/pdf-service .

Note: Don’t miss the “.” at the end of the above command. The “.” specifies that the source code is in the current working directory at build time.

You should get this output:

Double Check Container Registry console for container image title pdf-service:

Deploy the container image on Cloud Run

Next, we’re going to deploy our container image on our first flavor: fully managed Cloud Run.

  1. Deploy the container image pdf-service on Cloud Run:
gcloud beta run deploy --image gcr.io/[PROJECT ID]/pdf-service

2. Select option 1 to deploy on fully managed Cloud Run.

3. Select a region.

4. Type in the service name (pdf-service).

5. When it asks you if you want to allow unauthenticated invocations, select yes.

You should get this output:

6. Click on the URL or go to the Cloud Run console and click the new deployment name to find the URL. Voila! Your serverless container image is running on a stable and secure HTTPS endpoint! You can now upload a test Word document and convert it to a pdf.

Deploy Container image on Cloud Run for Anthos

Now let’s deploy the same container image on Cloud Run for Anthos deployed on GKE.

First we need a GKE cluster with these minimum settings:

  • Cloud Run on GKE enabled
  • Kubernetes version: see recommended versions
  • Nodes with 4 vCPU
  • Scopes to access cloud-platform, write to logging, write to monitoring
  1. First, enable the Kubernetes Engine API:
gcloud services enable container.googleapis.com

2. Set the desired zone for the new cluster. You can use any zone where GKE is supported:

gcloud config set compute/zone ZONE

3. Create a GKE cluster with the following command:

gcloud beta container clusters create run-cluster1 \--addons=HorizontalPodAutoscaling,HttpLoadBalancing,Istio,CloudRun \--machine-type=n1-standard-4 \--cluster-version=latest --zone=us-central1-a \--enable-stackdriver-kubernetes \--scopes cloud-platform

Important: Running a GKE configuration like the one described in this page can be costly. GKE is billed differently than Cloud Run, so you will be billed for each node in your cluster, even if you have no services deployed to them. To avoid charges, you should delete your cluster or scale the number of the nodes in the cluster to zero if you are not using it.

Services deployed on Cloud Run on GKE aren’t given a domain name like fully managed Cloud Run, so we need to map the GKE cluster’s ingress gateway external IP address to a custom domain, or a free DNS wildcard site like xip.io.

4. Export the IP of the ingress gateway of your cluster:

export GATEWAY_IP=”$(kubectl get svc istio-ingressgateway \--namespace istio-system \--output ‘jsonpath={.status.loadBalancer.ingress[0].ip}’)”

5. Copy the external IP:

echo $GATEWAY_IP

6. Then map the external IP to the free DNS wildcard site. Replace the [EXTERNAL_IP] with the IP address you just copied.

kubectl patch configmap config-domain --namespace knative-serving --patch \‘{“data”: {“example.com”: null, “[EXTERNAL-IP].xip.io”: “”}}’

7. Now deploy the image on Cloud Run on your GKE cluster. Replace [PROJECT ID] with your project ID.

gcloud beta run deploy --image gcr.io/[PROJECT ID]/pdf-service --cluster run-cluster1

8. Select option 2 to deploy the image on Cloud Run on GKE when prompted, then select the region.

9. Type the service name when prompted (pdf-service).

You should get the following output:

Click on the URL or go to the Cloud Run console and click the new deployment name to find the URL. Bam! That exact same container image is running on a stable endpoint now on a GKE cluster, and it was deployed as serverless code!

We now have our two versions of Cloud Run deployments live:

Port to IBM Cloud using Knative

Using Knative I was able to easily run the same container image as serverless code and deploy it to another Kubernetes Cluster I had running in IBM Cloud. Here are the general steps I did to be able to do this:

  1. Create a Kubernetes Cluster in another cloud provider like IBM Cloud.

2. There you can enable the Knative add-on.

3. Now head back to your Google Cloud console. In your GCP Container Registry, enable the pdf-service container image to be publicly available.

4. In the Google Cloud Shell home directory, create a yaml file named service.yaml with the following content:

apiVersion: serving.knative.dev/v1alpha1kind: Servicemetadata:name: pdfspec:runLatest:configuration:revisionTemplate:spec:container:image: [CONTAINER IMAGE URL]

Note: Replace [CONTAINER IMAGE URL] with your public URL of your container image. Ex: gcr.io/vpc-demo-225319/pdf-service

6. In the Cloud Shell, download the IBM SDK and login using these steps.

7. Run the following command to point to your running cluster in IBM Cloud. Replace [CLUSTER ID].

ibmcloud ks cluster-config --cluster [CLUSTER ID]

8. You might get a warning that the command is using deprecated behavior, but it should give you a confirmation that you downloaded the kubeconfig file successfully.

Now run the export command given to you.

9. Confirm you’ve set kubeconfig to your IBM cluster by running:

kubectl get nodes

You should see the IP addresses of the nodes running in IBM.

10. Run the following to apply service.yaml to the IBM cluster:

kubectl apply -f service.yaml

11. Enter the following to view the container image URL endpoint:

Kubectl get ksvc

The result should look like this:

12. Copy the domain in your browser and you should see the service is now running on the IBM Kubernetes cluster!

Congratulations!

You’ve just deployed a serverless container running a legacy app on fully hosted Cloud Run, Cloud Run for Anthos, and on IBM Cloud using Knative! Cloud Run coupled with Knative gives you the flexibility to run serverless, the agility of containers, and portability across environments. Other advantages include fast scale up, fast scale down, saving you from cost when the service is not running, and the ability to use any binary or language because of the versatility of containers. The biggest advantage in my opinion: you have a consistent experience wherever you prefer, full managed, for Anthos/GKE, or on your own Kubernetes cluster. It’s another foot forward in an effort to give precious time back to coding versus infrastructure management, all the while environments modernize and decouple. If that doesn’t get you up in the morning, I don’t know what will!

What to do next?

  1. Learn more about Cloud Run!
  2. Subscribe to the GCP Youtube channel where you’ll find a lot more on serverless and how to deploy this demo.
  3. Follow me on Twitter to stay up to date on the latest on GCP.
  4. And check out Google’s Cloud events near you. They’ve even hosted Cloud Run clubs where you actually get to run a 5k, learn about Cloud Run, do hands-on labs, and meet Googlers and other community members!

--

--

Stephanie Wong
The Startup

Google Cloud Developer Advocate and producer of awesome online content. Creator of the series, GCP Networking End-to-End; host of Google’s Next onAir. @swongful