Reddit Clone with Kubernetes & Ingress

Introduction:

Kubernetes, with its container management capabilities, is a powerful tool but can be intimidating for newcomers. Minikube is your trusty companion on your journey to mastering Kubernetes. It's like a miniature version of Kubernetes that you can run on your own computer, providing a safe environment for experimentation and learning. In this guide, we'll walk you through setting up Minikube on your Linux machine and deploying a Reddit clone application step by step.

Prerequisites:

Before diving into this exciting project, make sure you have the following prerequisites in place:

  1. Basic Knowledge of Kubernetes: Understanding Kubernetes objects like Pods, Deployments, Services, and Ingress.

  2. DockerHub Account: You'll need an active DockerHub account for building and hosting your Docker images.

  3. Git: Git should be installed on your Ubuntu machine.

  4. Docker & Minikube Installed: If not, refer to our installation guide for instructions.

Setting Up the Development Environment:

To begin, let's set up the development environment by creating an EC2 instance with the following configuration: (AMI-Ubuntu, Type-t2.medium)

Once the instance is ready, execute the following commands to update the system and install Docker

# Update all installed packages to the latest version
sudo apt-get update

# Install Docker
sudo apt-get install docker.io -y

# Grant superuser privileges to run Docker commands
sudo usermod -aG docker $USER && newgrp docker

Installing Minikube and kubectl:

Next, let's install Minikube and kubectl to create and manage Kubernetes clusters:

# Download the Minikube binary
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

# Install the Minikube binary
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Install 'kubectl' using Snap
sudo snap install kubectl --classic

# Start Minikube cluster with the Docker driver
minikube start --driver=docker

Setting Up the Project Code:

Import the project from GitHub to access the necessary files for building the Docker image:

# Clone the project from GitHub
git clone https://github.com/Saurav05/reddit-clone-yt.git

The project includes a Dockerfile used to build the Docker image. Here's the Dockerfile content:

FROM node:19-alpine3.15

WORKDIR /reddit-clone

COPY . /reddit-clone
RUN npm install 

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

Build the Docker image from the current directory:

docker build . -t <dockerhubusername/reddit>

Log in to DockerHub using the Docker CLI:

docker login

This will help to access your dockerhub account so that you can push the image to the dockerhub

Push the Docker image to DockerHub:

docker push <dockerhubusername>/reddit:latest

Once the image is built, we need to push the image to the Docker hub registry so that the image can be fetched later and used for deployment while running the application

Deploying the Application:

With the Docker image ready, it's time to deploy the application. Create a deployment manifest for Kubernetes named (deployment.yml):

# deployment.yml
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: sauravkhatri/reddit
        ports:
        - containerPort: 3000

The deployment file will create 2 pods with reddit clone image that is fetched from the docker hub with the command(image: sauravkhatri/reddit ). Apply the deployment manifest to create the Pods:

kubectl apply -f deployment.yml

Create a Service to provide a stable IP and port for accessing the Pods:

# service.yml
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

Apply the Service manifest to create the Service (service.yml):

kubectl apply -f service.yml

Once the service is created and run you can get the URL of the application to be accessed through the browser. Use the following command for the service

minikube service reddit-clone-service --url

In order to run the application make sure a firewall or a security group does not block the port 3000.

Run this command to expose the app service can be accessed through a browser

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

Now, you can access the application in your browser using your machine's IP and port 3000.

Enabling Ingress in Minikube:

In minikube ingress comes as an addon we need to enable it before configuring it.

To enable Ingress, run the following command:

minikube addons enable ingress

Apply the Ingress manifest (ingress.yml) to configure Ingress:

# ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-reddit-app
spec:
  ingressClassName: nginx
  rules:
  - host: redditcl.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: reddit-clone-service
            port:
              number: 3000
  - host: "*.redditcl.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: reddit-clone-service
            port:
              number: 3000

Apply the Ingress manifest:

kubectl apply -f ingress.yml

Bind Ingress with the domain of the application:

curl --resolve "redditcl.com:80:<IP of Ingress>" redditcl.com

Upon executing the command we can see the output in the console

Congratulations on successfully deploying the Reddit clone with Minikube and Ingress! You've taken a significant step in mastering Kubernetes, and the possibilities are endless. Happy coding!