python
Python Microservices Project
This project demonstrates a simple microservices architecture implemented in Python using Flask. It consists of four services:
- User Service (Python): Manages user-related data.
- Product Service (Python): Manages product-related data.
- Order Service (Python): Handles order creation and management, demonstrating service-to-service communication with User and Product services.
- Notification Service (Python): A placeholder service for sending notifications.
Architecture Overview
The architecture is based on a set of independently deployable services that communicate with each other.
+-----------------------+ +-----------------------+
| User Service (Py) |<----->| Order Service (Py) |
| (Port 8080) | | (Port 8082) |
+-----------------------+ +-----------------------+
^
|
v
+-----------------------+ +-----------------------+
| Product Service (Py) |<----->| Order Service (Py) |
| (Port 8081) | | (Port 8082) |
+-----------------------+ +-----------------------+
^
|
v
+-----------------------+
| Notification Svc (Py) |
| (Port 8083) |
+-----------------------+
Service-to-Service Communication
In a Kubernetes environment, service-to-service communication is facilitated by Kubernetes DNS. Each Service resource in Kubernetes gets a DNS name (e.g., user-service-py, product-service-py). Other services within the same Kubernetes cluster can resolve these DNS names to the respective service's ClusterIP, allowing them to communicate without needing to know the exact IP addresses.
For example, the Order Service (Python) communicates with the User Service (Python) and Product Service (Python) using their Kubernetes service names:
http://user-service-py:8080/users/{userId}http://product-service-py:8081/products/{productId}
The port numbers (8080, 8081) correspond to the targetPort defined in each service's Kubernetes Service manifest.
Services Details
1. User Service (Python)
- Functionality: Provides REST endpoints for managing users.
- Technology: Flask
- Endpoints:
GET /users: Get all users.GET /users/{id}: Get user by ID.
- Port: 8080
2. Product Service (Python)
- Functionality: Provides REST endpoints for managing products.
- Technology: Flask
- Endpoints:
GET /products: Get all products.GET /products/{id}: Get product by ID.
- Port: 8081
3. Order Service (Python)
- Functionality: Handles order creation and retrieval. Demonstrates calling other microservices.
- Technology: Flask (using
requestslibrary for HTTP calls) - Endpoints:
GET /orders: Get all orders.GET /orders/{id}: Get order by ID.GET /orders/create/{userId}/{productId}/{quantity}: Create a dummy order and call User/Product services.
- Port: 8082
4. Notification Service (Python)
- Functionality: A simple service to simulate sending notifications.
- Technology: Flask
- Endpoints:
POST /notifications/send: Send a notification.
- Port: 8083
Setup and Local Development
-
Prerequisites:
- Python 3.9 or higher
pip- Docker
- Kubernetes cluster (e.g., Minikube, Docker Desktop Kubernetes)
kubectlconfigured to connect to your cluster
-
Build Services: You can use the provided
Makefileto build and manage the services.bash make buildThis will install the Python dependencies for each service. -
Build Docker Images: Use the
Makefileto build Docker images. Replaceyour-docker-registrywith your actual Docker registry (e.g.,myusernamefor Docker Hub).bash make docker-build DOCKER_REGISTRY=your-docker-registryThen push them to your registry:bash make docker-push DOCKER_REGISTRY=your-docker-registryNote: Update theimagefield in thekubernetes/deployment.yamlfiles for each service to point to your pushed images (e.g.,image: your-docker-registry/user-service-py:latest). -
Deploy to Kubernetes: Use the
Makefileto deploy to Kubernetes.bash make k8s-deploy -
Access Services: Since all services are
ClusterIPtype, they are only accessible within the cluster. To access them from outside (e.g., for testing), you can usekubectl port-forwardor set up an Ingress controller.Example for
user-service-py:bash kubectl port-forward service/user-service-py 8080:8080Then accesshttp://localhost:8080/usersin your browser.
CI/CD with Jenkins
A Jenkinsfile is provided at the root of the python directory. This file defines a Jenkins Pipeline that automates the build, Docker image creation, and deployment to Kubernetes for all services.
The pipeline includes the following stages:
- Unit Tests: Runs
python -m unittest discoverfor each service. - SonarQube Analysis: Performs static code analysis using SonarQube for each service. The pipeline is configured to continue even if the SonarQube quality gate fails, marking the build as
UNSTABLE. - Build Docker Images: Builds the Docker images for each service using the
Makefile. - Push Docker Images: Pushes the Docker images to the configured registry using the
Makefile. - Deploy to Kubernetes: Applies the Kubernetes manifests to deploy the services using the
Makefile.
Steps to use the Jenkinsfile:
- Configure a Jenkins server with Docker and Kubernetes plugins.
- Ensure
kubectlis configured on the Jenkins agent to access your Kubernetes cluster. - Configure SonarQube integration in Jenkins (e.g., install SonarQube Scanner, configure SonarQube server connection).
- Create a new Pipeline job in Jenkins.
- Configure the job to use "Pipeline script from SCM" and point it to this repository.
- Run the Jenkins job. It will execute the stages defined in the
Jenkinsfile.
Important: Remember to replace your-docker-registry in the Jenkinsfile, Makefile, and Kubernetes manifests with your actual Docker registry. Also, ensure your Jenkins setup has the necessary SonarQube credentials (sonarqube-token) and SONAR_SCANNER_HOME tool configured.