Skip to main content

Command Palette

Search for a command to run...

Deploying a Reddit Clone with Kubernetes Ingress

Updated
6 min read
Deploying a Reddit Clone with Kubernetes Ingress
M

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

  1. First We need to expose our deployment so use kubectl expose deployment reddit-clone-deployment --type=NodePort command.

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

    kubectl 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.

W

Nice 🙂👍

S

This project gives the perfect explanation covering k8s deployment, service and ingress to understand in better way. Thank you Maria.., we are expecting many more to come from you and please try to cover something related to EKS deployment in AWS.

Thank you.

J

When I'm executing kubectl apply -f Deployment.yml I get the error The connection to the server localhost:8080 was refused - did you specify the right host or port? I am running both servers on EC2 instances and in the security gropus I've opened ports 3000, 8080, but I can't get passed this error. Thanks!

C

Nice explanation

S
Sunita3y ago

Good Job. Very well Explained.