Deploying a Reddit Clone on Kubernetes with Ingress for Streamlined External Access and Routing
🕸️ What is Ingress in Kubernetes⁉️
In Kubernetes, Ingress is an API object used to manage external access to services within a cluster. It acts as a smart router or traffic manager for incoming HTTP and HTTPS traffic, allowing you to define rules for how traffic should be directed to different services based on factors like hostnames, paths, and more. Think of Ingress as a gateway that controls how external traffic flows into your Kubernetes cluster.
🕸️ Why Use Ingress in Kubernetes⁉️
Ingress is valuable for several reasons:
Centralized Routing: Instead of exposing each service individually to the internet, Ingress provides a centralized entry point for routing traffic. This simplifies external access management and reduces complexity.
Path-Based Routing: Ingress allows you to route traffic to different services based on URL paths. For example, you can route traffic to
/app1
to one service and/app2
to another, all using a single external IP address and port.Host-Based Routing: You can route traffic to different services based on hostnames (domain names). This is useful for hosting multiple websites or applications on the same cluster, each with its own domain.
Load Balancing: Ingress controllers often include built-in load balancing, distributing traffic evenly among pods in a service. This improves application availability and scalability.
TLS Termination: Ingress can handle SSL/TLS termination, allowing you to encrypt traffic between clients and the Ingress controller. This simplifies SSL certificate management for your services.
🕸️Hands-On For Understanding
- Let's create a Reddit clone on Kubernetes with ingress enabled
Prerequisites
Before you start, make sure you have the following prerequisites installed on an Ubuntu EC2 instance:
EC2 instance with Ubuntu (AMI: Ubuntu, Type: t2.medium)
Docker
Minikube
kubectl
Here we make use of two servers , one is CI server (uset t2.micro) for getting the code from github , building the image and then pushing it to the docker hub !!
On deployment server (use t2.medium to make it more scalable) ,we setup Kubernetes which will make our reddit-clone-application more Scalable
CI-Server:
Step 1: Clone the Source Code First
You need to clone the source code for the Reddit clone application from GitHub. Open your terminal and run the following command:
git clone https://github.com/srahul0502/reddit-clone-k8s-ingress.git
Step 2: Containerize the Application using Docker
This step involves creating a Docker image for your application. You'll need to create a Dockerfile with the following content:
FROM node:14-alpine
WORKDIR /reddit-clone
COPY . /reddit-clone
RUN npm install
EXPOSE 3000
CMD ["npm", "run", "dev"]
Then, build the Docker image:
docker build -t <DockerHub_Username>/<Imagename> .
Replace <DockerHub_Username>
and <Imagename>
with your Docker Hub username and the desired image name.
Step 3: Push the Image to DockerHub
Push the Docker image to DockerHub so that Kubernetes can access it. First, log in to your DockerHub account:
docker login
# it will ask for username and password
Then, push the image:
docker push <DockerHub_Username>/<Imagename>
Deployment-Server:
Step 4: Write Kubernetes Manifest Files In Kubernetes
You define your application and its configuration using YAML files. You'll need to create two YAML files: Deployment.yml
and Service.yml
.
Here's an example of 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: <DockerHub_Username>/<Imagename>
ports:
- containerPort: 3000
And here's an example of 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
Step 5: Deploy the Application to Kubernetes
Now, deploy your application to Kubernetes using the following commands:
kubectl apply -f Deployment.yml
kubectl apply -f Service.yml
You can check the status of your deployment and service using these commands:
kubectl get deployment
kubectl get services
Step 6: Configure Ingress
Ingress is used to route external traffic to your Kubernetes services. Create an ingress.yml
file with the following content:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-reddit-app
spec:
rules:
- host: "domain.com" # Replace with your domain or IP address
http:
paths:
- pathType: Prefix
path: "/test"
backend:
service:
name: reddit-clone-service
port:
number: 3000
- host: "*.domain.com" # Replace with your domain or IP address
http:
paths:
- pathType: Prefix
path: "/test"
backend:
service:
name: reddit-clone-service
port:
number: 3000
Enable Ingress in Minikube (if not already enabled):
minikube addons enable ingress
Minikube doesn't automatically activate the Ingress feature by default; you need to enable it explicitly using the command
minikube addons enable ingress
.If you want to inspect the current status of Minikube's addons, you can use the command
minikube addons list
.Once Ingress is enabled, you can proceed to create an Ingress resource for your service using
kubectl apply -f ingress.yml
. This step sets up the routing rules for external traffic.To confirm that the Ingress resource is correctly configured and operational, you can run the command
kubectl get ingress ingress-reddit-app
. This command will provide information about the Ingress resource's status and configuration.
Apply the Ingress configuration:
kubectl apply -f ingress.yml
Check the status of the Ingress:
kubectl get ingress ingress-reddit-app
Step 7: Expose the Application
Expose your deployment using the following command:
kubectl expose deployment reddit-clone-deployment --type=NodePort
This command is used to create a network route to a service. In this case, it's creating a route to the
reddit-clone-deployment
deployment.--type=NodePort
specifies the type of service you want to expose. NodePort is one type that exposes a specific port on every Node in the cluster.
You can access your application using the Minikube IP and NodePort:
curl -L http://<Minikube_IP>:<NodePort>
You can test your deployment using curl -L <minikube-ip> is a minikube ip & Port 31000 is defined in Service.yml
Then We have to expose our app service
kubectl port-forward svc/reddit-clone-service 3000:3000 --address 0.0.0.0 &
Step 8: Test Ingress
Test your Ingress configuration using the following command (replace domain
with your domain or IP):
curl -L http://domain/test
You should also be able to access your deployed application using your EC2 instance's IP address and port 3000. Make sure you've opened port 3000 in your EC2 instance's security group.
Congratulations! You've successfully deployed a Reddit clone on Kubernetes with Ingress.
I hope you understood the concept , and can make a reddit clone !!
Happy Learning :D