MP9: Kubernetes

In this MP we will be creating a scalable, automatically load-balancing website using Kubernetes. The techniques used in this MP are commonly used by large companies like Google and Amazon to scale for all the users that surf through their website at the same time.

Background

Kubernetes is an application for container orchestration. It is commonly use for quick deployment, scaling and management of applications in containers. Kubernetes is composed of pods, to allow it to manage any container appropriately.

Kubernetes works as:

The pods within Kubernetes can be created through command line arguments, or *.yaml files. An example of a *.yaml file looks something like this,

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

For further documentation on how *.yaml files represent pods, you can look at the Kubernetes tutorials page.

Part 1

First thing we will do is finish the search function for our website.

Our search will find the number of occurrences of a specific word in ten different Wikipedia articles. We will start our search at the Wikipedia article for Black Panther, and then we will do a depth-first-search for the next links. Most of the function has been implemented, all that is left is counting the occurrences from the given text.

Run app.py,

$ python3 app.py

To see the website go to http://localhost:8080. You should be able to look up words, find their frequency and measure how long it took to do all the operations. Note once you search a word, it is saved in a cache; to measure the time properly again, search another word. The cache allows you to spam click the submit button and measure how long a normal website takes to operate on many users simultaneously.

Part 2

Since we want to replicate our website over several nodes and have them all active in parallel, we will create a Dockerfile that runs our website inside a container. In the Dockerfile, we need to include the app.py source file and our HTML template (make sure it’s inside a directory called templates!). We will also need to tell our container to run our app.py file. The source image (tiangolo/uwsgi-nginx-flask:python3.6) has been specified for you.

To test that the docker container works run the following commands:

Build container:

$ docker build -t mp9 . 

Then run the container,

$ docker run -p 8080:8080 mp9

Now you should be able to go to, http://localhost:8080 and see your website running as before.

Part 3

Now that we have created our Dockerfile, we need to send it to the cloud. Follow the commands to get it set up in your GCP project.

Set up your GCP Cluster by going to Google Cloud Console and selecting a project. Click the + symbol on the top right, give your project a name, and you are set up with GCP.

You will also need to have gcloud and kubectl installed. Note if you are using the cloud console, you do not need to install these components.

With gcloud installed, set the project name and zone.

Set up project name,

$ gcloud config set project <Project Name>

Set up your zone,

$ gcloud config set compute/zone us-central1-b

Build container within gcp,

$ docker build -t gcr.io/<Project Name>/mp9 .

Push to gcloud,

$ gcloud docker -- push gcr.io/<Project Name>/mp9

Now we will create a new cluster for our pods,

$ gcloud container clusters create mp9-cluster --num-nodes=3

You should see the following message:

Creating cluster mp9-cluster...|

You should then see a description of your newly created cluster.

Now that the files are in our project, we need to create a deployment pod. The Kubernetes Documentation defines a pod as follows:

A pod (as in a pod of whales or pea pod) is a group of one or more containers (such as Docker containers), with shared storage/network, and a specification for how to run the containers

Essentially, our pod will contain our web application container, and the pod will be replicated so that we have multiple hosts serving the application in parallel.

Using deploy.yaml, we will define our deployment pods and make sure that it has 3 replicas of the image. You may want to use this example as a template for your deploy.yaml. Note that image should be set to the “gcr.io” URL where you pushed your container image in Part 3.

To check that the pods were created successfully run the following commands: To build the pods run the following command:

$ kubectl create -f deploy.yaml

Kubernetes will tell you if your yaml file was accepted.

To see the pods in place,

$ kubectl get pods

You should see your three pods set up. There might be other pods running, this is fine. You can try destroying a pod and Kubernetes will recreate it. Another test to see if it works well, is creating replicas.

Part 4

We have created our pods, and have set up our containers within our pods. Now we need to create an external IP to view our website so that we can let Kubernetes balance the workload between our pods. We will do this in ingress.yaml. You should use a “LoadBalancer” type in your ingress file so that Kubernetes distributes the load across the replicas of our app.

To check that the pods were created successfully run the following commands: To build the pods,

$ kubectl create -f ingress.yaml

To see the pods in place,

$ kubectl get services

You should see your service set up with an external IP address. Go to that link and make sure the website is up and running!

To make sure that everything is working correctly, search a word and hit submit three times really fast. In the Kubernetes version of the website, the time elapsed should not change for submitting the word once or three times (This should run in less than 7 seconds). If you do the same for the normal website, the time elapsed increases. Note: To refresh the time for a specific word, search a new word.

Report Component

For each component of the MP, please provide a brief description of what work you needed to do to make the deployment work correctly.

This report does not need to be as comprehensive as MP6, and is to test your understanding of the concepts discussed.

Submit your report in a file called report.txt. This MP will be hand-graded and not auto-graded.

Submission

MP 9 is due on Tuesday, April 24TH, 2018 at 11:59PM.

You can find starter code and the Git repository where you should submit your code here:

If you have issues accessing your repository, make sure that you’ve signed into Gitlab. If you still do not have access, please make a private post on the course Piazza.

Please write your solutions as indicated in the following file:

… and commit your code to Gitlab like this:

git add .
git commit -m "Completed MP" # Your commit message doesn't need to match this
git push

NOTE

To make sure that your profile does not lose all funds follow these commands to delete your project.

To delete the services,

$ kubectl delete -f ingress.yaml

Make sure that there are no external IP’s being used.

$ gcloud compute forwarding-rules list

Delete your pods,

$ kubectl delete -f deploy.yaml

Delete your cluster,

$ gcloud container clusters delete mp9-cluster