Deploying a Reddit Clone with Ingress in Kubernetes using Minikube
Hands-On Kubernetes: Mastering Ingress with a Reddit Clone Deployment in Minikube
Table of contents
- Step 1: Clone the source code of the project
- Step 2: Build the Dockerfile
- Step 3: Push the docker image to Docker Hub
- Step 4: Creating a Deployment Manifest for K8s
- What is a Deployment?
- Step 5: Create a Service Manifest for K8s
- Step 6: Test your application
- Step 7: Configuring Ingress
- 1. Enable Ingress in Minikube
- 2. Write the Ingress K8s Manifest
- 3. Test the Ingress
- Well Done on Your Reddit Clone Deployment! 🔥
Welcome back, fellow Kubernetes explorers! In our previous blog, we took you on a journey to set up Minikube on your Linux machine. If you haven't already installed Minikube, make sure to check out our guide here as it's the first step toward today's exciting adventure.
We're diving deeper into the Kubernetes universe in this hands-on project guide. But, before we begin this exciting Reddit clone deployment journey, let's make sure you have the following prerequisites:
Basic Knowledge of Kubernetes: This adventure assumes that you have a basic understanding of Kubernetes objects such as Pod, Deployment, Service, and Ingress.
DockerHub Account: This blog requires an active DockerHub account that will be used to upload and download the docker image we will be building. You can create an account by visiting https://hub.docker.com/
Git: Git installed on your Ubuntu machine
Docker & Minikube Installed: If you haven't already set up docker & Minikube cluster, please refer to our installation guide here to get started.
With all the prerequisites satisfied, let’s dive into our project!
Step 1: Clone the source code of the project
Run the given command in your Linux terminal to download the project files
git clone https://github.com/kunal-gohrani/reddit-clone-k8s-ingress.git
Since the project is evolving continuously, we will be using the branch blog for the purpose of this guide. Let’s checkout into the blog branch using the command:
git checkout blog
Step 2: Build the Dockerfile
The project folder includes a Dockerfile that will be used to build the image.
COPY . /reddit-clone
RUN npm install
Run the below-given commands inside the root of the project folder to build the docker image, replace the placeholder
<username> with your DockerHub username.
docker build . -t <username>/reddit-clone:latest
Use the command
docker images to view your newly built image, the output should be similar to this:
Step 3: Push the docker image to Docker Hub
After building the image, we need to push it to docker hub, our Kubernetes deployment will later fetch the same image from docker hub to run the app.
Login to DockerHub from docker CLI:
This step is crucial to push docker images. Run the given command to log in to docker hub with your username and password.
Push the Docker image to DockerHub:
Use the command
docker push <username>/reddit-clone:latest to push the image, replace the placeholder
<username> with your username.
After pushing the image, refresh your DockerHub website, and you will be able to see a new repository has been created containing your docker image.
Step 4: Creating a Deployment Manifest for K8s
Congrats on reaching here! 🥳 You have now successfully built a docker image and uploaded it to Docker Hub, thus completing the basic steps of the continuous integration Process.
Now we will be focusing on deploying the docker image in a K8s cluster. For this, we will be using the Deployment object of K8s to create Pods that run our image.
What is a Deployment?
In K8s, a Deployment object acts like the manager of the Pods, It ensures that the specified number of pod replicas with the desired container images are running normally. If a pod encounters problems or needs an update, the Deployment handles it seamlessly while maintaining the desired number of pods. K8s objects are declared using YAML files and are often referred to as manifests. You can read more about the Deployment object here.
You can view the
deployment.yml file present in the project folder or copy it from here.
- name: reddit-clone
- containerPort: 3000
Make sure to replace the value of
image key with that of your image name as shown in the YAML file.
The deployment creates 2 pods running 1 container each with the reddit-clone image we pushed earlier. The key containerPort declares that the container accepts connections from port 3000.
kubectl apply -f deployment.yml to create the deployment object in K8s. You should see an output similar to this:
kubectl get deployment and
kubectl get pods to ensure that your deployment has been successfully created and pods are running. Your output should look like this:
Step 5: Create a Service Manifest for K8s
Our next step is to create a service object that will allow us to connect to the pods created by the deployment file.
A Service in K8s serves as a link between distinct pods or microservices inside a cluster. Consider it a well-known phone number in a directory that enables pods to connect and converse despite their dynamic nature or changing IP addresses. Services are critical because they provide a consistent and discoverable endpoint for applications, as well as load balancing and abstraction of underlying pod modifications. The dynamic and scalable nature of Kubernetes would make it difficult for pods to identify and interact with one another without Services. You can read more about Service Objects here.
You can view the
service.yml file present in the project folder or copy the one below and paste it into your YAML file
# Indicates this as a service
# Service name
# Selector for Pods
# Port is the port service is gonna listen to
- port: 3000
# Target port is the port container is listening to
# We are using ClusterIP service which is not directly
# accessible from outside the cluster, other types of services
# are NodePort, LoadBalancer
kubectl apply -f service.yml to create this service in K8s. Run
kubectl get svc to check if the service has been created, the output should look like this:
Step 6: Test your application
Now it is time to test our deployed application. Since our service object is of the type ClusterIP, it is not accessible outside the cluster, but for the purpose of testing, we can forward all requests received in a specific port on the host to the service port using
kubectl port-forward command.
Make sure port 3000 is not blocked by a firewall or a security group if you are running Linux on the cloud, This is crucial for testing the app.
You need to note the IP of the machine Minikube is running in, use
ifconfig command on Linux to find your machine’s IP address.
Run the command
kubectl port-forward svc/reddit-clone-service 3000:3000 --address 0.0.0.0 After running this command, keep the terminal open.
Now in your browser, open the URL
<LinuxIP>:3000 Replace the placeholder
<LinuxIP> with the IP of the Linux machine you noted above. If everything is configured well, you should see a site similar to this:
and in your terminal running the port-forward command, the output should look something like this:
The app has now been successfully deployed! Congratulations on reaching this far! 🥳
Now we will be configuring ingress.
Step 7: Configuring Ingress
Ingress is a clever traffic management and routing solution for Kubernetes apps running within the cluster. While LoadBalancer and NodePort Services are useful for exposing specific services, Ingress offers a more advanced solution. It serves as a single entry point for various services, making it an excellent solution when you need to access numerous microservices via distinct URLs or domains. You can read more about ingress and ingress controllers here
1. Enable Ingress in Minikube
In Minikube, ingress comes as an addon and we need to enable it before configuring it. Run
minikube addons enable ingress in the terminal to enable ingress. The output should be like this:
2. Write the Ingress K8s Manifest
You can use the
ingress.yml present in the project folder or copy the YAML from here:
- host: redditclone.com
- pathType: Prefix
# Port Service is listening on
- host: "*.redditclone.com"
- pathType: Prefix
# Port Service is listening on
We have used the domain redditclone.com as our entry point to the ingress Create the ingress rule using the command
kubectl apply -f ingress.yml
and then run
kubectl get ingress, the output should be like this:
We need to wait for the Address column to be populated, it will take some time before it is so keep checking
kubectl get ingress.
After the address column is populated like this
Note down the IP displayed in the address column.
3. Test the Ingress
We have now successfully deployed the ingress and now we can test it. To test the ingress, we need to send a request to
redditclone.com , however, we don’t own this domain, and there’s no DNS record pointing redditclone.com to our cluster. So, we will be using curl command to forcefully resolve redditclone.com to the IP of ingress as noted above. The command is:
curl --resolve "redditclone.com:80:<IP of Ingress>" redditclone.com
Upon executing this command, we immediately get a rather big output of the HTML file which is of our Reddit clone.
NOTE: If you are running minikube in a linux machine with GUI and want to access redditclone.com from your browser, you can edit /etc/hosts file using vi to add a line with the format like:
<IP of Ingress>
redditclone.com The file should then look something like this:
After saving the file, you should be able to access the app by using URL redditclone.com in your browser.
Well Done on Your Reddit Clone Deployment! 🔥
Congratulations on successfully deploying the Reddit clone app with Minikube! You've unlocked the door to the Kubernetes world, and this is just the beginning. Keep exploring, learning, and building with Kubernetes—it's a journey filled with endless possibilities.
If you run into issues while deploying this app or have some suggestions on improving the blog or just want to reach out to showcase your deployment, please contact me on LinkedIn.
Thank you fellow K8s adventurers, Do follow me for more such exciting blogs on K8s, Docker, and Linux. 🧑🏻💻