⬡ Hub
Skip to content

python

Python Microservices Project

This project demonstrates a simple microservices architecture implemented in Python using Flask. It consists of four services:

  1. User Service (Python): Manages user-related data.
  2. Product Service (Python): Manages product-related data.
  3. Order Service (Python): Handles order creation and management, demonstrating service-to-service communication with User and Product services.
  4. 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 requests library 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

  1. Prerequisites:

    • Python 3.9 or higher
    • pip
    • Docker
    • Kubernetes cluster (e.g., Minikube, Docker Desktop Kubernetes)
    • kubectl configured to connect to your cluster
  2. Build Services: You can use the provided Makefile to build and manage the services. bash make build This will install the Python dependencies for each service.

  3. Build Docker Images: Use the Makefile to build Docker images. Replace your-docker-registry with your actual Docker registry (e.g., myusername for Docker Hub). bash make docker-build DOCKER_REGISTRY=your-docker-registry Then push them to your registry: bash make docker-push DOCKER_REGISTRY=your-docker-registry Note: Update the image field in the kubernetes/deployment.yaml files for each service to point to your pushed images (e.g., image: your-docker-registry/user-service-py:latest).

  4. Deploy to Kubernetes: Use the Makefile to deploy to Kubernetes. bash make k8s-deploy

  5. Access Services: Since all services are ClusterIP type, they are only accessible within the cluster. To access them from outside (e.g., for testing), you can use kubectl port-forward or set up an Ingress controller.

    Example for user-service-py: bash kubectl port-forward service/user-service-py 8080:8080 Then access http://localhost:8080/users in 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 discover for 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:

  1. Configure a Jenkins server with Docker and Kubernetes plugins.
  2. Ensure kubectl is configured on the Jenkins agent to access your Kubernetes cluster.
  3. Configure SonarQube integration in Jenkins (e.g., install SonarQube Scanner, configure SonarQube server connection).
  4. Create a new Pipeline job in Jenkins.
  5. Configure the job to use "Pipeline script from SCM" and point it to this repository.
  6. 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.

Files and Subdirectories