Deploying a Flask app to Kubernetes
Building a Flask application and deploying it to Kubernetes using Docker and Minikube.
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
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
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
You can access the code for this project here: https://github.com/shrued/minikube-flask-app