Deploying a Voting App: Microservices Architecture Using Docker and Kubernetes
About Project
As the title suggests, this project is about deploying a voting app using Kubernetes. In this application, there is a voting page that lets us choose between Cat or Dog and then displays the result on the result page. The application is fairly simple, but what we learn here is important. This project helped me solidify my basics and implement Kubernetes fundamentals, which are crucial.
This project is a great example of connecting various pieces to create a complete picture, which I enjoy a lot.
I first came across this project during my Kubernetes course by KodeKloud, and it is officially sourced from a GitHub repository named dockersamples. Let's first get introduced to the technologies used:
Microservice: They are independent component that run each application process as a service. These services communicate via a well-defined interface using lightweight APIs. Services are built for business capabilities and each service performs a single function. Because they are independently run, each service can be updated, deployed, and scaled to meet demand for specific functions of an application.
Docker: It is a software platform that allows you to build, test, and deploy applications quickly. Docker packages software into standardized units called containers that have everything the software needs to run including libraries, system tools, code, and runtime. Call it a package of ready-to-mix food packet which contains all ingredient inside the package.
Kubernetes: Kubernetes is open-source software that allows you to deploy and manage containerized applications at scale. It can be thought of as the heat, water, and mixing process needed to turn those ingredients into a delicious dish.
Architecture/Flow of the Application
This application is based on microservices architecture. The diagram below, referred from the official GitHub repository, gives an overview of components of the application:
Note: I am not listing YAML files as you can find them in the GitHub Repository, which you can access using link given in next Section.
Voting App: This component enables users to vote for either a "Cat" or a "Dog" through a webpage. As it is exposed to users, the service type of this component is NodePort.
Redis: This component stores the votes from the Voting App in a key-value manner. It is a type of in-memory cache. As the number of users increases, the number of read-write operations increases as well. If we store the votes directly in a database, it will slow down the system. Hence, we need an in-memory cache that periodically stores data to a permanent database like PostgreSQL. It is a ClusterIP service type as it only communicates with other pods.
Note: If the service type is not mentioned in the YAML file, it is considered a ClusterIP service type by default.
Worker App: This component is connected to Redis and the DB container and continuously reads from the Redis container and writes to the DB container. As it doesn't need to be accessed externally and only performs actions internally, it does not require a service type.
Database(PostgreSQL): This component provides the stored votes to the Result App. As it only communicates with other pods, the service type is ClusterIP.
Result App: This component shows the result of voting through a webpage and also has a service type of NodePort as it is exposed to users.
Application Deployment
Ensure you have Docker and Kubernetes installed. I use Minikube to set up a local Kubernetes cluster.
I have deployed the application using two methods:
Using Docker --link command
Using Kubernetes
We will go through both the methods in this blog.
First, clone the repository. I recommend cloning my repository as the commands I will list are based on it, or you can clone the dockersamples repository, but the commands will change.
git clone https://github.com/sanket-chamate01/voting-app-kubernetes-deployment.git
To make it simple, Docker images are already published on my DockerHub account, so there is no need to build images. However, I recommend you build your own images and use them as it will help you more in your journey ahead.
Docker Way of Deploying the Application
Make sure Docker is installed on your system.
Running Redis Container
docker run -d --name=redis redis
Running PostgreSQL Container
docker run -d --name=db -e POSTGRES_HOST_AUTH_METHOD=trust postgres:9.4
Note: "POSTGRES_HOST_AUTH_METHOD=trust" implies that you don't need a username and password to access the database. This method is not recommended for production, but as we are the only ones using this application, it is fine. Use a username and password for production-level projects.
Running Voting App Container
docker run -d --name=vote -p 5000:80 --link redis:redis sanket01/voting-app-vote-app
Running Result App Container
docker run -d --name=result -p 5001:80 --link db:db sanket01/voting-app-result-app
Running Worker App Container
docker run -d --name=worker --link db:db --link redis:redis sanket01/voting-app-worker-app
Note: The usage of "--link" is not the recommended way for inter-container communication in Docker. For a production environment, consider using Docker networks instead.
Visit localhost:5000 to access the vote-app. Visit localhost:5001 to access the result-app.
Kubernetes Way of Deploying the Application
All the required YAML files are in the repository. Make sure to change directory to k8-pods
by running cd k8-pods
command to access all the YAML files.
Deploy Vote App Pod and Service
kubectl create -f vote-app-pod.yaml kubectl create -f vote-app-service.yaml
Deploy Redis Pod and Service
kubectl create -f redis-pod.yaml kubectl create -f redis-service.yaml
Deploy Database(PostgreSQL) Pod and Service
kubectl create -f postgres-pod.yaml kubectl create -f postgres-service.yaml
Deploy Worker App Pod
kubectl create -f worker-pod.yaml
Deploy Result App Pod and Service
kubectl create -f result-app-pod.yaml kubectl create -f result-app-service.yaml
To access the Voting webpage, use the provided URL after running the command:
minikube service vote-app-service --url
To access the Result webpage, use the provided URL after running the command:
minikube service result-app-service --url
Let's See the Result of Our Work
Great! We have successfully deployed the application.
Minikube is resource-intensive, so make sure to clean up and delete all resources:
kubectl delete pods,services -l app=vote-app
kubectl delete pods,services -l app=result-app
kubectl delete pods,services -l app=redis
kubectl delete pods,services -l app=postgres
kubectl delete pods -l app=worker
Summary
This article guides you through deploying a simple voting app using Docker and Kubernetes. The app consists of multiple microservices: a Voting App, Redis for in-memory caching, a Worker App, a PostgreSQL database, and a Result App. You'll learn how to deploy these components individually using Docker containers and orchestrate them using Kubernetes. Additionally, the article provides steps for setting up the environment, running the application, and cleaning up resources post-deployment.
Subscribe to my newsletter
Read articles from Sanket Chamate directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Sanket Chamate
Sanket Chamate
I am a problem solver who enjoys exploring the inner workings of everything. Interested and curious about a wide range of topics.