This project involves setting up a scalable, observable, and modern microservice infrastructure using Kubernetes on Google Cloud Platform. The project includes creating a Kubernetes cluster using GKE (Google Kubernetes Engine), configuring custom node pools, deploying a sample application, implementing auto-scaling, monitoring, and setting up a service mesh.
- Project Summary
- Architecture
- Infrastructure Features
- Application: Book Catalog API
- Monitoring and Alert System
- API Usage Examples
- Access Information
- Installation Steps
This case study demonstrates how to set up and configure a modern microservice infrastructure. The project includes the following main components:
- GKE Kubernetes Cluster: A Kubernetes cluster with customized node pools
- Book Catalog API: A sample PHP Laravel application
- Auto Scaling: Load-based scaling implemented with HPA and KEDA
- Monitoring System: Monitoring and alerting system implemented with Prometheus and Grafana
- Service Mesh: Secure and manageable service-to-service communication with Istio
The project has a multi-layered architecture consisting of the following components visualized with interactive diagrams:
graph TD
classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:white
classDef infra fill:#4285f4,stroke:#fff,stroke-width:1px,color:white
classDef monitoring fill:#fbbc04,stroke:#fff,stroke-width:1px,color:black
classDef app fill:#34a853,stroke:#fff,stroke-width:1px,color:white
classDef mesh fill:#ff6d00,stroke:#fff,stroke-width:1px,color:white
GKE["GKE Cluster<br>europe-west1"]:::k8s
GKE --> MainPool["main-pool<br>n2d-standard-2<br>No scaling"]:::infra
GKE --> AppPool["application-pool<br>n2d-standard-2<br>scaling: 1-3 nodes"]:::infra
GKE --> MonitoringSystem["Monitoring System"]:::monitoring
AppPool --> Frontend["Frontend<br>Nginx"]:::app
AppPool --> Backend["Backend<br>PHP-FPM Laravel"]:::app
AppPool --> DB["Database<br>PostgreSQL"]:::app
MonitoringSystem --> Prometheus["Prometheus<br>Metrics Collection"]:::monitoring
MonitoringSystem --> Grafana["Grafana<br>Dashboard & Alerts"]:::monitoring
Prometheus -.-> DB
Prometheus -.-> Backend
Prometheus -.-> Frontend
IstioDeploy["Istio Service Mesh"]:::mesh
GKE --> IstioDeploy
IstioDeploy --> Istiod["istiod<br>control plane"]:::mesh
IstioDeploy --> IngressGateway["istio-ingressgateway"]:::mesh
IstioDeploy --> EgressGateway["istio-egressgateway"]:::mesh
IngressGateway --> Frontend
KEDA["KEDA<br>AutoScaler"]:::infra
GKE --> KEDA
KEDA -.-> Backend
HPA["Horizontal Pod Autoscaler<br>CPU > 25%"]:::infra
GKE --> HPA
HPA -.-> Backend
HPA -.-> Frontend
flowchart TD
classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:white
classDef infra fill:#4285f4,stroke:#fff,stroke-width:1px,color:white
classDef app fill:#34a853,stroke:#fff,stroke-width:1px,color:white
classDef selector fill:#ff6d00,stroke:#fff,stroke-width:1px,color:white
GKE["GKE Cluster"]:::k8s
GKE --> MainPool["main-pool<br>n2d-standard-2<br>Auto-scaling: Disabled"]:::infra
GKE --> AppPool["application-pool<br>n2d-standard-2<br>Auto-scaling: 1-3 nodes"]:::infra
AppPool --> NodeSelector["nodeSelector:<br>pool=application-pool"]:::selector
NodeSelector --> FrontendPod["Frontend Pod<br>Nginx"]:::app
NodeSelector --> BackendPod["Backend Pod<br>PHP-FPM Laravel"]:::app
NodeSelector --> DBPod["Database Pod<br>PostgreSQL"]:::app
graph TD
classDef monitoring fill:#fbbc04,stroke:#fff,stroke-width:1px,color:black
classDef alert fill:#ff6d00,stroke:#fff,stroke-width:1px,color:white
classDef metrics fill:#4285f4,stroke:#fff,stroke-width:1px,color:white
Prometheus["Prometheus<br>Time Series DB"]:::monitoring
Prometheus --> PrometheusOperator["Prometheus Operator"]:::monitoring
PrometheusOperator --> ServiceMonitor["ServiceMonitor<br>Metrics Scraping"]:::monitoring
PrometheusOperator --> PrometheusRule["PrometheusRule<br>Alert Rules"]:::monitoring
ServiceMonitor --> AppMetrics["Application Metrics<br>CPU, Memory, Requests"]:::metrics
ServiceMonitor --> K8sMetrics["Kubernetes Metrics<br>Node, Pod Status"]:::metrics
PrometheusRule --> PodRestartAlert["Pod Restart Alert<br>15 minutes restart window"]:::alert
PrometheusRule --> CPUAlert["CPU Usage Alert<br>>25% CPU"]:::alert
Prometheus --> Grafana["Grafana<br>Dashboard & Alerts"]:::monitoring
Grafana --> Dashboard["Kubernetes Dashboard"]:::monitoring
Grafana --> Alerts["Alert Management"]:::monitoring
graph TD
classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:white
classDef autoscaler fill:#ff6d00,stroke:#fff,stroke-width:1px,color:white
classDef app fill:#34a853,stroke:#fff,stroke-width:1px,color:white
classDef metrics fill:#fbbc04,stroke:#fff,stroke-width:1px,color:black
K8s["Kubernetes Cluster"]:::k8s
K8s --> HPA["Horizontal Pod Autoscaler"]:::autoscaler
K8s --> KEDA["Kubernetes Event-Driven Autoscaler"]:::autoscaler
HPA --> HPAMetrics["CPU Usage > 25%<br>1-3 pods"]:::metrics
HPAMetrics --> HPADeployment["Book Catalog Web/App<br>Deployments"]:::app
KEDA --> KEDAMetrics["CPU Usage > 25%<br>1-3 pods"]:::metrics
KEDA --> ScaledObject["ScaledObject<br>book-catalog-scaled-object"]:::autoscaler
ScaledObject --> BookCatalog["Book Catalog<br>Deployment"]:::app
%% Note: While KEDA is shown with CPU-based scaling in this example,
%% it can also scale based on other data sources (Prometheus, Kafka, RabbitMQ, etc.)
graph TD
classDef mesh fill:#ff6d00,stroke:#fff,stroke-width:1px,color:white
classDef app fill:#34a853,stroke:#fff,stroke-width:1px,color:white
classDef traffic fill:#4285f4,stroke:#fff,stroke-width:1px,color:white
classDef security fill:#fbbc04,stroke:#fff,stroke-width:1px,color:black
Istio["Istio Service Mesh"]:::mesh
Istio --> Istiod["istiod<br>Control Plane"]:::mesh
Istio --> IngressGW["istio-ingressgateway"]:::mesh
Istio --> EgressGW["istio-egressgateway"]:::mesh
IngressGW --> IstioGateway["Istio Gateway<br>Ingress Rules"]:::traffic
IstioGateway --> VirtualService["VirtualService<br>Traffic Rules"]:::traffic
VirtualService --> Frontend["Frontend Service"]:::app
Frontend --> Backend["Backend Service"]:::app
Backend --> DB["Database Service"]:::app
Istiod --> mTLS["Mutual TLS<br>Service Security"]:::security
Istiod --> Telemetry["Telemetry<br>Tracing, Metrics"]:::traffic
graph LR
classDef infra fill:#4285f4,stroke:#fff,stroke-width:1px,color:white
classDef app fill:#34a853,stroke:#fff,stroke-width:1px,color:white
classDef db fill:#326ce5,stroke:#fff,stroke-width:1px,color:white
classDef api fill:#ff6d00,stroke:#fff,stroke-width:1px,color:white
User(("User")) --> Ingress["LoadBalancer<br>External IP"]:::infra
Ingress --> FrontendSvc["Frontend Service"]:::infra
FrontendSvc --> Frontend["Nginx<br>Web Server"]:::app
Frontend --> BackendSvc["Backend Service"]:::infra
BackendSvc --> Backend["PHP-FPM<br>Laravel API"]:::app
Backend --> DBSvc["Database Service"]:::infra
DBSvc --> DB["PostgreSQL<br>Book Catalog DB"]:::db
Backend --> API["RESTful API Endpoints"]:::api
API --> ListBooks["GET /api/books"]:::api
API --> GetBook["GET /api/books/{id}"]:::api
API --> CreateBook["POST /api/books"]:::api
API --> UpdateBook["PUT /api/books/{id}"]:::api
API --> DeleteBook["DELETE /api/books/{id}"]:::api
- Region: europe-west1
- Logging and Monitoring: Disabled
- Kubernetes Version: 1.27.3-gke.100
-
main-pool
- Machine Type: n2d-standard-2
- Auto Scaling: Disabled (fixed 1 node)
- Labels:
pool=main-pool
-
application-pool
- Machine Type: n2d-standard-2
- Auto Scaling: Enabled (min:1, max:3 nodes)
- Labels:
pool=application-pool
- Book Catalog Application: Microservice architecture with 3 separate deployments
- Frontend (Nginx)
- Backend (PHP-FPM)
- Database (PostgreSQL)
- NodeSelector: All applications run on
application-pool
- HPA: Scales between 1-3 pods when CPU usage exceeds 25%
- KEDA: Alternative scaling from 1-3 pods when CPU usage exceeds 25%
- Prometheus: Collecting Kubernetes metrics
- Grafana: Visualization and alert configuration
- Pod Restart Alert: Alerts when any pod restarts within 15 minutes
- Istio: Mesh structure for inter-service communication
- istiod (control plane)
- istio-ingressgateway
- istio-egressgateway
Book Catalog API is a simple CRUD application for managing a book catalog. It was developed using Laravel and PostgreSQL.
- API Based: Book management via RESTful API
- Database: PostgreSQL
- Architecture: Laravel MVC
- Language: PHP 8.2
Each book has the following attributes:
id: Unique identifiername: Title of the bookauthor: Author of the bookpages: Number of pagescreated_at: Date addedupdated_at: Last update date
curl http://35.241.242.66/api/bookscurl -X POST http://35.241.242.66/api/books \
-H "Content-Type: application/json" \
-d '{"name":"1984","author":"George Orwell","pages":328}'curl http://35.241.242.66/api/books/1curl -X PUT http://35.241.242.66/api/books/1 \
-H "Content-Type: application/json" \
-d '{"name":"1984","author":"George Orwell","pages":352}'curl -X DELETE http://35.241.242.66/api/books/1- Features: Time series database, query language, alert system
- Data Collection: Kubernetes metrics, pod status, CPU and memory usage
- Scrape Interval: 15 seconds
- Features: Visualization, dashboards, alerts
- Dashboards: Kubernetes overview, pod status, resource usage
- Alerts:
- Pod restart alert (any restart within 15 minutes)
- Pod high CPU usage
- Pod high memory usage
- External Access URL: http://35.241.242.66/api/books
- Service Type: LoadBalancer
- Port: 80
- URL: http://34.77.133.67
- Service Type: LoadBalancer
- URL: http://35.205.72.133
- Service Type: LoadBalancer
- Username/Password: admin/admin
Steps required for project installation:
cd infrastructure/terraform
terraform init
terraform applykubectl apply -f infrastructure/k8s/book-catalog/deployment.yaml
kubectl apply -f infrastructure/k8s/book-catalog/service.yaml
kubectl apply -f infrastructure/k8s/book-catalog/hpa.yaml
kubectl apply -f infrastructure/k8s/book-catalog/nginx-configmap.yaml
kubectl apply -f infrastructure/k8s/book-catalog/migration-job.yamlhelm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --create-namespace -f infrastructure/monitoring/prometheus-values.yaml
kubectl apply -f infrastructure/monitoring/prometheus-services.yaml
kubectl apply -f infrastructure/monitoring/pod-restart-rule.yaml
kubectl apply -f infrastructure/monitoring/book-catalog-servicemonitor.yamlhelm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --namespace keda --create-namespace
kubectl apply -f infrastructure/k8s/book-catalog/keda-scaledobject.yamlcurl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.18.0 sh -
cd istio-1.18.0
./bin/istioctl install --set profile=demo -y
kubectl label namespace default istio-injection=enabled
kubectl apply -f infrastructure/k8s/book-catalog/istio-gateway.yamlThis project was prepared to demonstrate DevOps and Cloud Native application development practices. It shows step by step how to set up and configure a modern microservice infrastructure using Kubernetes on GKE.