Deployed a Reddit Clone app with Mongodb on Kubeadm using 2 nodes cluster with Ingress enabled
Prerequisite:
First You have to install some Prerequisites for this deployment. For kubeadm installation
https://github.com/farzshamim/Installation-scripts/blob/main/kubernetes_installation_kubeadm.sh
or you can check my blog as well for installation kubeadm with docker and containerd.
Here, i have created two ec2 instance of t2-medium for a smooth operation but you can choose t2-micro for worker node.
Open the ports in security inbound rule 6443, 31001 and whatever is required as per your preference.
Step 1: Clone the code
https://github.com/farzshamim/reddit-clone-k8s-ingress.git
or you can use the image farzshamim/reddit-clone:latest
Step 2: Containerize the Application using Docker
Build the docker image and push it to docker hub.
Dockerfile:
FROM node:19-alpine3.15
WORKDIR /reddit-clone
COPY . /reddit-clone
RUN npm install
EXPOSE 3000
CMD ["npm","run","dev"]
Step 3: Write a Kubernetes Manifest File.
You can refer to the website https://kubernetes.io/ for the format which are available there.
Write mongo-config.yaml file
For database i have choosen mongodb. In data:
key:value=mongo-url: mongo-service
apiVersion: v1 kind: ConfigMap metadata: name: mongo-config data: mongo-url: mongo-service
2. Write a mongo-secret.yaml file:
In this file, the key:value pairs are specified by encoding in the CLI by using the code : generate yours one by the following
echo -n <username> | base64
echo -n <password> | base64
apiVersion: v1 kind: Secret metadata: name: mongo-secret data: mongo-user: bW9uZ28tdXNlcg== mongo-password: bW9uZ28tcGFzc3dvcmQ=
3. Write a database.yaml file: i.e mongo.yaml
The deployment and service both are in one file. Make sure the labels and selector should be the same. Specify the replicas, container image, and environment of the database you are using in this case: MongoDB and add the secret key reference to the deployment file environment.
The service selector and the deployment label name should be the same and the target port of the service should be same as the deployment container port i.e 27017.
apiVersion: apps/v1 kind: Deployment metadata: name: mongo-deployment labels: app: mongo spec: replicas: 1 selector: matchLabels: app: mongo template: metadata: labels: app: mongo spec: containers: - name: mongodb image: mongo:6.0 ports: - containerPort: 27017 env: - name: MONGO_INITDB_ROOT_USERNAME valueFrom: secretKeyRef: name: mongo-secret key: mongo-user - name: MONGO_INITDB_ROOT_PASSWORD valueFrom: secretKeyRef: name: mongo-secret key: mongo-password --- apiVersion: v1 kind: Service metadata: name: mongo-service spec: selector: app: mongo ports: - protocol: TCP port: 27017 targetPort: 27017
4.Write an web-app.yaml file: i.e reddit-clone.yaml
Here, everything will be the same as above mongo.yaml file. The addition will be:
configMapKeyRef: name: mongo-config key: mongo-url which has been taken from the mongo-config .yaml.
Type: NodePort
with port 3000 redirecting to the external port 31001 to communicate with the browser.
apiVersion: apps/v1 kind: Deployment metadata: name: reddit-clone-deployment labels: app: reddit-clone spec: replicas: 3 selector: matchLabels: app: reddit-clone template: metadata: labels: app: reddit-clone spec: containers: - name: reddit-clone image: farzshamim/reddit-clone:latest ports: - containerPort: 3000 env: - name: USER_NAME valueFrom: secretKeyRef: name: mongo-secret key: mongo-user - name: USER_PWD valueFrom: secretKeyRef: name: mongo-secret key: mongo-password - name: DB_URL valueFrom: configMapKeyRef: name: mongo-config key: mongo-url --- apiVersion: v1 # Indicates this as a service kind: Service metadata: # Service name name: reddit-clone-service spec: selector: # Selector for Pods app: reddit-clone ports: - port: 3000 targetPort: 3000 nodePort: 31001 protocol: TCP type: NodePort
To deploy the app you need to run following the command: First, run the secret and config yaml file by the blow kubectl apply -f command and then the app and database yaml file. kubectl apply -f reddit-clone.yaml
Just Like this create a mongo.yaml using kubectl apply -f mongo.yaml
If You want to check your deployment & Service use the command kubectl get deployment
& kubectl get services
The app is running in your worker node http://43.204.96.206:31001/
Step 4: Configuring Ingress
Pods and services in Kubernetes have their own IP; however, it is normally not the interface you'd provide to the external internet. Though there is a service with node IP configured, the port in the node IP can't be duplicated among the services. It is cumbersome to decide which port to manage with which service. Furthermore, the node comes and goes, it wouldn't be clever to provide a static node IP to an external service. Ingress defines a set of rules that allows the inbound connection to access Kubernetes cluster services. It brings the traffic into the cluster at L7 and allocates and forwards a port on each VM to the service port. This is shown in the following figure. We define a set of rules and post them as source type ingress to the API server. When the traffic comes in, the ingress controller will then fulfill and route the ingress by the ingress rules. As shown in the following figure, ingress is used to route external traffic to the Kubernetes endpoints by different URLs:
Write an ingress.yaml file
Now you can able to create ingress for your service.
kubectl apply -f ingress.yaml
use this command to apply ingress settings.Verify that the ingress resource is running correctly by using
kubectl get ingress ingress-reddit-app
command.
Install minikube to enable ingress:
Minikube doesn't enable ingress by default; we have to enable it first using minikube addons enable ingress
command.
- If you want to check the current setting for addons in minikube use
minikube addons list
command.
Now you can able to create ingress for your service. kubectl apply -f ingress.yaml
use this command to apply ingress settings.
- Verify that the ingress resource is running correctly by using
kubectl get ingress ingress-reddit-app
command.
Expose the app
First We need to expose our deployment so use
kubectl expose deployment reddit-clone-deployment --type=NodePort
command.You can test your deployment using curl -L http://192.168.49.2:31000. 192.168.49.2 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 &
Test Ingress
Now It's time to test your ingress so use the curl -L domain/test command in the terminal.
ou 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.
Get Connected:
If you have any suggestion about this post feel free to let me know and be updated on my blog in the following ways:
#TrainWithShubham #DevOps #chatgpt #AI #devops #devopsengineer #devops2023 #devopscommunity #devopslife #devopsnotes #DevOpsGuys #DevOpsHandbook #devopsinuk #shellscript #linux #kubernetes #kubeadm