Skip to content

Architecture Overview

Before You Read

Familiarity with Kubernetes concepts (pods, services, namespaces) and GCP basics (projects, GKE, Cloud SQL) will help. If you're new, start with System Overview.

Platform Layers

The Orofi platform has four conceptual layers:

graph TB
    L1["Layer 1: Edge\nCloud DNS · Let's Encrypt · Istio IngressGateway"]
    L2["Layer 2: API Gateway\n4 gateway services per client type"]
    L3["Layer 3: Core Services\ncommunication · identity · monolith · analytics"]
    L4["Layer 4: Data\nCloud SQL · MongoDB · Redis · Kafka"]

    L1 --> L2 --> L3 --> L4

Layer 1: Edge (Ingress)

  • Cloud DNS resolves *.dev.orofi.xyz, *.stage.orofi.xyz, *.orofi.xyz to the GKE load balancer static IP
  • Istio IngressGateway (oro-gateway in istio-system) receives all HTTPS traffic on port 443
  • cert-manager issues and renews TLS certificates from Let's Encrypt, stored as istio-tls-cert
  • Istio VirtualServices route requests to the correct API Gateway based on hostname/path

Layer 2: API Gateways

Four dedicated gateway services act as the entry point for each client type. Each gateway has its own: - Kubernetes namespace - GCP service account with workload identity - GCP Secret Manager secret - API key for downstream service authentication

Gateway Namespace Serves
api-gateway-public api-gateway-public Public-facing end users
api-gateway-account api-gateway-account Authenticated account users
api-gateway-oro api-gateway-oro Internal Oro operations
api-gateway-admin-dashboard api-gateway-admin-dashboard Admin dashboard users

Layer 3: Core Microservices

Four core services, each isolated in its own namespace with its own database user and secrets:

Service Namespace Primary Responsibility
microservice-communication microservice-communication Messaging, notifications, email/SMS
microservice-identity microservice-identity Auth, JWT, API keys, user identity, encryption
microservice-monolith microservice-monolith Core business logic
microservice-analytics microservice-analytics Analytics, reporting, event processing

Layer 4: Data

Store Type Technology Access Pattern
Per-service relational DB Relational Cloud SQL MySQL 8.0 Each service connects to its own DB schema
Document store Document MongoDB (Percona PSMDB) Shared cluster, accessed by monolith and identity
Cache Key-value Cloud Memorystore Redis (HA) All services share one Redis instance
Event stream Pub/Sub Kafka (KRaft, Bitnami v32.4.3) All services publish/consume events

Cross-Cutting Components

These platform components support all services:

graph LR
    subgraph "Cross-Cutting Platform"
        ArgoCD["ArgoCD\n(GitOps controller)"]
        ESO["External Secrets Operator\n(Secret sync from GCP)"]
        Istio["Istio\n(mTLS, routing, observability)"]
        Prom["Prometheus\n(metrics)"]
        Grafana["Grafana\n(dashboards)"]
        Loki["Loki\n(logs)"]
        CertMgr["cert-manager\n(TLS lifecycle)"]
        KEDA["KEDA\n(event-driven autoscaling)"]
        K6Op["K6 Operator\n(load testing)"]
    end
Component Namespace Purpose
ArgoCD argocd GitOps — applies Kubernetes manifests from Git
External Secrets Operator external-secrets Syncs GCP Secret Manager → Kubernetes Secrets
Istio (istiod + gateways) istio-system Service mesh, traffic management, mTLS
cert-manager cert-manager Automated TLS certificate lifecycle
Prometheus prometheus Metrics scraping and alerting
Grafana grafana Metrics and log visualization
Loki loki Log aggregation
kube-state-metrics kube-state-metrics Kubernetes object metrics for Prometheus
node-exporter node-exporter Node-level system metrics
KEDA (cluster-wide) Scale workloads based on Kafka/MongoDB/CPU metrics
K6 Operator k6-operator Run distributed load tests against services
KubeCost kubecost Kubernetes cost monitoring

Deployment Model

All services use the same deployment pattern, defined in the shared Helm chart template at infrastructure-configuration/projects/templates/microservice/helm/:

flowchart LR
    Git["Git (Bitbucket)\nService repo"]
    BB["Bitbucket Pipelines\nBuild & push image"]
    ArtReg["Artifact Registry\nus-central1-docker.pkg.dev"]
    ArgoCD["ArgoCD\nDetects drift"]
    K8S["GKE Cluster\nApply Helm chart"]

    Git -->|push/merge| BB
    BB -->|docker push| ArtReg
    ArtReg -->|image available| ArgoCD
    ArgoCD -->|helm upgrade| K8S

See GitOps Workflow for the full deployment process.

Namespace Isolation

Every workload runs in a dedicated namespace. This enforces: - Secret isolation — each namespace only mounts the secrets it needs - RBAC isolation — service accounts are namespace-scoped - Network policy isolation — Istio PeerAuthentication enforces mTLS per namespace - Resource quota isolation — limits can be applied per namespace

Cluster
├── istio-system          (Istio control plane + gateways)
├── cert-manager          (TLS automation)
├── argocd                (GitOps controller)
├── external-secrets      (Secret sync controller)
├── prometheus            (Metrics)
├── grafana               (Dashboards)
├── loki                  (Logs)
├── kafka                 (Event streaming)
├── mongo-db              (MongoDB replica set)
├── kube-state-metrics
├── node-exporter
├── kubecost
├── k6-operator
├── api-gateway-public    (Gateway: public users)
├── api-gateway-account   (Gateway: account users)
├── api-gateway-oro       (Gateway: oro operations)
├── api-gateway-admin-dashboard  (Gateway: admin)
├── microservice-communication
├── microservice-identity
├── microservice-monolith
└── microservice-analytics

See Also