Building a High-Performance Reddit Clone with Kubernetes Ingress

Before we begin with the Project, we need to make sure we have the following prerequisites installed:

  1. EC2 ( AMI- Ubuntu, Type- t2.micro ) - CI server

  2. EC2 ( AMI- Ubuntu, Type- t2.medium ) - Deployment server

You can Install all this by doing the below steps one by one. and these steps are for Ubuntu AMI.

# Steps:-

# For Docker Installation
sudo apt-get update
sudo apt-get install docker.io -y
sudo usermod -aG docker $USER && newgrp docker

# For Minikube & 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

Clone the source code

The first step is to clone the source code for the app. You can do this by using this command git clone https://github.com/LondheShubham153/reddit-clone-k8s-ingress.git

Containerize the Application using Docker

  • Write a Dockerfile with the following code:

FROM node:19-alpine3.15

WORKDIR /reddit-clone

COPY . /reddit-clone

RUN npm install 

EXPOSE 3000

CMD ["npm","run","dev"]

Building Docker-Image

Now it's time to build a Docker Image from this Dockerfile. docker build -t <DockerHub_Username>/<Imagename> . use this command to build a docker image.

Push the Image To DockerHub

  • Then use docker push <DockerHub_Username>/<Imagename> for pushing to the DockerHub.

  • You can use an existing docker image i.e. trainwithshubham/reddit-clone for deployment.

Write a Kubernetes Manifest File

Now, You might be wondering what this manifest file in Kubernetes is. Don't worry, I'll tell you in brief.

Write Deployment.yml file

Let's Create a Deployment File For our Application. Use the following code for the Deployment.yml file.

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: trainwithshubham/reddit-clone
        ports:
        - containerPort: 3000

kubectl apply -f Deployment.yml

kubectl get deployment

Write Service.yml file

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

kubectl apply -f Service.yml

kubectl get services

Expose the app

expose our service:

minikube service reddit-clone-service --url (reddit-clone-service is a service name)

curl -L http://192.168.49.2:31000

Here we app is running in the CLI terminal

expose our deployment :

kubectl expose deployment reddit-clone-deployment --type=NodePort

To run the application in the browser :

open port: 3000 in a security group

kubectl port-forward svc/reddit-clone-service 3000:3000 --address 0.0.0.0

kubectl port-forward svc/reddit-clone-service 3000:3000 --address 0.0.0.0 &

Let's Configure Ingress

Ingress:

An API object that manages external access to the services in a cluster, typically HTTP.

Ingress may provide load balancing, SSL termination and name-based virtual hosting.

Let's write ingress.yml and put the following code in it:

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: 3000

Minikube doesn't enable ingress by default; we have to enable it first using the minikube addons enable ingress command.

curl -L domain.com/test

Now application running in the CLI terminal using ingress.