A Python-based monitoring application built using Flask and psutil, containerized with Docker, and deployed on AWS EKS using Kubernetes.
β
Real-time monitoring using psutil
β
Containerized with Docker
β
Deployed on AWS ECR & EKS
β
Automated Kubernetes Deployments
β
Infrastructure as Code (IaC) with Python
Before you begin, ensure you have the following:
-
π Python installed β Download Python
-
π³ Docker installed & running
-
βοΈ AWS CLI configured (
aws configure
) -
π¦ Kubernetes CLI (kubectl) installed
-
π οΈ Python dependencies installed:
pip3 install -r requirements.txt
1οΈβ£ Navigate to the project folder:
cd Cloud-Native-Monitoring-App
2οΈβ£ Start the Flask app:
python3 app.py
3οΈβ£ Open in browser: http://localhost:5000/
1οΈβ£ Create a Dockerfile
in the root directory:
# Use a lightweight Python base image
FROM python:3.9-slim-buster
# Set a non-root user for better security
RUN addgroup --system appgroup && adduser --system --group appuser
# Set the working directory
WORKDIR /app
# Copy dependencies file and install required packages
COPY requirements.txt ./
RUN pip3 install --no-cache-dir -r requirements.txt
# Copy the rest of the application
COPY . .
# Change ownership to non-root user
RUN chown -R appuser:appgroup /app
# Switch to non-root user
USER appuser
# Set environment variables
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_ENV=production
# Expose the application port
EXPOSE 5000
# Use gunicorn for better performance in production
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
2οΈβ£ Build the Docker image:
docker build -t my-flask-app .
3οΈβ£ Run the container:
docker run -p 5000:5000 my-flask-app
π Now, access the app at http://localhost:5000/.
1οΈβ£ Create an ECR repository using Python (ecr.py
):
import boto3
import botocore
# AWS Session (Optional: Modify if using multiple profiles)
session = boto3.session.Session()
ecr_client = session.client('ecr')
# Define repository name
repository_name = "my_monitoring_app_image"
try:
# Check if the repository already exists
existing_repos = ecr_client.describe_repositories()
repo_names = [repo['repositoryName'] for repo in existing_repos.get('repositories', [])]
if repository_name in repo_names:
print(f"β
Repository '{repository_name}' already exists.")
else:
# Create a new ECR repository
response = ecr_client.create_repository(repositoryName=repository_name)
repository_uri = response['repository']['repositoryUri']
print(f"π Successfully created repository: {repository_name}")
print(f"π Repository URI: {repository_uri}")
except botocore.exceptions.ClientError as e:
error_code = e.response['Error']['Code']
if error_code == "RepositoryAlreadyExistsException":
print(f"β οΈ Repository '{repository_name}' already exists.")
else:
print(f"β An error occurred: {e}")
Run the script:
python3 ecr.py
2οΈβ£ Push Docker image to ECR (replace <ECR_URI>
with your repo URI):
aws ecr get-login-password | docker login --username AWS --password-stdin <ECR_URI>
docker tag my-flask-app:latest <ECR_URI>:latest
docker push <ECR_URI>:latest
1οΈβ£ Create an EKS cluster & node group (cloud-native-cluster
) via AWS Console.
2οΈβ£ Update kubeconfig:
aws eks update-kubeconfig --name cloud-native-cluster
3οΈβ£ Deploy the application using Python (eks.py
):
import logging
from kubernetes import client, config
# Configure logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
def load_kube_config():
"""Loads Kubernetes configuration (either local or in-cluster)."""
try:
config.load_kube_config() # Use for local development
logging.info("Loaded kubeconfig from local environment.")
except Exception:
config.load_incluster_config() # Use when running inside a Kubernetes cluster
logging.info("Loaded in-cluster Kubernetes configuration.")
def create_deployment(api_instance):
"""Creates a Kubernetes Deployment for the Flask app."""
deployment = client.V1Deployment(
metadata=client.V1ObjectMeta(name="my-flask-app"),
spec=client.V1DeploymentSpec(
replicas=1,
selector=client.V1LabelSelector(match_labels={"app": "my-flask-app"}),
template=client.V1PodTemplateSpec(
metadata=client.V1ObjectMeta(labels={"app": "my-flask-app"}),
spec=client.V1PodSpec(
containers=[
client.V1Container(
name="my-flask-container",
image="568373317874.dkr.ecr.us-east-1.amazonaws.com/my_monitoring_app_image:latest",
ports=[client.V1ContainerPort(container_port=5000)]
)
]
)
)
)
)
try:
api_instance.create_namespaced_deployment(namespace="default", body=deployment)
logging.info("Deployment created successfully.")
except Exception as e:
logging.error(f"Failed to create deployment: {e}")
def create_service(api_instance):
"""Creates a Kubernetes Service for the Flask app."""
service = client.V1Service(
metadata=client.V1ObjectMeta(name="my-flask-service"),
spec=client.V1ServiceSpec(
selector={"app": "my-flask-app"},
ports=[client.V1ServicePort(port=5000, target_port=5000)]
)
)
try:
api_instance.create_namespaced_service(namespace="default", body=service)
logging.info("Service created successfully.")
except Exception as e:
logging.error(f"Failed to create service: {e}")
def main():
"""Main function to deploy the application."""
load_kube_config()
api_client = client.ApiClient()
# Create Deployment and Service
create_deployment(client.AppsV1Api(api_client))
create_service(client.CoreV1Api(api_client))
if __name__ == "__main__":
main()
Run the script:
python3 eks.py
1οΈβ£ Create service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: flask-service
labels:
app: flask-app
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb" # Use Network Load Balancer for better performance (AWS-specific)
spec:
selector:
app: flask-app
ports:
- protocol: TCP
port: 80
targetPort: 5000
type: LoadBalancer
2οΈβ£ Deploy the service:
kubectl apply -f service.yaml
3οΈβ£ Get the service URL:
kubectl get svc flask-service
-
Check deployments:
kubectl get deployments
-
Check pods:
kubectl get pods
-
Check services:
kubectl get svc
-
If needed, edit the deployment:
kubectl edit deployment my-flask-app
-
Expose the service (if LoadBalancer is not available):
kubectl port-forward service/flask-service 5000:5000
Now, access http://localhost:5000 π.
β
Python Flask Monitoring App π
β
Dockerized & Hosted on AWS EKS βοΈ
β
Automated Kubernetes Deployment π
β
Scalable & Cloud-Native π₯
πΉ Enjoy Cloud-Native Observability! π
π Check out the AWS EKS Documentation.
π Explore Kubernetes Official Docs.
Contributions are welcome! If you'd like to improve this project, feel free to submit a pull request.
If you find this repository helpful and plan to use it for learning, please give it a star. Your support is appreciated!
This project is crafted by Harshhaa π‘.
Iβd love to hear your feedback! Feel free to share your thoughts.