Deploying a Reddit Clone with Kubernetes Ingress

I am passionate about learning new skills . Currently quenching my thirst for knowledge by learning DevOps methodology.
Prerequisites for this project-
⁌ Reddit clone in Github
⁌ Profile in Dockerhub
⁌ CI server (t2.micro free tier eligible)
⁌ Deployment Server (t2.medium) (2 CPU, 4 GB RAM)
Step 1 -: Connect to CI-server EC2 instance. At this moment it is an empty server. We need to install Docker on it.
# For Docker Installation
sudo apt-get update
sudo apt-get install docker.io -y
sudo usermod -aG docker $USER && newgrp docker
Step 2 -: Clone the source code
After installing Docker in CI server, we need to bring Reddit Clone code from GitHub to CI-server
git clone https://github.com/mvgeorge1/reddit-clone-yt.git
Step 3 -: Containerize the application using Docker
Write a Dockerfile with the following command-
FROM node:19-alpine3.15
WORKDIR /reddit-clone
COPY . /reddit-clone
RUN npm install
EXPOSE 3000
CMD ["npm","run","dev"]
Explanation :This is a Dockerfile for building a container image based on the node:19-alpine3.15 image.
It sets the working directory to /reddit-clone and copies the current directory's contents to /reddit-clone in the container. Then, it runs npm install to install the dependencies for the project.
The EXPOSE instruction exposes port 3000 in the container to the host system, so that other containers or systems can access the app on that port.
Finally, the CMD instruction specifies the command to run when the container is started. In this case, it runs npm run dev, which likely starts a development server for the Reddit clone application.
Overall, this Dockerfile is used to build a container image for running the Reddit clone application.
Now friends we need to create an image from this Dockerfile and push it to the Docker Hub repository.
Step 4 -: Building Docker image
Code to build an image from Dockerfile and tag it to a repository created in Github
docker build . -t mvgeorge1/reddit-clone (Here "dot" signifies the current location where Dockerfile is situated.)
Step 5 -: Push the image to DockerHub

Login to your Dockerhub from CI-Server
docker login
Now push the image to Dockerhub using command
docker push username/image-name:latest
docker push mvgeorge1/reddit-clone:latest
Step 6 -: Connect with the deployment server
Install the pre-requisite
For docker installation -
sudo apt-get update
sudo apt-get install docker.io -y
sudo usermod -aG docker $user && newgrp docker
For Minikube and kubectl -
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
sudo snap install kubectl --classic
minikube start --driver=docker
Check with the help of kubectl get pods if the cluster is working fine.
Step 7 -: Write a Kubernetes Manifest file
Now we want that the image that we have pushed in Dockerhub, it should be deployed on the Deployment Server.
(a) Write a Deployment.yml file
In Kubernetes, a deployment file is a configuration file written in YAML or JSON format that describes how to create and manage a set of replica pods for a given application. The deployment file specifies the desired state of the application, including the number of replicas, the Docker image to use, and any necessary environment variables or volumes.
When a deployment file is applied to a Kubernetes cluster, the Kubernetes controller manager creates and manages the replicas according to the specified configuration. If any replicas fail or are terminated, the controller manager automatically creates new replicas to maintain the desired number of replicas.
Deployments in Kubernetes allow for rolling updates and rollbacks, making it easy to update an application without downtime. The deployment file can be updated with a new Docker image or configuration, and Kubernetes will create new replicas with the updated configuration while gradually terminating the old replicas.
Overall, a deployment file is a key component in the deployment of containerized applications in Kubernetes, providing a declarative way to manage application updates and scale the application up or down as needed.
apiVersion: apps/v1
kind: Deployment
metadata:
name: reddit-clone-deployment
labels:
app: reddit-clone
spec:
replicas: 2
selector:
matchLabels:
app: reddit-clone
template:
metadata:
labels:
app: reddit-clone
spec:
containers:
- name: reddit-clone
image: mvgeorge1/reddit-clone
ports:
- containerPort: 3000
kubectl apply -f Deployment.yml
kubectl get deployment
You can see here , 2 Replicaset are ready.

(b) Write a service.yml file
In Kubernetes, services are an abstraction layer that provides a consistent way to access a set of pods. Pods are the smallest deployable units in Kubernetes that contain one or more containers, and services allow you to group them together and provide a stable IP address and DNS name.
When you create a service in Kubernetes, it creates a virtual IP address that is associated with a specific set of pods. This IP address is stable, even if the pods are deleted or recreated, which means that clients can always connect to the service using the same IP address and DNS name.
Services in Kubernetes can be of several types, including:
ClusterIP*: This is the default type of service and provides a virtual IP address that can only be accessed from within the cluster.*
NodePort*: This type of service exposes the service on a specific port on each node in the cluster.*
LoadBalancer*: This type of service provisions an external load balancer to route traffic to the service.*
ExternalName*: This type of service maps a DNS name to an external resource.*
Services in Kubernetes also support load balancing, which means that traffic is distributed evenly across all pods in the service. This helps to ensure that all pods are used efficiently and that clients receive a consistent level of service.
apiVersion: v1
kind: Service
metadata:
name: reddit-clone-service
labels:
app: reddit-clone
spec:
type: NodePort
ports:
- port: 3000
targetPort: 3000
nodePort: 31000
selector:
app: reddit-clone
minikube service reddit-clone-service --url

Expose the app
First We need to expose our deployment so use
kubectl expose deployment reddit-clone-deployment --type=NodePortcommand.kubectl port-forward svc/reddit-clone-service 3000:3000 --address 0.0.0.0 &
VOILA !!! Reddit clone app looks good ! Isn't it???? 💃💃💃💃

Step 8: Let's configure Ingress
In Kubernetes, "ingress" is a resource object that defines rules for how external users or clients can access services running inside a cluster. Essentially, it acts as a gateway or entry point for incoming traffic from outside the cluster.
The ingress resource typically consists of a set of routing rules that define how incoming traffic should be directed to different services based on the request path or hostname. These rules are defined using a set of annotations on the ingress resource, which specify things like the backend service to route traffic to, SSL/TLS settings, and other options.
In addition to defining routing rules, ingress also supports features like load balancing, SSL/TLS termination, and path-based routing, making it a powerful and flexible tool for managing external access to services running inside a Kubernetes cluster.

minikube addons enable ingress
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-reddit-app 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: 3000kubectl apply -f ingress.yml

Now It's time to test your ingress so use the curl -L domain/test command in the terminal.
You can also see the deployed application on Ec2_ip:3000
Note:- Make sure you open the 3000 port in a security group of your Ec2 Instance.
I hope you guys enjoyed doing this project as much as I did. I appreciate you taking the time to go through my blog.



