feat: tenant demo (segundo silo)

This commit is contained in:
ATM Platform
2026-06-15 20:58:06 +00:00
parent eba21e91ac
commit 49ad21c7a8
4 changed files with 335 additions and 0 deletions
@@ -0,0 +1,55 @@
# Silo "demo" — isolamento do tenant (namespace + quota + limites + rede)
apiVersion: v1
kind: Namespace
metadata:
name: demo-prod
labels:
name: demo-prod
tenant: demo
athleticmap.io/tier: pilot
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-quota
namespace: demo-prod
spec:
hard:
requests.cpu: "2"
requests.memory: 2Gi
limits.cpu: "4"
limits.memory: 6Gi
pods: "20"
persistentvolumeclaims: "4"
---
apiVersion: v1
kind: LimitRange
metadata:
name: defaults
namespace: demo-prod
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-cross-tenant
namespace: demo-prod
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector: {}
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
egress:
- {}
+83
View File
@@ -0,0 +1,83 @@
# PostgreSQL dedicado do tenant demo (banco da aplicação + banco do Keycloak)
apiVersion: v1
kind: ConfigMap
metadata:
name: pg-initdb
namespace: demo-prod
data:
01-keycloak.sql: |
CREATE DATABASE keycloak;
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
namespace: demo-prod
spec:
accessModes: [ReadWriteOnce]
storageClassName: local-path
resources:
requests:
storage: 5Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: demo-prod
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
value: athleticmap
- name: POSTGRES_USER
value: atm
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
- name: initdb
mountPath: /docker-entrypoint-initdb.d
readinessProbe:
exec:
command: ["pg_isready", "-U", "atm", "-d", "athleticmap"]
initialDelaySeconds: 10
periodSeconds: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: postgres-data
- name: initdb
configMap:
name: pg-initdb
---
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: demo-prod
spec:
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432
+78
View File
@@ -0,0 +1,78 @@
# Keycloak dedicado do tenant demo (IdP do silo) — modo dev, persistindo no Postgres
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
namespace: demo-prod
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:26.0
args: ["start-dev"]
env:
- name: KC_DB
value: postgres
- name: KC_DB_URL
value: "jdbc:postgresql://postgres:5432/keycloak"
- name: KC_DB_USERNAME
value: atm
- name: KC_DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
- name: KC_BOOTSTRAP_ADMIN_USERNAME
value: admin
- name: KC_BOOTSTRAP_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-admin
key: password
- name: KC_HEALTH_ENABLED
value: "true"
- name: KC_HTTP_ENABLED
value: "true"
- name: KC_PROXY_HEADERS
value: xforwarded
- name: KC_HOSTNAME
value: "auth-demo.187.77.37.184.nip.io"
- name: KC_HOSTNAME_STRICT
value: "false"
ports:
- containerPort: 8080
- containerPort: 9000
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
readinessProbe:
httpGet:
path: /health/ready
port: 9000
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 40
---
apiVersion: v1
kind: Service
metadata:
name: keycloak
namespace: demo-prod
spec:
selector:
app: keycloak
ports:
- port: 8080
targetPort: 8080
+119
View File
@@ -0,0 +1,119 @@
# Esqueletos (stubs) de Backend, BFF e Frontend do tenant demo + Ingress TLS
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: backend, namespace: demo-prod }
spec:
replicas: 1
selector: { matchLabels: { app: backend } }
template:
metadata: { labels: { app: backend } }
spec:
containers:
- name: whoami
image: traefik/whoami:latest
args: ["--name", "athletic-map-backend demo (stub)"]
ports: [{ containerPort: 80 }]
---
apiVersion: v1
kind: Service
metadata: { name: backend, namespace: demo-prod }
spec:
selector: { app: backend }
ports: [{ port: 80, targetPort: 80 }]
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: bff, namespace: demo-prod }
spec:
replicas: 1
selector: { matchLabels: { app: bff } }
template:
metadata: { labels: { app: bff } }
spec:
containers:
- name: whoami
image: traefik/whoami:latest
args: ["--name", "athletic-map-bff demo (stub)"]
ports: [{ containerPort: 80 }]
---
apiVersion: v1
kind: Service
metadata: { name: bff, namespace: demo-prod }
spec:
selector: { app: bff }
ports: [{ port: 80, targetPort: 80 }]
---
apiVersion: v1
kind: ConfigMap
metadata: { name: frontend-index, namespace: demo-prod }
data:
index.html: |
<!doctype html>
<html lang="pt-br"><head><meta charset="utf-8"><title>Athletic Map — Demo</title>
<style>body{font-family:system-ui,sans-serif;background:#155eef;color:#fff;display:flex;
min-height:100vh;align-items:center;justify-content:center;margin:0}
.c{text-align:center}h1{color:#ffd23f}</style></head>
<body><div class="c"><h1>Athletic Map</h1>
<p>Frontend (stub) — silo <b>demo</b> no k3s</p>
<p>tenant: <b>demo</b></p></div></body></html>
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: frontend, namespace: demo-prod }
spec:
replicas: 1
selector: { matchLabels: { app: frontend } }
template:
metadata: { labels: { app: frontend } }
spec:
containers:
- name: nginx
image: nginx:alpine
ports: [{ containerPort: 80 }]
volumeMounts:
- { name: html, mountPath: /usr/share/nginx/html }
volumes:
- name: html
configMap: { name: frontend-index }
---
apiVersion: v1
kind: Service
metadata: { name: frontend, namespace: demo-prod }
spec:
selector: { app: frontend }
ports: [{ port: 80, targetPort: 80 }]
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
namespace: demo-prod
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
tls:
- hosts:
- demo.187.77.37.184.nip.io
- auth-demo.187.77.37.184.nip.io
- api-demo.187.77.37.184.nip.io
- bff-demo.187.77.37.184.nip.io
secretName: demo-tls
rules:
- host: demo.187.77.37.184.nip.io
http:
paths:
- { path: /, pathType: Prefix, backend: { service: { name: frontend, port: { number: 80 } } } }
- host: auth-demo.187.77.37.184.nip.io
http:
paths:
- { path: /, pathType: Prefix, backend: { service: { name: keycloak, port: { number: 8080 } } } }
- host: api-demo.187.77.37.184.nip.io
http:
paths:
- { path: /, pathType: Prefix, backend: { service: { name: backend, port: { number: 80 } } } }
- host: bff-demo.187.77.37.184.nip.io
http:
paths:
- { path: /, pathType: Prefix, backend: { service: { name: bff, port: { number: 80 } } } }