Deploying a Python Flask App to Kubernetes

Welcome to back to THINK Days!

Today we will walk through the steps to deploy a Python Flask application on to a Kubernetes cluster. We will build just the simple ‘hello-world’ app. The technologies we would be working with are Flask, Docker, and Kubernetes on IBM Cloud Kubernetes Service.

Why Flask?

Flask is lightweight, minimalistic Python web framework designed to get an app up and running quickly. It is sometimes called a micro-framework as it does not require specific tools or plug-ins to run. Also, thought I would explore Python while I am at it :)

Pre-requisites:

  • An IBM Cloud account – (sign up for a free account)
  • A basic, foundational knowledge of Flask and Python

Building and Containerizing the Flask App

On a code editor of you choice, create a folder (ie py-app) and a file main.py file and enter the following:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World from Pycon Flask"

if __name__ == "__main__":
    # Only for debugging while developing
    app.run(host='0.0.0.0', debug=True, port=80)

Then create a Dockerfile in the root directory of the project and enter the following:

FROM tiangolo/uwsgi-nginx-flask:python3.7
COPY ./py-app /py-app

Now, let's containerize this simple app by running the following commands:

$ docker build -t hello-world .
$ docker run -d --name pycon -p 80:80 hello-world

To test the output from the Flask app just use curl to ping the app:

curl http://localhost

Pushing the image to IBM Cloud Container Registry

I will quickly walk through the steps on the CLI, but do check out my previous blog on a detail walkthrough to push containers to IBM Cloud Container Registry .

Log in to your IBM Cloud account:

ibmcloud login -a https://cloud.ibm.com

Note, if you have a federated ID, like I do, log in to the IBM Cloud CLI:

ibmcloud login --sso

In the Select a region prompt select an approporiate region in my case that would be us-south

You can ensure that you're targeting the correct IBM Cloud Container Registry region by running:

ibmcloud cr region-set us-south

Now if you don't already have one, create a namespace by running the following command.

ibmcloud cr namespace-add $(kubectl config view --minify --output 'jsonpath={..namespace}')

To view and confirm your namespace run the command:

kubectl config view --minify --output 'jsonpath={..namespace}'

Log your local Docker daemon into the IBM Cloud Container Registry.

ibmcloud cr login

Select your repository and tag by which you can identify your image:

docker tag hello-world us.icr.io/<namespace>/hello-world:latest

Finally, Push the image to the registry:

docker push us.icr.io/<namespace>/hello-world:latest

Kubernetes Deployment

Before we dig in here's a summary of what we get to accomplish wit Kubernetes. Kubernetes is a container orchestration tool used to manage and aid in deployments. Deployments are used to manage pods, which include containerized instances of an app. The following command deploys the app in a single pod by referring to the image that we built in the private registry. For the purposes of this walkthrough, the deployment is named hello-world-deployment, but you can give the deployment any name that you want.

kubectl create deployment hello-world-deployment --image=us.icr.io/<namespace>/hello-world:latest

This should output:
deployment "hello-world-deployment" created

But we aren't done just yet. We need to make the app available to the world. We do this by exposing the deployment as a NodePort service. NodePorts are randomly assigned when they are generated with the expose command, but within 30000-32767. The NodePort that you expose is the port on which the worker node listens for traffic:

kubectl expose deployment/hello-world-deployment --type=NodePort --port=80 --name=hello-world-service --target-port=80

Now that all the deployment work is done, you can test the app in a browser. To do that, we need to get the details to from the URL.

First, let's get information about the service to see which NodePort was assigned:

kubectl describe service hello-world-service

To get the public IP address for the worker node in the cluster, run:

ibmcloud ks worker ls --cluster <cluster_name>

Open a browser and check out the app with the following URL:

http://<IP_address>:<NodePort>

When you enter that URL in a browser, you can see the following text.

Hello World from Pycon Flask

Oila! You have successfully built setup a Python Flask App then containerized it using a Docker Image and deployed it onto an IBM Cloud Kubernetes Service.

Thank you for following along this THINK Day's Tutorial and be sure to look out for my next post, where I will continue sharing my Journey with IBM Cloud Services!!!

==== Follow me on Social Media(@mrinasugosh) ====
Dev.to: @mrinasugosh
Github: @mrinasugosh
Twitter: @mrinasugosh
LinkedIn: @mrinasugosh

27