| --- |
| |
| |
| |
| |
|
|
| apiVersion: v1 |
| kind: Namespace |
| metadata: |
| name: optimai-bre |
| labels: |
| app.kubernetes.io/name: optimai-bre |
| environment: production |
|
|
| --- |
| |
| |
| |
| apiVersion: v1 |
| kind: ConfigMap |
| metadata: |
| name: bre-config |
| namespace: optimai-bre |
| data: |
| ASPNETCORE_ENVIRONMENT: "Production" |
| ASPNETCORE_URLS: "http://+:8080" |
| AiOptions__UseAzureOpenAI: "true" |
| AiOptions__ModelName: "gpt-4o" |
| Serilog__MinimumLevel__Default: "Information" |
|
|
| --- |
| |
| |
| |
| apiVersion: v1 |
| kind: Secret |
| metadata: |
| name: bre-secrets |
| namespace: optimai-bre |
| type: Opaque |
| stringData: |
| postgres-connection: "Host=postgres-service;Database=optimai_bre;Username=optimai;Password=CHANGE_ME" |
| redis-connection: "redis-service:6379,password=CHANGE_ME" |
| jwt-secret-key: "CHANGE_ME_TO_STRONG_RANDOM_KEY_MIN_32_CHARS" |
| azure-openai-endpoint: "https://your-resource.openai.azure.com/" |
| azure-openai-key: "CHANGE_ME" |
|
|
| --- |
| |
| |
| |
| apiVersion: apps/v1 |
| kind: Deployment |
| metadata: |
| name: bre-gateway |
| namespace: optimai-bre |
| labels: |
| app: bre-gateway |
| version: "1.0.0" |
| spec: |
| replicas: 3 |
| selector: |
| matchLabels: |
| app: bre-gateway |
| strategy: |
| type: RollingUpdate |
| rollingUpdate: |
| maxSurge: 1 |
| maxUnavailable: 0 |
| template: |
| metadata: |
| labels: |
| app: bre-gateway |
| version: "1.0.0" |
| annotations: |
| prometheus.io/scrape: "true" |
| prometheus.io/port: "8080" |
| prometheus.io/path: "/metrics" |
| spec: |
| terminationGracePeriodSeconds: 30 |
| affinity: |
| podAntiAffinity: |
| requiredDuringSchedulingIgnoredDuringExecution: |
| - labelSelector: |
| matchExpressions: |
| - key: app |
| operator: In |
| values: |
| - bre-gateway |
| topologyKey: kubernetes.io/hostname |
| containers: |
| - name: bre-gateway |
| image: optimai/bre-gateway:1.0.0 |
| imagePullPolicy: Always |
| ports: |
| - containerPort: 8080 |
| name: http |
| env: |
| - name: ConnectionStrings__PostgreSQL |
| valueFrom: |
| secretKeyRef: |
| name: bre-secrets |
| key: postgres-connection |
| - name: ConnectionStrings__Redis |
| valueFrom: |
| secretKeyRef: |
| name: bre-secrets |
| key: redis-connection |
| - name: Jwt__SecretKey |
| valueFrom: |
| secretKeyRef: |
| name: bre-secrets |
| key: jwt-secret-key |
| - name: AiOptions__Endpoint |
| valueFrom: |
| secretKeyRef: |
| name: bre-secrets |
| key: azure-openai-endpoint |
| - name: AiOptions__ApiKey |
| valueFrom: |
| secretKeyRef: |
| name: bre-secrets |
| key: azure-openai-key |
| envFrom: |
| - configMapRef: |
| name: bre-config |
| resources: |
| requests: |
| memory: "256Mi" |
| cpu: "250m" |
| limits: |
| memory: "512Mi" |
| cpu: "1000m" |
| readinessProbe: |
| httpGet: |
| path: /health/ready |
| port: 8080 |
| initialDelaySeconds: 20 |
| periodSeconds: 10 |
| failureThreshold: 3 |
| livenessProbe: |
| httpGet: |
| path: /health |
| port: 8080 |
| initialDelaySeconds: 30 |
| periodSeconds: 30 |
| failureThreshold: 3 |
| lifecycle: |
| preStop: |
| exec: |
| command: ["/bin/sh", "-c", "sleep 5"] |
| volumeMounts: |
| - name: logs |
| mountPath: /app/logs |
| volumes: |
| - name: logs |
| emptyDir: {} |
|
|
| --- |
| |
| |
| |
| apiVersion: v1 |
| kind: Service |
| metadata: |
| name: bre-gateway-service |
| namespace: optimai-bre |
| labels: |
| app: bre-gateway |
| spec: |
| type: ClusterIP |
| selector: |
| app: bre-gateway |
| ports: |
| - port: 80 |
| targetPort: 8080 |
| name: http |
|
|
| --- |
| |
| |
| |
| apiVersion: autoscaling/v2 |
| kind: HorizontalPodAutoscaler |
| metadata: |
| name: bre-gateway-hpa |
| namespace: optimai-bre |
| spec: |
| scaleTargetRef: |
| apiVersion: apps/v1 |
| kind: Deployment |
| name: bre-gateway |
| minReplicas: 3 |
| maxReplicas: 20 |
| 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: 120 |
|
|
| --- |
| |
| |
| |
| apiVersion: policy/v1 |
| kind: PodDisruptionBudget |
| metadata: |
| name: bre-gateway-pdb |
| namespace: optimai-bre |
| spec: |
| minAvailable: 2 |
| selector: |
| matchLabels: |
| app: bre-gateway |
|
|
| --- |
| |
| |
| |
| apiVersion: apps/v1 |
| kind: Deployment |
| metadata: |
| name: bre-frontend |
| namespace: optimai-bre |
| spec: |
| replicas: 2 |
| selector: |
| matchLabels: |
| app: bre-frontend |
| template: |
| metadata: |
| labels: |
| app: bre-frontend |
| spec: |
| containers: |
| - name: bre-frontend |
| image: optimai/bre-frontend:1.0.0 |
| ports: |
| - containerPort: 3000 |
| env: |
| - name: NEXT_PUBLIC_API_URL |
| value: "https://api.optimaibre.com/api/v1" |
| resources: |
| requests: |
| memory: "128Mi" |
| cpu: "100m" |
| limits: |
| memory: "256Mi" |
| cpu: "500m" |
| readinessProbe: |
| httpGet: |
| path: /api/health |
| port: 3000 |
| initialDelaySeconds: 15 |
| periodSeconds: 10 |
|
|
| --- |
| apiVersion: v1 |
| kind: Service |
| metadata: |
| name: bre-frontend-service |
| namespace: optimai-bre |
| spec: |
| type: ClusterIP |
| selector: |
| app: bre-frontend |
| ports: |
| - port: 80 |
| targetPort: 3000 |
|
|
| --- |
| |
| |
| |
| apiVersion: networking.k8s.io/v1 |
| kind: Ingress |
| metadata: |
| name: bre-ingress |
| namespace: optimai-bre |
| annotations: |
| kubernetes.io/ingress.class: nginx |
| nginx.ingress.kubernetes.io/ssl-redirect: "true" |
| nginx.ingress.kubernetes.io/proxy-body-size: "10m" |
| nginx.ingress.kubernetes.io/proxy-read-timeout: "60" |
| nginx.ingress.kubernetes.io/rate-limit: "1000" |
| nginx.ingress.kubernetes.io/rate-limit-window: "1m" |
| cert-manager.io/cluster-issuer: letsencrypt-prod |
| spec: |
| tls: |
| - hosts: |
| - api.optimaibre.com |
| - app.optimaibre.com |
| secretName: bre-tls-secret |
| rules: |
| - host: api.optimaibre.com |
| http: |
| paths: |
| - path: / |
| pathType: Prefix |
| backend: |
| service: |
| name: bre-gateway-service |
| port: |
| number: 80 |
| - host: app.optimaibre.com |
| http: |
| paths: |
| - path: / |
| pathType: Prefix |
| backend: |
| service: |
| name: bre-frontend-service |
| port: |
| number: 80 |
|
|
| --- |
| |
| |
| |
| apiVersion: apps/v1 |
| kind: StatefulSet |
| metadata: |
| name: postgres |
| namespace: optimai-bre |
| spec: |
| serviceName: postgres-service |
| replicas: 1 |
| selector: |
| matchLabels: |
| app: postgres |
| template: |
| metadata: |
| labels: |
| app: postgres |
| spec: |
| containers: |
| - name: postgres |
| image: postgres:15-alpine |
| env: |
| - name: POSTGRES_DB |
| value: optimai_bre |
| - name: POSTGRES_USER |
| value: optimai |
| - name: POSTGRES_PASSWORD |
| valueFrom: |
| secretKeyRef: |
| name: bre-secrets |
| key: postgres-password |
| - name: PGDATA |
| value: /var/lib/postgresql/data/pgdata |
| ports: |
| - containerPort: 5432 |
| resources: |
| requests: |
| memory: "512Mi" |
| cpu: "500m" |
| limits: |
| memory: "2Gi" |
| cpu: "2000m" |
| volumeMounts: |
| - name: postgres-data |
| mountPath: /var/lib/postgresql/data |
| readinessProbe: |
| exec: |
| command: ["pg_isready", "-U", "optimai", "-d", "optimai_bre"] |
| initialDelaySeconds: 10 |
| periodSeconds: 5 |
| volumeClaimTemplates: |
| - metadata: |
| name: postgres-data |
| spec: |
| accessModes: ["ReadWriteOnce"] |
| storageClassName: "managed-premium" |
| resources: |
| requests: |
| storage: 100Gi |
|
|
| --- |
| apiVersion: v1 |
| kind: Service |
| metadata: |
| name: postgres-service |
| namespace: optimai-bre |
| spec: |
| clusterIP: None |
| selector: |
| app: postgres |
| ports: |
| - port: 5432 |
|
|
| --- |
| |
| |
| |
| apiVersion: apps/v1 |
| kind: StatefulSet |
| metadata: |
| name: redis |
| namespace: optimai-bre |
| spec: |
| serviceName: redis-service |
| replicas: 1 |
| selector: |
| matchLabels: |
| app: redis |
| template: |
| metadata: |
| labels: |
| app: redis |
| spec: |
| containers: |
| - name: redis |
| image: redis:7-alpine |
| command: |
| - redis-server |
| - --requirepass |
| - $(REDIS_PASSWORD) |
| - --maxmemory |
| - 512mb |
| - --maxmemory-policy |
| - allkeys-lru |
| env: |
| - name: REDIS_PASSWORD |
| valueFrom: |
| secretKeyRef: |
| name: bre-secrets |
| key: redis-password |
| ports: |
| - containerPort: 6379 |
| resources: |
| requests: |
| memory: "256Mi" |
| cpu: "100m" |
| limits: |
| memory: "512Mi" |
| cpu: "500m" |
| volumeMounts: |
| - name: redis-data |
| mountPath: /data |
| volumeClaimTemplates: |
| - metadata: |
| name: redis-data |
| spec: |
| accessModes: ["ReadWriteOnce"] |
| resources: |
| requests: |
| storage: 10Gi |
|
|
| --- |
| apiVersion: v1 |
| kind: Service |
| metadata: |
| name: redis-service |
| namespace: optimai-bre |
| spec: |
| clusterIP: None |
| selector: |
| app: redis |
| ports: |
| - port: 6379 |
|
|