How to Deploy a Dockerized web application or service to Google Kubernetes Engine (GKE) in Google Cloud Platform (GCP)

By the time I am writing this, I have just deployed for first time a web app into Google Cloud Platform, using Google Kubernetes Engine. This post intends to help beginners to do the same.

Any feedback is welcomed through comments section below, even more if you have plenty experience with GCP and GKE and you think any of the steps could be improved, but please, keep in mind that this post is aimed for beginners, keep a pragmatic approach.

Find below a simple step-by-step tutorial:

1. Create a Google account

In case you don’t have an account yet, you will need to create a google account.

2. Enable Google Cloud Platform

Once you are logged in, create a free account into Google Cloud Platform and enable it, you may get some free credits to spend.

Once the service is added, you can access to Google Cloud Console. Note that a default project will have been created, but you may create a new one.

If you just created the account, a default project will have been created. Go to the top bar, and click on the name of the project. A new pop up will be displayed. showing the Project Id. Please, take note of Project Id of the project you want to use. You will need it later. You can find it

3. Enable billing for your Google account

Even if you use free initial credits, you will need to enable billing on Billing section and provide card details.

Bonus point: if you do care a lot about your credits, go to Billing section, Budgets and Alerts page and setup some alerts. You will receive emails on completing defined percentages of your budget.

4. Setup your local environment

Install Docker. You will need it for building your Docker Image, testing it locally, and pushing the image to Google Container Registry.

Install the Google Cloud SDK. You will need it to setup Docker, and alternatively, run some commands instead of using Google Cloud Console.

Setup your Google Cloud SDK with your Google Cloud Project Id.

gcloud config set project <PROJECT_ID>

Install the Kubernetes Command Line tool.

 gcloud components install kubectl

5. Build a Docker image and push it to your private Google Cloud Container Registry

Dockerize your web app or service, i.e., create a Dockerfile that will describe how the docker containers must be setup to run your web app or service.

Configure Docker to use gcloud to as credential helper. This will allow Docker to push the image to your private Google Cloud Container Registry.

gcloud auth configure-docker

Build your Docker Image, in case you didn’t do it before. The tag format is very important, as it tells Docker where to store the image into private Google Cloud Registry.

 docker build -t <HOST>/<PROJECT_ID>/<APP_NAME>:<TAG_VERSION> 

The four current options for host are: gcr.io, us.gcr.io, eu.gcr.io and asia.gcr.io, depending on the Docker Registry you want to use (you can read this help page for more details).

Note that if you already built previously your image, you still need to create a new tag for such image with the previous format:

docker tag <IMAGE_ID> <HOST>/<PROJECT_ID>/<APP_NAME>:<TAG_VERSION>

Push your image to your private Google Cloud Container Registry.

docker push <HOST>/<PROJECT_ID>/<APP_NAME>:<TAG_VERSION>

By the time I am writing this, I am not aware of any feature in Google Cloud Console, which allows you to push to your private Google Cloud Container Registry, so command line is the way I went.

5. Create a new cluster in GCP for your new web app or service

Despite, you can do this with Google Cloud SDK, for beginners, I would recommend to do it from Google Cloud Console . Launch it and, in Kubernetes Engine section, access to Clusters page. From there click on Create a new cluster.

On the left side, select Standard Cluster.

Before seeing the picture below, note the following points:

  • Location type is Zonal, since we are in a budget, with a low demanding project (note that a region contains several zones, and Regional option replicates nodes in all zones of the selected region).
  • Zone: remember, some regions are cheaper than others. For Europe, eureope-west4 region is cheap.
  • Default pool: for this proof of concept, one single pool is ok (remember you can change it later). The more CPUs and memory, the more you pay. On a budget, you can click on Customize link, and then select 0 cores, which means 1 shared CPU, so your app will be sharing resources with other apps. Minimum RAM is 0.6GB, for shared CPUs, but you may need more RAM (remember you are sharing). Shared CPUs don’t offer GPUs, so that’s another point to consider.
How to Deploy a Dockerized web application or service to Google Kubernetes Engine (GKE) in Google Cloud Platform (GCP) 1

As we won’t change Advanced Options, you don’t need to change them, but it is good you have a look to them.

Just click on create and wait until cluster is created.

6a. Deploy your web app or service to Kubernetes with Google Cloud Console

You can run this task with Kubectl or with Google Cloud Console. I will show how I did it with KubeCtl, but I would recommend to do it with Google Cloud Console, since it is more descriptive.

From Google Cloud Console, go to Kubernetes Engine section, open the Clusters page, and click the Deploy button on top of the page (if you have more than one cluster, you may need to do it from details page of the selected cluster). Since you will actually create a new Workload, you can also do it from Workloads page.

Click Existing container image, since you previously uploaded your image, and click Select button, in order to select your instance.

How to Deploy a Dockerized web application or service to Google Kubernetes Engine (GKE) in Google Cloud Platform (GCP) 2

One important Environment Variable to ad is Port to be set with the internal port used internally by the container for receiving requests (called <INTERNAL_CONTAINER_PORT> in the next section).

Once you have finished editing the container, click Done. You can also add more containers to the deployment, but for current example one is enough. Click Continue, for displaying the next page.

How to Deploy a Dockerized web application or service to Google Kubernetes Engine (GKE) in Google Cloud Platform (GCP) 3

Just set the application name (name for given deployment), any Kubernetes labels you may need, select the cluster, and click Deploy. Once is finished your container in the node will be running the web app or service included in your Docker image.

Expose the deployment of the web app or service to Internet, through a Load Balancer.

From Google Cloud Console, go to Kubernetes Engine section, open the Workloads page, select the recently created deployment, and from de deployment details page, click the Actions button on top of the page and then the Expose button.

Set a mapping from internal container port (called <INTERNAL_CONTAINER_PORT> in the next section), specified in deployment, to the external port that will be exposed by load balancer (called <EXTERNAL_PORT> in the next section) . Click Done, then select Load Balancer in Service Type field, and then click Expose. A new Service will have been created (you can see it from Services page, in Kubernetes Engine section).

How to Deploy a Dockerized web application or service to Google Kubernetes Engine (GKE) in Google Cloud Platform (GCP) 4

6b. Deploy your web app or service to Kubernetes with Kubernetes Command Line Tool

This is the way I did it, but I think that Google Cloud Console is much better for beginners.

Setup Kubernetes Command Line Tool to connect to your new cluster in Google Kubernetes Engine

gcloud container clusters get-credentials <CLUSTER_NAME>

Create a new Kubernetes Deployment, specifying the internal port of the container.

kubectl run <DEPLOYMENT_NAME> --image=<HOST>/<PROJECT_ID>/<APP_NAME>:<TAG_VERSION> --port <INTERNAL_CONTAINER_PORT>

Expose the deployment of the web app or service to Internet, through a Load Balancer.

kubectl expose deployment <DEPLOYMENT_NAME> --type=LoadBalancer --port <EXTERNAL_PORT> --target-port <INTERNAL_CONTAINER_PORT>