Kubernetes Deployment
FluxiQ SPB is designed for production deployment on Kubernetes. This guide covers Helm chart configuration, resource management, autoscaling, and operational best practices for running the platform in a Kubernetes cluster.
Prerequisites
| Tool | Version | Purpose |
|---|---|---|
| Kubernetes | >= 1.28 | Container orchestration |
| Helm | >= 3.14 | Package management |
| kubectl | >= 1.28 | Cluster management |
| Container registry | - | Store Docker images |
Cluster Architecture
Kubernetes Cluster
├── Namespace: spb-production
│ ├── Deployment: api-gateway (3 replicas)
│ ├── Deployment: auth-service (2 replicas)
│ ├── Deployment: bacen-gateway (2 replicas)
│ ├── Deployment: message-processor (3 replicas)
│ ├── Deployment: user-management (2 replicas)
│ ├── Deployment: transaction-service (3 replicas)
│ ├── Deployment: securities-service (2 replicas)
│ ├── Deployment: settlement-service (2 replicas)
│ ├── Deployment: forex-service (2 replicas)
│ ├── Deployment: cash-service (2 replicas)
│ ├── Deployment: extract-service (2 replicas)
│ ├── Deployment: frontend (2 replicas)
│ ├── StatefulSet: postgresql (3 replicas, HA)
│ ├── StatefulSet: ibm-mq (2 replicas)
│ ├── Ingress: spb-ingress
│ ├── ConfigMap: spb-config
│ ├── Secret: spb-secrets
│ ├── HPA: per-service autoscalers
│ └── PDB: per-service disruption budgets
├── Namespace: spb-monitoring
│ ├── Deployment: prometheus
│ ├── Deployment: grafana
│ └── DaemonSet: otel-collector
└── Namespace: spb-staging
└── (mirror of production)Helm Chart
Installation
bash
# Add the FluxiQ Helm repository
helm repo add fluxiq https://charts.fluxiq.io
helm repo update
# Install the SPB chart
helm install spb fluxiq/spb \
--namespace spb-production \
--create-namespace \
--values values-production.yaml
# Upgrade an existing installation
helm upgrade spb fluxiq/spb \
--namespace spb-production \
--values values-production.yaml
# Check installation status
helm status spb -n spb-productionValues File
yaml
# values-production.yaml
global:
image:
registry: registry.fluxiq.io/spb
tag: "1.0.0"
pullPolicy: IfNotPresent
imagePullSecrets:
- name: registry-credentials
postgresql:
host: postgresql-ha-pgpool.spb-production.svc
port: 5432
database: spb_production
existingSecret: spb-db-credentials
bacen:
mode: production
ispb: "12345678"
mqHost: ibm-mq.spb-production.svc
mqPort: 1414
mqChannel: BACEN.SVRCONN
mqQueueManager: QM1
apiGateway:
replicaCount: 3
image:
repository: api-gateway
service:
type: ClusterIP
port: 4000
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1000m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilization: 70
targetMemoryUtilization: 80
env:
- name: SECRET_KEY_BASE
valueFrom:
secretKeyRef:
name: spb-secrets
key: secret-key-base
authService:
replicaCount: 2
image:
repository: auth-service
service:
port: 4001
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
bacenGateway:
replicaCount: 2
image:
repository: bacen-gateway
service:
port: 4002
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 1Gi
messageProcessor:
replicaCount: 3
image:
repository: message-processor
service:
port: 4003
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 1Gi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 20
targetCPUUtilization: 60
env:
- name: BROADWAY_CONCURRENCY
value: "20"
- name: BROADWAY_MAX_DEMAND
value: "100"
transactionService:
replicaCount: 3
image:
repository: transaction-service
service:
port: 4005
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1000m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilization: 70
securitiesService:
replicaCount: 2
image:
repository: securities-service
service:
port: 4006
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
settlementService:
replicaCount: 2
image:
repository: settlement-service
service:
port: 4007
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
forexService:
replicaCount: 2
image:
repository: forex-service
service:
port: 4008
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
cashService:
replicaCount: 2
image:
repository: cash-service
service:
port: 4009
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
extractService:
replicaCount: 2
image:
repository: extract-service
service:
port: 4010
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
frontend:
replicaCount: 2
image:
repository: frontend
service:
port: 3000
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
hosts:
- host: spb.fluxiq.io
paths:
- path: /api
pathType: Prefix
service: api-gateway
port: 4000
- path: /
pathType: Prefix
service: frontend
port: 3000
tls:
- secretName: spb-tls
hosts:
- spb.fluxiq.ioKubernetes Manifests
Deployment Example
yaml
# api-gateway-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
namespace: spb-production
labels:
app: api-gateway
part-of: fluxiq-spb
spec:
replicas: 3
selector:
matchLabels:
app: api-gateway
template:
metadata:
labels:
app: api-gateway
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "4000"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: spb-service
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: api-gateway
image: registry.fluxiq.io/spb/api-gateway:1.0.0
ports:
- containerPort: 4000
name: http
protocol: TCP
envFrom:
- configMapRef:
name: spb-config
- secretRef:
name: spb-secrets
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1000m
memory: 512Mi
livenessProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: http
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 30
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: api-gatewayHorizontal Pod Autoscaler
yaml
# api-gateway-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-gateway
namespace: spb-production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-gateway
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
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 2
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 120Pod Disruption Budget
yaml
# api-gateway-pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-gateway
namespace: spb-production
spec:
minAvailable: 2
selector:
matchLabels:
app: api-gatewaySecrets
bash
# Create secrets from literal values
kubectl create secret generic spb-secrets \
--namespace spb-production \
--from-literal=secret-key-base="$(openssl rand -hex 64)" \
--from-literal=jwt-secret="$(openssl rand -hex 64)" \
--from-literal=database-password="your-db-password"
# Or use sealed-secrets for GitOps
kubeseal --format=yaml < spb-secrets.yaml > spb-sealed-secrets.yamlDatabase Migration
Run migrations as a Kubernetes Job:
yaml
# migration-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: spb-migrate
namespace: spb-production
spec:
template:
spec:
containers:
- name: migrate
image: registry.fluxiq.io/spb/api-gateway:1.0.0
command: ["bin/service", "eval", "ApiGateway.Release.migrate()"]
envFrom:
- configMapRef:
name: spb-config
- secretRef:
name: spb-secrets
restartPolicy: OnFailure
backoffLimit: 3bash
kubectl apply -f migration-job.yaml
kubectl wait --for=condition=complete job/spb-migrate -n spb-production --timeout=120sMonitoring
Prometheus ServiceMonitor
yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: spb-services
namespace: spb-monitoring
spec:
namespaceSelector:
matchNames:
- spb-production
selector:
matchLabels:
part-of: fluxiq-spb
endpoints:
- port: http
path: /metrics
interval: 15sAlerting Rules
yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: spb-alerts
namespace: spb-monitoring
spec:
groups:
- name: spb.rules
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate on {{ $labels.service }}"
- alert: BACENConnectionDown
expr: bacen_mq_connection_status == 0
for: 1m
labels:
severity: critical
annotations:
summary: "BACEN MQ connection is down"
- alert: SettlementWindowMissed
expr: settlement_window_deadline_seconds < 300
for: 1m
labels:
severity: warning
annotations:
summary: "Settlement window closing in less than 5 minutes"Operational Commands
bash
# Check deployment status
kubectl get deployments -n spb-production
# View pod logs
kubectl logs -f deployment/api-gateway -n spb-production
# Scale a service manually
kubectl scale deployment transaction-service --replicas=5 -n spb-production
# Rolling restart (zero-downtime)
kubectl rollout restart deployment/api-gateway -n spb-production
# Check rollout status
kubectl rollout status deployment/api-gateway -n spb-production
# Rollback to previous version
kubectl rollout undo deployment/api-gateway -n spb-production
# Port-forward for debugging
kubectl port-forward svc/api-gateway 4000:4000 -n spb-production
# Open a shell in a running pod
kubectl exec -it deployment/api-gateway -n spb-production -- bin/service remoteProduction Checklist
Before going to production, verify the following:
- [ ] All secrets are stored in Kubernetes Secrets (not ConfigMaps)
- [ ] Resource requests and limits are configured for every container
- [ ] Liveness, readiness, and startup probes are defined
- [ ] Pod Disruption Budgets are set for critical services
- [ ] Horizontal Pod Autoscalers are configured
- [ ] Topology spread constraints distribute pods across availability zones
- [ ] Network policies restrict inter-service communication
- [ ] TLS is enabled on the Ingress
- [ ] Database backups are configured and tested
- [ ] Prometheus alerting rules are active
- [ ] Log aggregation is configured (e.g., Loki, ELK)
- [ ] IBM MQ TLS certificates are configured for BACEN production
- [ ] HSM integration is tested with production key material
- [ ] BACEN_MODE is set to
production(notsimulator) - [ ] Disaster recovery runbook is documented and tested