Deploying a container to the Cloud using Google Cloud Platform and Kubernetes Engine

Rowan Laurence
Beyond
Published in
4 min readJan 23, 2018

Part eight of a series

What’s Kubernetes?

Kubernetes is a way of orchestrating containers in the Cloud, enabling you to do things like auto-scale, fast deploys and manage running versions of containers. You simply create a container and upload it to a container repository. In this example I used Google’s Container Registry, it’s really simple to use and works brilliantly with their Kubernetes implementation.

By the end of this section we are going to have:

  1. A public IP address (that you can point your domain to)
  2. A load balancer configured to accept traffic, assigned to that IP address
  3. A pod containing one Kubernetes container running our Play application

To the cloud!

Install gcloud tools, download the package, and put it somewhere useful
https://cloud.google.com/sdk/gcloud/

Sign up for an account at cloud.google.com — they will give you $300 worth of credit!
https://cloud.google.com/

You need to upload your container somewhere….
Wait, Google thought of this and gave you a whole system to do so?

Read this:
https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app
You’ll need to create a new project, enable Kubernetes Engine on your account, and enable Container Registry.

From the command line at the root of your project folder.

docker build -t [HOSTNAME]/[PROJECT-ID]/[IMAGE][:TAG|@DIGEST] .

Where HOSTNAME is the hostname where you want to upload to for container registry (e.g. us.gcr.io,) and PROJECT-ID is your project id (this can be found on your Google Cloud Platform Dashboard).
https://cloud.google.com/container-registry/docs/

For instance:

docker build -t us.gcr.io/sf-xmas-123/sf-xmas/app:$(git log -1 — pretty=%H) .

Here I’ve tagged my image with the latest commit hash as it makes tracking changes effortless.

Get the ID of the newly build Docker image:

docker images -q -f reference=*:$(git log -1 — pretty=%H)

Now do the following command to push the container registry:

gcloud docker — push [HOSTNAME]/[PROJECT-ID]/sf-xmas/app:$(git log -1 — pretty=%H)

This will push your container to the internet. Think of this as a git version of your compiled server, not just your compiled application.

*Very important definition, it’s everything in one, not just your app, your install of java, it’s everything as one and this makes life so good!!

Your whole application, it’s runtime, it’s logic, it’s drivers; EVERYTHING as one package — this is epic for scaling by deploying quickly.

How do I get this running?

In Cloud Shell or from gcloud tools you need to follow some magic commands. There are 3 brilliant articles listed below, but read them and then come back to this guide.

https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app
https://cloud.google.com/container-registry/docs/pushing-and-pulling
https://cloud.google.com/kubernetes-engine/docs/tutorials/configuring-domain-name-static-ip

Our app is called sf-xmas

This is the project so tell google this is the one you want to work with.

gcloud config set project sf-xmas

Set a zone where you are deploying to.

gcloud config set compute/zone us-central1-b

Create cluster of 1, we have an in memory DB, extra nodes will break this!

gcloud container clusters create xmas-cluster — num-nodes=1

Deploy code & run — use port 9000 as PLAY default.

kubectl run sf-xmasapp — image=us.gcr.io/sf-xmas/app:1 — port 9000

Create an ip address in your region.

gcloud compute addresses create sf-xmasapp-ip — region us-central1

Get the IP.

gcloud compute addresses describe sf-xmasapp-ip — region us-central1

Keep this IP address safe somewhere!

Create load balancer forwarding traffic to 9000 from 80 — make sure this has the same name as your app above.

kubectl expose deployment sf-xmasapp — type=LoadBalancer — port 80 — target-port 9000 — load-balancer-ip YOUR_IP_ADDRESS

Point your domain at this IP and you’re in business — that’s literally it.

*remember to update application.conf to accept your domain name as part of play.filters.allowed

I have updated the code and want to deploy a new container

Repeat the steps from earlier to build and tag your application with Docker. Make sure you give it a new version number (here we are using 25), then push to Google Container Registry.

Tag the build in docker to match our structure on Google Cloud.

docker tag IMAGE_ID us.gcr.io/sf-xmas/app:25

Push the docker image to the registry.

gcloud docker — push us.gcr.io/sf-xmas/app:25

Set the live version on our pod to use version 25.

kubectl set image deployment/sf-xmasapp sf-xmasapp=us.gcr.io/sf-xmas/app:25

So why did I do all of this? What’s the point?

You now have an app — a very fast app, running on the internet for essentially pennies. If we weren’t using an in memory database we could set to auto scale and have this app infinitely scale across Google Cloud. We could deploy across multiple availability zones and we could have the load balancer handle traffic for that.

Rolling releases are never really easy, but here we have a cloud deploy, we have a public IP, and we have a fully stocked Java app that can spin up a new container in under 2 seconds.

We can have our cake and eat it.

Welcome to the Cloud, welcome to Kubernetes.

Appendix

--

--

Rowan Laurence
Beyond
Writer for

Technical Director at Beyond San Francisco — Interested in all things digital, scalable software, collecting shoes and dance music