Thanks! We'll be in touch in the next 12 hours
Oops! Something went wrong while submitting the form.

A Practical Guide to Deploying Multi-tier Applications on Google Container Engine (GKE)

Introduction

All modern era programmers can attest that containerization has afforded more flexibility and allows us to build truly cloud-native applications. Containers provide portability - ability to easily move applications across environments. Although complex applications comprise of many (10s or 100s) containers. Managing such applications is a real challenge and that’s where container orchestration and scheduling platforms like Kubernetes, Mesosphere, Docker Swarm, etc. come into the picture. 
Kubernetes, backed by Google is leading the pack given that Redhat, Microsoft and now Amazon are putting their weight behind it.

Kubernetes can run on any cloud or bare metal infrastructure. Setting up & managing Kubernetes can be a challenge but Google provides an easy way to use Kubernetes through the Google Container Engine(GKE) service.

What is GKE?

Google Container Engine is a Management and orchestration system for Containers. In short, it is a hosted Kubernetes. The goal of GKE is to increase the productivity of DevOps and development teams by hiding the complexity of setting up the Kubernetes cluster, the overlay network, etc.

Why GKE? What are the things that GKE does for the user?

  • GKE abstracts away the complexity of managing a highly available Kubernetes cluster.
  • GKE takes care of the overlay network
  • GKE also provides built-in authentication
  • GKE also provides built-in auto-scaling.
  • GKE also provides easy integration with the Google storage services.

In this blog, we will see how to create your own Kubernetes cluster in GKE and how to deploy a multi-tier application in it. The blog assumes you have a basic understanding of Kubernetes and have used it before. It also assumes you have created an account with Google Cloud Platform. If you are not familiar with Kubernetes, this guide from Deis  is a good place to start.

Google provides a Command-line interface (gcloud) to interact with all Google Cloud Platform products and services. gcloud is a tool that provides the primary command-line interface to Google Cloud Platform. Gcloud tool can be used in the scripts to automate the tasks or directly from the command-line. Follow this guide to install the gcloud tool.

Now let's begin! The first step is to create the cluster.

Basic Steps to create cluster

In this section, I would like to explain about how to create GKE cluster. We will use a command-line tool to setup the cluster.

Set the zone in which you want to deploy the cluster

CODE: https://gist.github.com/velotiotech/1e6e3f217a26bc17fa07d5571894bb6d.js

Create the cluster using following command,

CODE: https://gist.github.com/velotiotech/60773c4eb8ad757e36e52b82a1a6c48d.js

Let's try to understand what each of these parameters mean:

--project: Project Name

--machine-type: Type of the machine like n1-standard-2, n1-standard-4

--image-type: OS image."COS" i.e. Container Optimized OS from Google: More Info here.

--disk-size: Disk size of each instance.

--num-nodes: Number of nodes in the cluster.

--network: Network that users want to use for the cluster. In this case, we are using default network.

Apart from the above options, you can also use the following to provide specific requirements while creating the cluster:

--scopes: Scopes enable containers to direct access any Google service without needs credentials. You can specify comma separated list of scope APIs. For example:

  • Compute: Lets you view and manage your Google Compute Engine resources
  • Logging.write: Submit log data to Stackdriver.

You can find all the Scopes that Google supports here: .

--additional-zones: Specify additional zones to high availability. Eg. --additional-zones us-east1-b, us-east1-d . Here Kubernetes will create a cluster in 3 zones (1 specified at the beginning and additional 2 here).

--enable-autoscaling : To enable the autoscaling option. If you specify this option then you have to specify the minimum and maximum required nodes as follows; You can read more about how auto-scaling works here. Eg:   --enable-autoscaling --min-nodes=15 --max-nodes=50

You can fetch the credentials of the created cluster. This step is to update the credentials in the kubeconfig file, so that kubectl will point to required cluster.

CODE: https://gist.github.com/velotiotech/9e36c65b1ec41cc1f19549285e160fda.js

Now, your First Kubernetes cluster is ready. Let’s check the cluster information & health.

CODE: https://gist.github.com/velotiotech/0fe995dec16bfa0a59589de1cb319e6d.js

After creating Cluster, now let's see how to deploy a multi tier application on it. Let’s use simple Python Flask app which will greet the user, store employee data & get employee data.

Application Deployment

I have created simple Python Flask application to deploy on K8S cluster created using GKE. you can go through the source code here. If you check the source code then you will find directory structure as follows:

CODE: https://gist.github.com/velotiotech/bb3a65be5baef59f9b094f665068c45f.js

In this, I have written a Dockerfile for the Python Flask application in order to build our own image to deploy. For MySQL, we won’t build an image of our own. We will use the latest MySQL image from the public docker repository.

Before deploying the application, let’s re-visit some of the important Kubernetes terms:

Pods:

The pod is a Docker container or a group of Docker containers which are deployed together on the host machine. It acts as a single unit of deployment.

Deployments:

Deployment is an entity which manages the ReplicaSets and provides declarative updates to pods. It is recommended to use Deployments instead of directly using ReplicaSets. We can use deployment to create, remove and update ReplicaSets. Deployments have the ability to rollout and rollback the changes.

Services:

Service in K8S is an abstraction which will connect you to one or more pods. You can connect to pod using the pod’s IP Address but since pods come and go, their IP Addresses change.  Services get their own IP & DNS and those remain for the entire lifetime of the service. 

Each tier in an application is represented by a Deployment. A Deployment is described by the YAML file. We have two YAML files - one for MySQL and one for the Python application.

1. MySQL Deployment YAML

CODE: https://gist.github.com/velotiotech/a184f61aa9b5d4d807393a481dd4de14.js

2. Python Application Deployment YAML

CODE: https://gist.github.com/velotiotech/2c5fa0cbeeae127c592ea291b2ab9a8d.js

Each Service is also represented by a YAML file as follows:

1. MySQL service YAML

CODE: https://gist.github.com/velotiotech/754d971447810e12f46feae2bbd11ee7.js

2. Python Application service YAML

CODE: https://gist.github.com/velotiotech/3d36fb6961fd5d0b3063b759480fa7d4.js

You will find a ‘kind’ field in each YAML file. It is used to specify whether the given configuration is for deployment, service, pod, etc.

In the Python app service YAML, I am using type = LoadBalancer. In GKE, There are two types of cloud load balancers available to expose the application to outside world.

  1. TCP load balancer: This is a TCP Proxy-based load balancer. We will use this in our example.
  2. HTTP(s) load balancer: It can be created using Ingress. For more information, refer to this post that talks about Ingress in detail.

In the MySQL service, I’ve not specified any type, in that case, type ‘ClusterIP’ will get used, which will make sure that MySQL container is exposed to the cluster and the Python app can access it.

If you check the app.py, you can see that I have used “mysql-service.default” as a hostname. “Mysql-service.default” is a DNS name of the service. The Python application will refer to that DNS name while accessing the MySQL Database.

Now, let's actually setup the components from the configurations. As mentioned above, we will first create services followed by deployments.

Services:

CODE: https://gist.github.com/velotiotech/5f7f4f58ae43a807be2ee8ad431e4272.js

Deployments:

CODE: https://gist.github.com/velotiotech/615c372ca454a2a85a22f5accc54acde.js

Check the status of the pods and services. Wait till all pods come to the running state and Python application service to get external IP like below:

CODE: https://gist.github.com/velotiotech/0a2afc570f688f51442fa85bbad9d90a.js

Once you get the external IP, then you should be able to make APIs calls using simple curl requests.

Eg. To Store Data :

CODE: https://gist.github.com/velotiotech/cea7b5e3a759e2fb471acafd471d065d.js

Eg. To Get Data :

CODE: https://gist.github.com/velotiotech/962f14d71c7d2064c76c595b4d5daf39.js

At this stage your application is completely deployed and is externally accessible.

Manual scaling of pods

Scaling your application up or down in Kubernetes is quite straightforward. Let’s scale up the test-app deployment.

CODE: https://gist.github.com/velotiotech/6e53671570987b28e1e1fe832e86f752.js

Deployment configuration for test-app will get updated and you can see 3 replicas of test-app are running. Verify it using,

CODE: https://gist.github.com/velotiotech/de6d5f0d3868c7e33ac6a8c0df46b5dc.js

In the same manner, you can scale down your application by reducing the replica count.

Cleanup :

Un-deploying an application from Kubernetes is also quite straightforward. All we have to do is delete the services and delete the deployments. The only caveat is that the deletion of the load balancer is an asynchronous process. You have to wait until it gets deleted.

CODE: https://gist.github.com/velotiotech/4e1e3b6074f267d041969f39d0db8f65.js

The above command will deallocate Load Balancer which was created as a part of test-service. You can check the status of the load balancer with the following command.

CODE: https://gist.github.com/velotiotech/57ddaf54b01ba1a024311b9e44403bd1.js

Once the load balancer is deleted, you can clean-up the deployments as well.

CODE: https://gist.github.com/velotiotech/d1db349d9a63edbc60dc032b45e8ae1a.js

Delete the Cluster:

CODE: https://gist.github.com/velotiotech/3ac82a151d930a80200e95707b983378.js

Conclusion

In this blog, we saw how easy it is to deploy, scale & terminate applications on Google Container Engine. Google Container Engine abstracts away all the complexity of Kubernetes and gives us a robust platform to run containerised applications. I am super excited about what the future holds for Kubernetes!

Check out some of Velotio's other blogs on Kubernetes.

Get the latest engineering blogs delivered straight to your inbox.
No spam. Only expert insights.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Did you like the blog? If yes, we're sure you'll also like to work with the people who write them - our best-in-class engineering team.

We're looking for talented developers who are passionate about new emerging technologies. If that's you, get in touch with us.

Explore current openings

A Practical Guide to Deploying Multi-tier Applications on Google Container Engine (GKE)

Introduction

All modern era programmers can attest that containerization has afforded more flexibility and allows us to build truly cloud-native applications. Containers provide portability - ability to easily move applications across environments. Although complex applications comprise of many (10s or 100s) containers. Managing such applications is a real challenge and that’s where container orchestration and scheduling platforms like Kubernetes, Mesosphere, Docker Swarm, etc. come into the picture. 
Kubernetes, backed by Google is leading the pack given that Redhat, Microsoft and now Amazon are putting their weight behind it.

Kubernetes can run on any cloud or bare metal infrastructure. Setting up & managing Kubernetes can be a challenge but Google provides an easy way to use Kubernetes through the Google Container Engine(GKE) service.

What is GKE?

Google Container Engine is a Management and orchestration system for Containers. In short, it is a hosted Kubernetes. The goal of GKE is to increase the productivity of DevOps and development teams by hiding the complexity of setting up the Kubernetes cluster, the overlay network, etc.

Why GKE? What are the things that GKE does for the user?

  • GKE abstracts away the complexity of managing a highly available Kubernetes cluster.
  • GKE takes care of the overlay network
  • GKE also provides built-in authentication
  • GKE also provides built-in auto-scaling.
  • GKE also provides easy integration with the Google storage services.

In this blog, we will see how to create your own Kubernetes cluster in GKE and how to deploy a multi-tier application in it. The blog assumes you have a basic understanding of Kubernetes and have used it before. It also assumes you have created an account with Google Cloud Platform. If you are not familiar with Kubernetes, this guide from Deis  is a good place to start.

Google provides a Command-line interface (gcloud) to interact with all Google Cloud Platform products and services. gcloud is a tool that provides the primary command-line interface to Google Cloud Platform. Gcloud tool can be used in the scripts to automate the tasks or directly from the command-line. Follow this guide to install the gcloud tool.

Now let's begin! The first step is to create the cluster.

Basic Steps to create cluster

In this section, I would like to explain about how to create GKE cluster. We will use a command-line tool to setup the cluster.

Set the zone in which you want to deploy the cluster

CODE: https://gist.github.com/velotiotech/1e6e3f217a26bc17fa07d5571894bb6d.js

Create the cluster using following command,

CODE: https://gist.github.com/velotiotech/60773c4eb8ad757e36e52b82a1a6c48d.js

Let's try to understand what each of these parameters mean:

--project: Project Name

--machine-type: Type of the machine like n1-standard-2, n1-standard-4

--image-type: OS image."COS" i.e. Container Optimized OS from Google: More Info here.

--disk-size: Disk size of each instance.

--num-nodes: Number of nodes in the cluster.

--network: Network that users want to use for the cluster. In this case, we are using default network.

Apart from the above options, you can also use the following to provide specific requirements while creating the cluster:

--scopes: Scopes enable containers to direct access any Google service without needs credentials. You can specify comma separated list of scope APIs. For example:

  • Compute: Lets you view and manage your Google Compute Engine resources
  • Logging.write: Submit log data to Stackdriver.

You can find all the Scopes that Google supports here: .

--additional-zones: Specify additional zones to high availability. Eg. --additional-zones us-east1-b, us-east1-d . Here Kubernetes will create a cluster in 3 zones (1 specified at the beginning and additional 2 here).

--enable-autoscaling : To enable the autoscaling option. If you specify this option then you have to specify the minimum and maximum required nodes as follows; You can read more about how auto-scaling works here. Eg:   --enable-autoscaling --min-nodes=15 --max-nodes=50

You can fetch the credentials of the created cluster. This step is to update the credentials in the kubeconfig file, so that kubectl will point to required cluster.

CODE: https://gist.github.com/velotiotech/9e36c65b1ec41cc1f19549285e160fda.js

Now, your First Kubernetes cluster is ready. Let’s check the cluster information & health.

CODE: https://gist.github.com/velotiotech/0fe995dec16bfa0a59589de1cb319e6d.js

After creating Cluster, now let's see how to deploy a multi tier application on it. Let’s use simple Python Flask app which will greet the user, store employee data & get employee data.

Application Deployment

I have created simple Python Flask application to deploy on K8S cluster created using GKE. you can go through the source code here. If you check the source code then you will find directory structure as follows:

CODE: https://gist.github.com/velotiotech/bb3a65be5baef59f9b094f665068c45f.js

In this, I have written a Dockerfile for the Python Flask application in order to build our own image to deploy. For MySQL, we won’t build an image of our own. We will use the latest MySQL image from the public docker repository.

Before deploying the application, let’s re-visit some of the important Kubernetes terms:

Pods:

The pod is a Docker container or a group of Docker containers which are deployed together on the host machine. It acts as a single unit of deployment.

Deployments:

Deployment is an entity which manages the ReplicaSets and provides declarative updates to pods. It is recommended to use Deployments instead of directly using ReplicaSets. We can use deployment to create, remove and update ReplicaSets. Deployments have the ability to rollout and rollback the changes.

Services:

Service in K8S is an abstraction which will connect you to one or more pods. You can connect to pod using the pod’s IP Address but since pods come and go, their IP Addresses change.  Services get their own IP & DNS and those remain for the entire lifetime of the service. 

Each tier in an application is represented by a Deployment. A Deployment is described by the YAML file. We have two YAML files - one for MySQL and one for the Python application.

1. MySQL Deployment YAML

CODE: https://gist.github.com/velotiotech/a184f61aa9b5d4d807393a481dd4de14.js

2. Python Application Deployment YAML

CODE: https://gist.github.com/velotiotech/2c5fa0cbeeae127c592ea291b2ab9a8d.js

Each Service is also represented by a YAML file as follows:

1. MySQL service YAML

CODE: https://gist.github.com/velotiotech/754d971447810e12f46feae2bbd11ee7.js

2. Python Application service YAML

CODE: https://gist.github.com/velotiotech/3d36fb6961fd5d0b3063b759480fa7d4.js

You will find a ‘kind’ field in each YAML file. It is used to specify whether the given configuration is for deployment, service, pod, etc.

In the Python app service YAML, I am using type = LoadBalancer. In GKE, There are two types of cloud load balancers available to expose the application to outside world.

  1. TCP load balancer: This is a TCP Proxy-based load balancer. We will use this in our example.
  2. HTTP(s) load balancer: It can be created using Ingress. For more information, refer to this post that talks about Ingress in detail.

In the MySQL service, I’ve not specified any type, in that case, type ‘ClusterIP’ will get used, which will make sure that MySQL container is exposed to the cluster and the Python app can access it.

If you check the app.py, you can see that I have used “mysql-service.default” as a hostname. “Mysql-service.default” is a DNS name of the service. The Python application will refer to that DNS name while accessing the MySQL Database.

Now, let's actually setup the components from the configurations. As mentioned above, we will first create services followed by deployments.

Services:

CODE: https://gist.github.com/velotiotech/5f7f4f58ae43a807be2ee8ad431e4272.js

Deployments:

CODE: https://gist.github.com/velotiotech/615c372ca454a2a85a22f5accc54acde.js

Check the status of the pods and services. Wait till all pods come to the running state and Python application service to get external IP like below:

CODE: https://gist.github.com/velotiotech/0a2afc570f688f51442fa85bbad9d90a.js

Once you get the external IP, then you should be able to make APIs calls using simple curl requests.

Eg. To Store Data :

CODE: https://gist.github.com/velotiotech/cea7b5e3a759e2fb471acafd471d065d.js

Eg. To Get Data :

CODE: https://gist.github.com/velotiotech/962f14d71c7d2064c76c595b4d5daf39.js

At this stage your application is completely deployed and is externally accessible.

Manual scaling of pods

Scaling your application up or down in Kubernetes is quite straightforward. Let’s scale up the test-app deployment.

CODE: https://gist.github.com/velotiotech/6e53671570987b28e1e1fe832e86f752.js

Deployment configuration for test-app will get updated and you can see 3 replicas of test-app are running. Verify it using,

CODE: https://gist.github.com/velotiotech/de6d5f0d3868c7e33ac6a8c0df46b5dc.js

In the same manner, you can scale down your application by reducing the replica count.

Cleanup :

Un-deploying an application from Kubernetes is also quite straightforward. All we have to do is delete the services and delete the deployments. The only caveat is that the deletion of the load balancer is an asynchronous process. You have to wait until it gets deleted.

CODE: https://gist.github.com/velotiotech/4e1e3b6074f267d041969f39d0db8f65.js

The above command will deallocate Load Balancer which was created as a part of test-service. You can check the status of the load balancer with the following command.

CODE: https://gist.github.com/velotiotech/57ddaf54b01ba1a024311b9e44403bd1.js

Once the load balancer is deleted, you can clean-up the deployments as well.

CODE: https://gist.github.com/velotiotech/d1db349d9a63edbc60dc032b45e8ae1a.js

Delete the Cluster:

CODE: https://gist.github.com/velotiotech/3ac82a151d930a80200e95707b983378.js

Conclusion

In this blog, we saw how easy it is to deploy, scale & terminate applications on Google Container Engine. Google Container Engine abstracts away all the complexity of Kubernetes and gives us a robust platform to run containerised applications. I am super excited about what the future holds for Kubernetes!

Check out some of Velotio's other blogs on Kubernetes.

Did you like the blog? If yes, we're sure you'll also like to work with the people who write them - our best-in-class engineering team.

We're looking for talented developers who are passionate about new emerging technologies. If that's you, get in touch with us.

Explore current openings