Deploying a Flask app to Kubernetes

Shruti
featurepreneur
Published in
4 min readFeb 1, 2021

Building a Flask application and deploying it to Kubernetes using Docker and Minikube.

Flask and Kubernetes

Prerequisites:

1. Create a Flask Application

First, create a simple Flask app. Add this code in a new file app.py.

from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def hello():
return jsonify({"Message": "How you doin'"})
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)

Create another file called requirements.txt and add this in it:

flask

This will add flask as a dependency.

2. Create a Docker Image

To deploy the application to Kubernetes, we need to put it in a container. To do that, we add a Dockerfile at the root of the project.

Create a file and name it Dockerfile. Add this to the file:

FROM python:3.7
RUN mkdir /app
WORKDIR /app/
ADD . /app/
RUN pip install -r requirements.txt
CMD ["python", "/app/app.py"]

Start Minikube.

minikube start

Now ssh/log in to Minikube VM and create the docker image.

minikube ssh
Minikube VM
Minikube VM

Before creating the docker image, clone the repository containing the application’s source code inside minikube and cd into the folder. If you didn’t already create a repository, you can use this:

git clone https://github.com/shrued/minikube-flask-app.git
cd minikube-flask-app

To generate a docker image using this Dockerfile,

docker build -t minikube-flask-app .

Check if the image was created with this command:

docker images

You should get an output similar to this:

REPOSITORY                                TAG         IMAGE ID       CREATED         SIZE
minikube-flask-app latest 12694ab43e50 4 seconds ago 885MB

Create an account in Docker Hub and log in to your account from your terminal using this command:

docker login

Before pushing the image to Docker Hub, we need to tag it. Replace <dockerhub_username> with your Docker Hub username.

docker tag flask-kubernetes-deploy <dockerhub_username>/minikube-flask-app

Now, the image can be pushed to Docker Hub. Replace <dockerhub_username> with your Docker Hub username.

docker push <dockerhub_username>/minikube-flask-app
Docker Hub
Docker Hub

3. Deploying the application

Create a file called deployment.yaml and add the following code in the file. Replace <dockerhub_username> with your Docker Hub username.

apiVersion: v1
kind: Service
metadata:
name: flask-test-service
spec:
selector:
app: flask-test-app
ports:
- protocol: "TCP"
port: 6000
targetPort: 5000
type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-test-app
spec:
selector:
matchLabels:
app: flask-test-app
replicas: 5
template:
metadata:
labels:
app: flask-test-app
spec:
containers:
- name: flask-test-app
image: docker.io/<dockerhub_username>/minikube-flask-app
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000

This will allow the application to have as many replicas (parallel pods) as we define. Here, we give 5. In addition, we can mention the ports used and additional metadata for the application.

With just the deployment we wouldn't be able to access our application from outside. To expose applications, we need a service. We can use service to define which ports to expose.

Both the service and deployment can be added to a single .yaml file with a --- for separation.

In a nutshell, service will work as a load balancer and deployment will serve as the application.

Exit from the VM before doing the next step using this command:

exit

To create the service and the deployment, we use this command and deploy the application to Kubernetes:

kubectl apply -f deployment.yaml

You should get an output similar to this:

service/flask-test-service created
deployment.apps/flask-test-app created

To check if everything is running we need to check the pods and the service.

Checking pods:

kubectl get po

This will give us 5 replicas as requested in the deployment.yaml file.

You should get an output similar to this:

NAME                              READY   STATUS    RESTARTS   AGE
flask-test-app-55dfc45dcf-6dfnj 1/1 Running 0 19s
flask-test-app-55dfc45dcf-fmzk6 1/1 Running 0 19s
flask-test-app-55dfc45dcf-jj82s 1/1 Running 0 19s
flask-test-app-55dfc45dcf-k4hzj 1/1 Running 0 19s
flask-test-app-55dfc45dcf-m7hp5 1/1 Running 0 19s

Checking the service:

kubectl get svc

You should get an output similar to this:

NAME                 TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
flask-test-service LoadBalancer 10.99.38.187 <pending> 6000:31154/TCP 68s

Run this command to access the application in your localhost browser:

minikube service flask-test-service

You should get an output similar to this:

|-----------|--------------------|-------------|-----------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|--------------------|-------------|-----------------------------|
| default | flask-test-service | 6000 | http://192.168.39.162:31154 |
|-----------|--------------------|-------------|-----------------------------|
🎉 Opening service default/flask-test-service in default browser...

And this command to view the deployment and pods on the Kubernetes dashboard:

minikube dashboard
Minikube Dashboard
Minikube Dashboard

You can access the code for this project here: https://github.com/shrued/minikube-flask-app

--

--

Shruti
featurepreneur

Tech builds shouldn't be intimidating – I break down my projects in detail, turning my learning experiences into your shortcuts.