Scalable Distributed Architecture with Kubernetes, Docker & Service Mesh
Cloud-native microservices are independently deployable services that work together to form a complete application. Built specifically for cloud environments, they leverage containerization, orchestration, and modern DevOps practices to deliver scalable, resilient, and maintainable systems.
This project demonstrates a complete cloud-native architecture with multiple microservices running on Kubernetes, communicating via REST APIs and message queues, with service discovery, load balancing, monitoring, and CI/CD pipelines fully automated.
Multi-tier cloud-native architecture with clear separation of concerns, asynchronous communication, and centralized observability.
Each microservice is independently deployable, has its own database, and communicates with others via well-defined APIs and asynchronous messaging.
Industry-standard design patterns implemented to ensure reliability, scalability, and maintainability of the microservices architecture.
Complete Kubernetes manifests for deploying all microservices with auto-scaling, health checks, and service mesh integration.
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
namespace: microservices
labels:
app: user-service
version: v1
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
version: v1
spec:
containers:
- name: user-service
image: myregistry/user-service:1.0.0
ports:
- containerPort: 3000
name: http
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: user-db-secret
key: connection-string
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: jwt-secret
key: secret
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: user-service
namespace: microservices
spec:
selector:
app: user-service
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: user-service-hpa
namespace: microservices
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: user-service
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: user-service
namespace: microservices
spec:
hosts:
- user-service
http:
- match:
- headers:
version:
exact: v2
route:
- destination:
host: user-service
subset: v2
weight: 100
- route:
- destination:
host: user-service
subset: v1
weight: 90
- destination:
host: user-service
subset: v2
weight: 10
timeout: 10s
retries:
attempts: 3
perTryTimeout: 2s
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: user-service
namespace: microservices
spec:
host: user-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 50
http2MaxRequests: 100
loadBalancer:
simple: ROUND_ROBIN
outlierDetection:
consecutiveErrors: 5
interval: 30s
baseEjectionTime: 30s
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
version: '3.8'
services:
# API Gateway
api-gateway:
image: kong:3.4
ports:
- "8000:8000"
- "8001:8001"
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: postgres
KONG_PG_DATABASE: kong
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong
depends_on:
- postgres
# User Service
user-service:
build: ./services/user-service
ports:
- "3001:3000"
environment:
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/users
JWT_SECRET: your-secret-key
REDIS_URL: redis://redis:6379
depends_on:
- postgres
- redis
# Order Service
order-service:
build: ./services/order-service
ports:
- "3002:3000"
environment:
MONGODB_URL: mongodb://mongo:27017/orders
RABBITMQ_URL: amqp://rabbitmq:5672
depends_on:
- mongo
- rabbitmq
# Payment Service
payment-service:
build: ./services/payment-service
ports:
- "3003:8080"
environment:
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/payments
STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY}
depends_on:
- postgres
# Inventory Service
inventory-service:
build: ./services/inventory-service
ports:
- "3004:8000"
environment:
DATABASE_URL: postgresql://postgres:postgres@postgres:5432/inventory
REDIS_URL: redis://redis:6379
depends_on:
- postgres
- redis
# Notification Service
notification-service:
build: ./services/notification-service
environment:
RABBITMQ_URL: amqp://rabbitmq:5672
SENDGRID_API_KEY: ${SENDGRID_API_KEY}
TWILIO_ACCOUNT_SID: ${TWILIO_ACCOUNT_SID}
TWILIO_AUTH_TOKEN: ${TWILIO_AUTH_TOKEN}
depends_on:
- rabbitmq
# PostgreSQL Database
postgres:
image: postgres:15-alpine
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- postgres-data:/var/lib/postgresql/data
# MongoDB Database
mongo:
image: mongo:7
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
# Redis Cache
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
# RabbitMQ Message Queue
rabbitmq:
image: rabbitmq:3-management
ports:
- "5672:5672"
- "15672:15672"
volumes:
- rabbitmq-data:/var/lib/rabbitmq
# Prometheus Monitoring
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
# Grafana Dashboards
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
GF_SECURITY_ADMIN_PASSWORD: admin
volumes:
- grafana-data:/var/lib/grafana
volumes:
postgres-data:
mongo-data:
redis-data:
rabbitmq-data:
prometheus-data:
grafana-data:
name: Build and Deploy Microservices
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
service: [user-service, order-service, payment-service, inventory-service]
steps:
- uses: actions/checkout@v3
- name: Run tests for ${{ matrix.service }}
run: |
cd services/${{ matrix.service }}
npm install
npm test
npm run lint
build:
needs: test
runs-on: ubuntu-latest
if: github.event_name == 'push'
strategy:
matrix:
service: [user-service, order-service, payment-service, inventory-service]
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Container Registry
uses: docker/login-action@v2
with:
registry: ${{ secrets.REGISTRY_URL }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: ./services/${{ matrix.service }}
push: true
tags: |
${{ secrets.REGISTRY_URL }}/${{ matrix.service }}:${{ github.sha }}
${{ secrets.REGISTRY_URL }}/${{ matrix.service }}:latest
cache-from: type=registry,ref=${{ secrets.REGISTRY_URL }}/${{ matrix.service }}:buildcache
cache-to: type=registry,ref=${{ secrets.REGISTRY_URL }}/${{ matrix.service }}:buildcache,mode=max
deploy:
needs: build
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v3
- name: Configure kubectl
uses: azure/k8s-set-context@v3
with:
method: kubeconfig
kubeconfig: ${{ secrets.KUBE_CONFIG }}
- name: Deploy to Kubernetes
run: |
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/secrets.yaml
kubectl apply -f k8s/configmaps.yaml
kubectl apply -f k8s/deployments/
kubectl apply -f k8s/services/
kubectl apply -f k8s/ingress.yaml
- name: Wait for rollout
run: |
kubectl rollout status deployment/user-service -n microservices
kubectl rollout status deployment/order-service -n microservices
kubectl rollout status deployment/payment-service -n microservices
kubectl rollout status deployment/inventory-service -n microservices
- name: Run smoke tests
run: |
kubectl run smoke-test --image=curlimages/curl --rm -i --restart=Never -- \
curl -f http://api-gateway/health