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
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
- Dockerfile:
FROM node:19-alpine3.15
WORKDIR /reddit-clone
COPY . /reddit-clone
RUN npm install
EXPOSE 3000
CMD ["npm","run","dev"]
- 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
- 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
- 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
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
- To access the service created with a NodePort type, you can use the following command:
curl -L http://minikube_ip:31000
Replace
minikube_ip
with the IP address of your Minikube instance and31000
with the assigned NodePortTo test locally with Ingress, you can use:
curl -L http://domain.com/test
- 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
- 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.👏👍