Deploying a Reddit Clone on Kubernetes with Ingress Enabled

1. Pre-requisites:

  • EC2 Instances:

    • CI server: t2.micro

    • CD server: t2.xlarge(To avoid disk-space issue)

  • Install Docker

  • Install Minikube

  • Install kubectl

2. Installation Steps:

Step 1: Set up EC2 Instances
  1. Launch an EC2 instance with the following specifications:

    • AMI: Ubuntu

    • Instance Type: t2.micro for the CI server, t2.xlarge for the CD server.

Step 2: Install Docker on CI server
sudo apt update
sudo apt install -y docker.io
sudo usermod -aG docker ubuntu
newgrp docker
Step 2: Clone the Source Code on CI server
git clone https://github.com/gmanne11/reddit-clone-k8s-ingress.git
cd reddit-clone-k8s-ingress

Step 3: Install Kubectl & Minikube on CD server

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install kubectl /usr/local/bin/kubectl
chmod +x ./kubectl
kubectl version

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
sudo apt install -y docker.io
sudo usermod -aG docker $USER
minikube start --driver=docker
minikube status
Step 4: Containerize the Application
  1. Dockerfile:

FROM node:19-alpine3.15

WORKDIR /reddit-clone

COPY . /reddit-clone

RUN npm install 

EXPOSE 3000

CMD ["npm","run","dev"]
  1. Build and push the Docker image to DockerHub.
docker login
docker build -t vivekmanne/reddit-clone:v1 .
docker push vivekmanne/reddit-clone:v1

Step 7: Write Kubernetes Manifest Files
  1. Deployment.yml:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reddit-clone-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: reddit-clone
  template:
    metadata:
      labels:
        app: reddit-clone
    spec:
      containers:
        - name: reddit-clone
          image: vivekmanne/reddit-clone:v1
          ports:
            - containerPort: 3000
  1. Service.yml:
apiVersion: v1
kind: Service
metadata:
  name: reddit-clone-service
spec:
  type: NodePort
  selector:
    app: reddit-clone
  ports:
    - port: 3000
      targetPort: 3000
      nodePort: 31000
  1. Ingress:

    In Kubernetes, each service has a unique IP address, and each pod also has its own IP. However, pods are ephemeral, meaning they can come and go, resulting in constantly changing IPs. Exposing these IPs directly is not a best practice.

    To address this, we use services to expose applications to the outside world. However, using a LoadBalancer type service results in each service having its own load balancer, potentially increasing costs.

    Moreover, these services do not offer enterprise-level load balancing capabilities such as host/path-based routing, ratio-based routing, TLS/SSL termination, WAF, or blacklisting/whitelisting,sticky-sessions etc..

    To overcome these limitations, enterprise-level load balancers developed Ingress controllers. Users deploy these controllers inside the Kubernetes cluster. The Ingress controller then implements routing rules defined in Ingress resource YAML files, providing advanced load balancing capabilities.

    This approach not only adds advanced load balancing features but also potentially saves costs by utilizing only one load balancer for the Ingress controller.

    Ingress.yml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: reddit-clone-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: “domain.com”
      http:
        paths:
          - path: "/test"
            pathType: Prefix
            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 8: Deploy the Application to Kubernetes
kubectl apply -f deployment.yml
kubectl apply -f service.yml
Step 9: Configure Ingress
minikube addons enable ingress
minikube addons list
kubectl apply -f ingress.yml
Step 10: Expose the Application
  1. To access the service created with a NodePort type, you can use the following command:
curl -L http://minikube_ip:31000
  1. Replace minikube_ip with the IP address of your Minikube instance and 31000 with the assigned NodePort

  2. To test locally with Ingress, you can use:

     curl -L http://domain.com/test
    
    1. For local testing, you can also expose the service using port forwarding:
    kubectl port-forward svc/reddit-clone-service 3000:3000 --address 0.0.0.0
  1. After port forwarding, you can access the service using:
    http://ec2_ip:3000

Note:- Make sure you open the 3000 port in a security group of your Ec2 Instance.

Congratulations !! You have successfully deployed a Reddit clone on Kubernetes with Ingress enabled.👏👍

0
Subscribe to my newsletter

Read articles from Gopi Vivek Manne directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Gopi Vivek Manne
Gopi Vivek Manne

I'm Gopi Vivek Manne, a passionate DevOps Cloud Engineer with a strong focus on AWS cloud migrations. I have expertise in a range of technologies, including AWS, Linux, Jenkins, Bitbucket, GitHub Actions, Terraform, Docker, Kubernetes, Ansible, SonarQube, JUnit, AppScan, Prometheus, Grafana, Zabbix, and container orchestration. I'm constantly learning and exploring new ways to optimize and automate workflows, and I enjoy sharing my experiences and knowledge with others in the tech community. Follow me for insights, tips, and best practices on all things DevOps and cloud engineering!