📍Task 1:
1. Deployment of a Microservices Application on K8s
- Do Mongo Db Deployment
- Do Flask App Deployment
- Connect both using Service Discovery
📍Flask-microservice app
Step 1
: Installing minikube on AWS EC2 instance visit this GitHub URL for the guide:
https://github.com/LondheShubham153/kubestarter/blob/main/minikube_installation.md
Step 2
: Create a projects
directory inside the home
directory:
Step 3
: Clone this GitHub repository: https://github.com/Varunmargam/microservices-k8s
Inside the project
folder:
Step 4
: Change the directory to k8s
inside the microservices-k8s
folder:
It contains the following 6 files:
Deployment Manifest file for the backend: taskmaster.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: taskmaster
namespace: flask
labels:
app: taskmaster
spec:
replicas: 1
selector:
matchLabels:
app: taskmaster
template:
metadata:
namespace: flask
labels:
app: taskmaster
spec:
containers:
- name: taskmaster
image: trainwithshubham/taskmaster-python:latest
ports:
- containerPort: 5000
imagePullPolicy: Always
Service Manifest file for the backend: taskmaster-svc.yml
apiVersion: v1
kind: Service
metadata:
name: taskmaster-svc
namespace: flask
spec:
selector:
app: taskmaster
ports:
- port: 80
targetPort: 5000
nodePort: 30007
type: NodePort
MongoDB Database Deployment Manifest file: mongo.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
namespace: flask
labels:
app: mongo
spec:
selector:
matchLabels:
app: mongo
template:
metadata:
namespace: flask
labels:
app: mongo
spec:
containers:
- name: mongo
image: mongo
ports:
- containerPort: 27017
volumeMounts:
- name: storage
mountPath: /data/db
volumes:
- name: storage
persistentVolumeClaim:
claimName: mongo-pvc
MongoDB Database Service Manifest file: mongo-svc.yml
apiVersion: v1
kind: Service
metadata:
namespace: flask
labels:
app: mongo
name: mongo
spec:
ports:
- port: 27017
targetPort: 27017
selector:
app: mongo
MongoDB Database PersistentVolume Manifest file: mongo-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongo-pv
namespace: flask
spec:
capacity:
storage: 256Mi
accessModes:
- ReadWriteOnce
hostPath:
path: /tmp/db
MongoDB Database PersistentVolumeClaim Manifest file: mongo-pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongo-pvc
namespace: flask
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 256Mi
Step 5
: Create a namespace named flask
:
Step 6
: Executing the kubectl apply
commands in this order following the best practice:
Verifying the mongo deployment and the service created:
Step 7
: Executing inside the mongo pod to see if we can access it:
kubectl exec -it <pod_name> -n <namespace> -- bash
# If successfully entered the pod then to login to the mongo database do
mongosh
Type exit
to exit from the Mongo database.
Step 8
: Applying the backend deployment file and verifying it:
Applying the backend service deployment file and verifying it:
Step 8
: Verify both pods are running:
Step 9
: Testing the application on the minikube ip:
# command to access the service ip:
minikube service taskmaster-svc -n flask --url
# test the application on minikube:
curl -L http://minikube_ip:30007
# the link that we got from the fiest command
You can see our application is running!
To list the tasks:
curl -L http://minikube_ip:30007/tasks
curl -L http://minikube_ip:30007/task
Step 10
: To run the application in our browser we have to expose the deployment and the app service:
# command to expose deployment
kubectl expose deployment taskmaster -n flask --type=NodePort
Exposing the service:
kubectl port-forward svc/taskmaster-svc -n flask 30007:80 --address 0.0.0.0
Before that, we have to expose the port 30007
in the security group of our instance running the minikube.
Now execute the above command:
Now go to your browser and type the link ec2_ip:30007:
I tried to add some data using the command:
curl -d '{"task":"completed the assignment"}' -H "Content-Type: application/json" -X POST http://ec2_ip:30007/task
ISSUE: But, suddenly the connection was refused and the connection in my browser was also refused don't know why? I would appreciate it if you could give some possible solutions or reasons in the comments.
📍Task 2:
2. Deployment of a Reddit-Clone Application
- Do Deployment of the Reddit Clone app
- Write an ingress controller for the same to give a custom route
📍Deployment of a Reddit-Clone Application using Ingress
Step 1
: Install minikube on AWS EC2 instance.
Step 2
: Inside the projects
directory clone using the git clone <HTTP_URL>
command this GitHub repository: https://github.com/Varunmargam/reddit-clone-k8s-ingress
It contains 3 manifest files:
Deployment manifest file for the Reddit app: deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: reddit-clone-deployment
namespace: reddit
labels:
app: reddit-clone
spec:
replicas: 2
selector:
matchLabels:
app: reddit-clone
template:
metadata:
namespace: reddit
labels:
app: reddit-clone
spec:
containers:
- name: reddit-clone
image: rohanrustagi18/redditclone
ports:
- containerPort: 3000
Service Manifest file: service.yml
apiVersion: v1
# Indicates this as a service
kind: Service
metadata:
# Service name
name: reddit-clone-service
namespace: reddit
spec:
selector:
# Selector for Pods
app: reddit-clone
ports:
# Port Map
- port: 3000
targetPort: 3000
protocol: TCP
type: LoadBalancer
Ingress Manifest file: ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-reddit-app
namespace: reddit
spec:
rules:
- host: "domain.com"
http:
paths:
- pathType: Prefix
path: "/test"
backend:
service:
name: reddit-clone-service
port:
number: 3000
- host: "*.domain.com"
http:
paths:
- pathType: Prefix
path: "/test"
backend:
service:
name: reddit-clone-service
port:
number: 3000
Step 3
: Create a namespace named reddit
:
Step 4
: Apply the deployment file:
Verifying the pods are running:
Step 5
: Apply the service file and verify it:
Step 6
: Apply the ingress file and verify it:
Step 7
: Exposing the deployment:
Step 8
: Exposing the service:
Step 9
: Go to the security group of your instance and add the port 3000
:
Step 10
: Go to your browser and access the application at ec2_ip:3000
:
📍Basic Flask-QA Application
The previous 2 assignments had the deployment and the service file inside the GitHub repository. Therefore, I thought of writing a deployment and the service file and tried to deploy a basic Question and Answer Flask application that I got from ChatGPT.
Step 1
: Inside the projects directory make a directory named flask-qa
:
Step 2
: Go inside the flask-qa
directory and create a Python file app.py
:
Step 3
: Copy the below Python code inside this file, then save and quit the Vim editor:
Application code:
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
# Mock data for questions and answers
questions = [
{"id": 1, "title": "What is your favorite programming language?", "answers": []},
{"id": 2, "title": "How do you deploy a Flask app?", "answers": []},
]
@app.route("/")
def index():
return render_template("index.html", questions=questions)
@app.route("/ask", methods=["GET", "POST"])
def ask():
if request.method == "POST":
title = request.form["title"]
new_question = {"id": len(questions) + 1, "title": title, "answers": []}
questions.append(new_question)
return redirect(url_for("index"))
return render_template("ask.html")
@app.route("/question/<int:question_id>", methods=["GET", "POST"])
def question(question_id):
question = next((q for q in questions if q["id"] == question_id), None)
if not question:
return redirect(url_for("index"))
if request.method == "POST":
answer_text = request.form["answer"]
question["answers"].append(answer_text)
return render_template("question.html", question=question)
if __name__ == "__main__":
app.run(debug=True)
Step 4
: Create a requirements.txt file open it in the Vim editor and copy the below content inside the file.
Requirements file:
Flask==2.1.0
Step 5
: Create a Dockerfile
and copy the below content in it.
Dockerfile:
FROM python:3.8-slim-buster
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]
Step 6
: Build a Docker image from the Dockerfile with the tag <dockerhub_username>/flask-qa:latest
The below output image shows that the build has been successful:
The docker image has been created:
Now, we will upload this docker image to our DockerHub account.
Step 7
: Log in to your DockerHub account:
docker login -u <dockerhub_username>
Step 8
: Push this docker image to our DockerHub Account:
docker push <image_name>
Step 9
: Go to your DockerHub account and see if the image has been uploaded:
The flask-qa
image has been uploaded:
Now, let's start creating the Deployment and Service manifest file.
Step 10
: Create a namespace flask-qa
:
Step 11
: Create a file named deployment.yml and write the deployment manifest file.
(📝Note: Try to write the manifest files on your own and then compare them with the below deployment file)
Deployment Manifest file: deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: qa-deployment
namespace: flask-qa
labels:
app: qa
spec:
replicas: 1
selector:
matchLabels:
app: qa
template:
metadata:
namespace: flask-qa
labels:
app: qa
spec:
containers:
- name: qa-app
image: varunmargam/flask-qa:latest
ports:
- containerPort: 5000
Step 12
: Apply the created deployment.yml
file by kubectl apply
:
Verifying the pods are running:
Step 13
: Create a service.yml file and write the Service Manifest file:
Service Manifest file: service.yml
apiVersion: v1
kind: Service
metadata:
name: qa-svc
namespace: flask-qa
spec:
selector:
app: qa
type: NodePort
ports:
- protocol: TCP
port: 5000
targetPort: 5000
nodePort: 30001
Step 14
: Apply service.yml
file and verify if the service has been created:
Step 15
: Exposing the deployment and service:
Added the port 30001
in the Ec2 Instance security groups inbound rules:
However I was unable to access the application on my browser at port 30001, I would appreciate it if anyone could share what can be the issue with this in the comments.
Shubham Londhe I kindly request your advice on the issues I am facing in the k8s-microservice app and the above flask-qa app.