[AWS] Highly available & Scalable Containerized Application using Docker, Kubernetes
Project Overview
⭐ GitHub Repo For This Project ⭐In this project we are going to build a scalable web application using Docker and Kubernetes, deploy it on AWS, and integrate monitoring services. The web application will be developed in Python and deployed in Docker containers. Use AWS's EC2 instances for virtualization and leverage AWS's managed Kubernetes service, EKS.
Objectives:
- Develop a Python-based web application: that is containerized using Docker to ensure portability and consistency across different environments.
- Deploy the Dockerized application: on Amazon EC2 instances, leveraging AWS's infrastructure for scalable and reliable hosting.
- Implement Kubernetes for container orchestration: using Amazon EKS to manage and scale the application efficiently across multiple instances.
Tools & Technologies
- VS Code (Source Repository): VS Code is simply an Integrated Development Environment (IDE) used to write computer programs of all kinds, in all types of programming languages. For this project we used React JS (JavaScript) as our primary programming language, along with some HTML and CSS code. This is our source repository where we will be developing and making changes to our source code, and it is directly connected to GitHub (Version Control).
- GitHub (Version Control): GitHub is simply a web-based platform for version control and collaboration on software development projects. It also allows us to host and manage code repositories. GitHub is the industry standard when it comes to hosting code repositories online. After we make changes to our source repository, the changes made will be ‘pushed’ to GitHub and finally these changes will be pulled from GitHub and deployed to our actual application.
- Docker (containerization): Application to containerize our application and push our dockerimages to our dockerhub repository.
- Kubectl (orchestration): Kubernetes Command-Line interface which will be used to setup kubernetes and provision resources in kubernetes.
Deliverables
- Functional CI/CD Pipeline: A fully operational Continuous Integration and Continuous Deployment pipeline configured in AWS, automating the build, testing, and deployment processes for our python application.
- Deployment Configuration Files: Deployment and Service configuration files that will be used to setup the service account used in kubernetes as well as the deployments instructions kubernetes will use to deploy our application.
- Documentation (This Document): Comprehensive documentation outlining the project setup, configuration steps, user guide, and maintenance procedures, including instructions on how to modify or extend the application.
Why containerization?
Containerization offers several benefits, especially in modern software development and deployment:
- Consistency Across Environments: Containers package applications with all their dependencies, ensuring that they run the same way regardless of where they are deployed (e.g., development, testing, production environments).
- Efficient Resource Usage: Containers are lightweight and share the host system’s kernel, making them more efficient in terms of resource usage compared to traditional virtual machines.
- Scalability and Flexibility: Containers can be easily scaled up or down, allowing applications to handle varying loads efficiently. They also enable microservices architectures, where different parts of an application can be developed, deployed, and scaled independently.
Architectural Diagram
Implementation
Develop and Dockerize Python Application
Firstly, I installed Python on my machine, you can go over to python.org and follow the instructions there on how to properly install Python. Then, I created and navigated to a folder called ‘newpython’ that I will be using to store all the files for this project. I then created and activated a virtual environment by running the following commands:
#this command creates a new virtual environment called venv
python -m venv venv
&
#this command activates our virtual environment
venv\Scripts\activate
Create the Flask Application
Now still inside the ‘newpython’ folder is where all our python files will be created. The first file will be the actual Python file that contains all the logic for our simple python app. I made use of Flask, which is lightweight web framework for Python that we can use to quickly build a web app.
To code the Flask based python file I navigated over to VS Code and created a new file in our working directory for this project ‘newpython’ and called the file ‘app.py’. Below is the simple python code for the web app. Below is the code for our python web app.
This app simply provides an API response that will return a message reading: ‘"Hello, welcome to your Flask app running in Docker!", when the ‘/greet’ API request is made. We also expose the app on port 5000.
Install Flask
For this to work we would need to have Flask installed. To do this I went back to my terminal and ran the following command:
pip install Flask
We also have to create a file that we will call ‘requirements.txt’ in which we will list all of the dependencies for our python app to work. These dependencies are ‘Flask’ and ‘Requests’.
Dockerize the Application
We can save and close the ‘requirements.txt’ file and begin the process of containerizing the Flask application, which is simply a method of packaging an application and its dependencies together into a container.
At this point we would need to download and install Docker onto our machines.
You can simply search up how to install Docker or simply go over to docker.com and follow the instructions there. After that was done, I proceeded to create a dockerfile, which is just text file that contains a series of instructions on how to build a Docker image. In the same directory I have been working from, I created a new dockerfile called ‘Dockerfile’ and wrote the following into the file:
# Use an official Python runtime as a parent image
FROM python:3.8-slim
# Set the working directory in the container
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Install any needed packages specified in requirements.txt
RUN pip install flask
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME=World
# Run app.py when the container launches
CMD ["python", "app.py"]
Next we will proceed to build the docker file using the terminal with the following command:
#This command creates builds the docker file and names it flask-app.
docker build -t flask-app .
#This command builds and actually containerizes our application using docker. At this point we should have Docker Desktop up and running.
docker run -p 5000:5000 flask-app
We can go over to Desktop and view our now containerized application.
Installing awscli, eksctl
If you haven't already installed and configured the AWS CLI, eksctl, or kubectl, you can follow this link and continue this project when you are done.
1. Verifying AWS CLI and eksctl Installation:
aws -–version
The command above displays the current aws cli version running on my pc
eksctl version
This command displays the current eksctl version running on my pc
aws configure
The command above configures the aws cli
2. Create EKS Cluster:
The next step was to use eksctl to create a new EKS cluster where we will deploy our dockerized application to in my aws account. Below is the command used to do this:
eksctl create cluster --name my-eks-cluster --version 1.28 --region us-east-1 --nodegroup-name linux-nodes --node-type t2.micro --nodes 2 --nodes-min 1 --nodes-max 4 –managed
this command creates an EKS cluster in aws region us-east-1, and names the cluster ‘my-eks-cluster’. We also assign 2 nodes to the cluster with a minimum of 1 node and a maximum of 4 managed nodes.
I then verified the cluster creation with:
eksctl get cluster --name my-eks-cluster
After running the above command, we get the following output that verifies that we have successfully created our EKS cluster.
A quick look at my AWS account also verifies this.
Deploy the Dockerized Application to EKS
1. Create Kubernetes Deployment and Service Configurations
Now before we deploy our Dockerized application to our EKS cluster, we need to write Kubernetes deployment and service files. I went back to VS Code and created a new .yaml file named ‘deployment.yaml’ which I specified the configurations for the deployment and the desired state for deploying my Dockerized Python/Flask application. See the Kubernetes deployment code below:
Kubernetes Deployment Configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-app
spec:
replicas: 3
selector:
matchLabels:
app: flask-app
template:
metadata:
labels:
app: flask-app
spec:
containers:
- name: flask-app
image: supertonka/flask-app:latest
ports:
- containerPort: 5000
I also wrote a Kubernetes service configuration file named `service.yaml` the purpose of this file is to expose the Flask application. See the Kubernetes service code below:
Kubernetes Service Configuration
apiVersion: v1
kind: Service
metadata:
name: flask-app-service
spec:
type: LoadBalancer
selector:
app: flask-app
ports:
- protocol: TCP
port: 80
targetPort: 5000
2. Apply Kubernetes Configuration
I used `kubectl` to apply the deployment and service configuration files:
kubectl apply -f deployment.yaml
applies the Kubernetes deployment configuration file
kubectl apply -f service.yaml
applies the Kubernetes service configuration file
I then verified that the deployment and service were running correctly by checking their status using the following commands:
kubectl get deployments
returns list of Kubernetes deployments
kubectl get services
returns list of running Kubernetes services
This guide should cover the steps required to set up and deploy your Dockerized Python application on an Amazon EKS cluster, including configuring and verifying everything as you described.
Challenges Faced and Solutions Implemented
1. Containerization
- Challenge: Getting started with Docker for containerization was tricky, especially managing multiple services.
- Solution: I broke down the process into steps, created efficient Dockerfiles, and used Docker Compose to manage everything smoothly.
2. Kubernetes (EKS) Configuration
- Challenge: Configuring Amazon EKS was challenging due to its complexity.
- Solution: I followed best practices and monitored the cluster to ensure everything ran smoothly.
Conclusion & Clean Up
That will conclude the setup for this project, though not that lengthy, the steps and configurations performed in this project closely resembles the steps that would be taken to build, containerize and deploy your application using docker and EKS in a production style environment, and that is the purpose of this project, to gain practical skill that can one day be translated and used in a more complex environment.
The final thing to do for this project would be to clean up all the resources we have created in our AWS Account. We do this so that AWS DOES NOT CRIPLE US FINANCIALLY!
Mainly we would need to delete our EKS cluster and all the resources that were created along with it. I did this project and as soon as I was done, I went straight to my aws management console and manually started deleting all the resources . So, with that said, I am NOT going to set this whole architecture up again and potentially get charged up to $15-20 by the time I wake up simply to show you what to delete. The best I can do in this case is simply to alert you of what to go manually delete.
Which are:
- EKS VPC (autocreated):
- EKS Cluster :
- NAT Gateway
- Internet Gateway
- Public & Private Subnets
- IPv4 Addresses
- Elastic IP addresses
- Network Interfaces
Some of these actions precede other actions, so begin with the lower-level resources like delinking the IPv4 addresses and then move on to the internet gateways and the NAT Gateways and then move on to the subnets and then finally the VPC itself.
ONE MORE TIP. WHEN TRYING TO FIND ALL THE RESOURCES CREATED FOR YOUR EKS CLUSTER SIMPLY GO OVER TO THE NEWLY CREATED VPC DEDICATED TO YOUR EKS CLUSTER AND TAKE A LOOK AT THE RESOURCE MAP, THIS WILL GIVE YOU AN OVERVIEW OF ALL THE RESOURCES ASSOCIATED WITH THIS NEWLY CREATED VPC.