DevOps Project - 3

Deploy a Reddit clone using Kubernetes Ingress

DevOps Project - 3

The figure below shows the flow of our project. In this, we are going to take some code(Reddit clone) from GitHub to a t2.micro instance where Docker is installed. This t2.micro instance will be a CI server where we will build the code, test it and then push it into a repository. That repository is going to be Dockerhub.

Then we need another server which is going to be our deployment server. Here we will have a Kubernetes setup which will deploy our image on a scale. This is going to be a heavy server, so make sure you have a t2.xlarge instance, not a t2.micro.

Prerequisites

First of all, here is the link to the Reddit clone. Click here. Fork it.

Then we need to launch two EC2 instances. One will be our CI Server and another will be our Deployment server.

CI - Server

Let us do all the work we need to do on our CI server.

First, we need to install Docker on this server.

So connect to our CI-Server and copy and paste these commands.

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

Now once our Docker is installed, we need to bring the code from GitHub. So clone the repository. Use the command,

git clone <repository_URL>

Get the repository URL from the forked repository. As shown in the screenshot,

Now your code is available on CI-Server. Now we need to build this code. We already have a Dockerfile available in the source code.


FROM node:19-alpine3.15

WORKDIR /reddit-clone

COPY . /reddit-clone

RUN npm install 

EXPOSE 3000

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

Now we need to build a docker image from this Dockerfile and push it to Dockerhub. Run the command,

docker build . -t <username/image_name>

for example,

docker build . -t iamnaved/reddit-clone

After hitting enter you will see this kind of output,

After the command is successful, we need to push the image to Dockerhub so that we can deploy it on Kubernetes.

So we need to log in to Docker through our terminal. Run the command,

docker login

Then it will ask you for your username and password. Enter them and you will be logged in as shown in the screenshot.

Now to push the image to Dockerhub, run the command,

docker push <username/image_name>

for example,
docker push iamnaved/reddit-clone:latest

As you can see in the screenshot, your image is being pushed to Dockerhub.

So our CI part is done. We brought the code from GitHub, built it using docker and pushed it to dockerhub. So the first half of our project was successful.

Deployment Server

Now let us start with the deployment server.

Connect to the Deployment server. We need to install Docker, minikube and kubectl on this server. Run these commands,

# 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

After successfully installing all these on our deployment server, we need to deploy the image which is available on Dockerhub.

So first we need to write Deployment. Here it is:

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

Make a folder on your instance, inside that create a Deployment.yaml file and paste the above code inside it. Now to deploy the application, run the command:

kubectl apply -f Deployment.yaml

Now to check the deployments, run the command:

kubectl get deployment

You will see this output,

You can manage the replicas as per your needs. Just simply update the number of replicas in the Deployments.yaml file.

Now how do we access our application?

For that, we will use a feature of Kubernetes which is known as 'Service'. So we need to create a Service.yaml file. Here it is:

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

Copy this and paste it into the Service.yaml file. Then run the command and your service will be created,

kubectl apply -f Service.yaml

Now you can access your application.

For that run the command:

minikube service reddit-clone-service --url

You will get a URL after executing this command.

Now run the command,

curl -L <URL>

Your application will run on the terminal itself.

But what if you want to run it on your browser? For that, you need to expose your deployment.

First, go to the security groups of your deployment server and add an inbound rule to make port 3000 available externally, and make it anywhere accessible.

Now run these commands:

kubectl expose deployment reddit-clone-deployment --type=NodePort
kubectl port-forward svc/reddit-clone-service 3000:3000 --address 0.0.0.0 &

Now open a new tab and enter <instance_IP:3000>, you will see your application running.

Ingress

Kubernetes Ingress is an API object that manages external access to services within a cluster.

First, we need to enable ingress on our minikube. Run the command:

minikube addons enable ingress

Create a file named ingress.yaml. Copy the below code and paste it into 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

Run the command:

kubectl apply -f ingress.yaml

Now, run this command:

curl -L domain.com/test

You will see your application running.

Outro

Congratulations, you successfully deployed a Reddit clone using Kubernetes ingress.

Stay connected with me for more blogs in this DevOps Project blog series.