A scalable URL shortening service built with Flask and MySQL, deployed on Kubernetes with load balancing capabilities.
- URL shortening and redirection
- Load balancing across multiple replicas
- Persistent MySQL storage
- Horizontal Pod Autoscaling (HPA)
- Stress testing capabilities
- Monitoring and metrics
-
Install the following tools:
- Docker Desktop with WSL2 backend
- Minikube
- kubectl
- Python 3.x (for local development)
-
Verify installations
docker --version
minikube version
kubectl version# Install Docker
sudo apt-get update
sudo apt-get install docker.io
# Install Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# Install kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl- Clone the repository:
git clone https://github.com/shrxyyya/Load-balanced-URL-Shortener.git
cd Load-balanced-URL-Shortener- Start Minikube:
# Start Minikube with Docker driver
minikube start --driver=docker
# Verify Minikube is running
minikube status- Build and deploy the application:
# Point shell to minikube's docker-daemon
eval $(minikube docker-env)
# Build the Docker image
docker build -t urlshortener:latest .
# Apply Kubernetes configurations
kubectl apply -f k8s/mysql-secret.yaml
kubectl apply -f k8s/mysql-pvc.yaml
kubectl apply -f k8s/mysql-configmap.yaml
kubectl apply -f k8s/urlshortener-config.yaml
kubectl apply -f k8s/mysql-deployment.yaml
kubectl apply -f k8s/urlshortener-deployment.yaml
# Verify all pods are running
kubectl get pods -w- Access the application:
# Terminal 1: Start minikube tunnel (keep this terminal open)
minikube tunnel
# Terminal 2: Forward MySQL port (keep this terminal open) - because my server was created on port 3307
kubectl port-forward service/mysql-service 3307:3306
# Terminal 3: Get the service URL
kubectl get service urlshortener-serviceThe application will be available at http:// shown in the service output.
- Make the test script executable:
chmod +x test_api.sh
dos2unix test_api.sh- Run the test script:
./test_api.shThis will:
- Create 10 shortened URLs
- Test redirections
- Show load balancing across pods
- Basic Stress Test:
# Terminal 4: Monitor CPU usage
watch -n 2 "kubectl top pods | grep urlshortener"
# -- OR --
# Terminal 4: Monitor HPA - Check current replica set information
kubectl get hpa urlshortener-hpa
# Terminal 3: Run basic stress test
./basic_stress_test.sh- Advanced Stress Test:
# Terminal 3: Run advanced stress test
./adv_stress_test.shThe stress tests will:
- Simulate multiple concurrent users
- Test system performance under load
- Monitor response times and success rates
- Verify load balancing effectiveness
- View application logs:
# View URL shortener logs
kubectl logs -l app=urlshortener
# View MySQL logs
kubectl logs -l app=mysql- If pods are not starting:
kubectl describe pods- If the service is not accessible:
# Check service status
kubectl get services
# Check service endpoints
kubectl get endpoints urlshortener-service- To restart deployments:
kubectl rollout restart deployment urlshortener-deployment
kubectl rollout restart deployment mysql-deploymentTo stop and clean up the project:
# Delete all resources
kubectl delete -f k8s/
# Stop minikube
minikube stop
# Optional: Delete minikube cluster
minikube deleteThe application uses the following environment variables (configured in ConfigMaps and Secrets):
- MYSQL_HOST: MySQL service hostname
- MYSQL_PORT: MySQL port (default: 3306)
- MYSQL_USER: MySQL username
- MYSQL_PASSWORD: MySQL password (in secret)
- MYSQL_DATABASE: Database name
- FLASK_ENV: Flask environment
The application consists of:
- MySQL Deployment (single pod for data consistency)
- URL Shortener Deployment (3 replicas for high availability)
- Persistent Volume for MySQL data
- Load Balancer Service for external access
- Horizontal Pod Autoscaler for dynamic scaling