- Ensure prefix is passed for all services

- Add eveai-tem secret (Scaleway Transactional Email) to allow sending emails
- Adapted security URLs
- Certification problem in regions solved
- Redis insight added to tools in k8s
- Introduced new way of connection pooling for Redis
- TRA-79 - intrernal server error bij registreren catalog
This commit is contained in:
Josako
2025-09-09 08:45:45 +02:00
parent 804486664b
commit a9bbd1f466
15 changed files with 447 additions and 103 deletions

View File

@@ -1,14 +1,19 @@
Routing alignment notes (staging/prod)
Summary
- Root (/) issues a 301 redirect to /admin/ via server-snippet on the apps ingress.
- Prefixes /admin, /api, /chat-client are stripped at the edge and forwarded to their backends on /. The applications do not need to be prefix-aware.
- Root (/) redirect will be handled at Bunny (edge). No server-snippet is used in the ingress.
- Prefixes /admin, /api, /chat-client are stripped at the ingress and forwarded to their backends on /. The applications do not need to be prefix-routed internally.
- For consistent external URLs (especially after POST/redirect), each prefix Ingress injects X-Forwarded-Prefix via nginx.ingress.kubernetes.io/proxy-set-headers and a per-prefix ConfigMap.
- /verify remains available (Prefix) without any rewrite in a separate Ingress.
- No CORS annotations at ingress. Static assets are served by Bunny CDN; API CORS is not handled here.
- /flower is intentionally NOT exposed on k8s.
Files
- ingress-https.yaml: NGINX Ingress (apps) with regex paths and rewrite-target to strip prefixes; includes server-snippet to 301 redirect root to /admin/.
- ingress-admin.yaml: Ingress for /admin with regex paths, rewrite-target to strip prefix, and proxy-set-headers pointing to eveai-admin-headers.
- ingress-api.yaml: Ingress for /api with regex paths, rewrite-target to strip prefix, and proxy-set-headers pointing to eveai-api-headers.
- ingress-chat-client.yaml: Ingress for /chat-client with regex paths, rewrite-target to strip prefix, and proxy-set-headers pointing to eveai-chat-headers.
- headers-configmaps.yaml: ConfigMaps defining X-Forwarded-Prefix per ingress.
- ingress-https.yaml: Legacy combined ingress retained for reference; server-snippet removed. Consider deprecating once split ingresses are applied.
- ingress-verify.yaml: Separate Ingress for /verify without regex/rewrite.
Paths behavior

View File

@@ -0,0 +1,24 @@
# ConfigMaps defining per-ingress proxy-set-headers
apiVersion: v1
kind: ConfigMap
metadata:
name: eveai-admin-headers
namespace: eveai-staging
data:
X-Forwarded-Prefix: /admin
---
apiVersion: v1
kind: ConfigMap
metadata:
name: eveai-api-headers
namespace: eveai-staging
data:
X-Forwarded-Prefix: /api
---
apiVersion: v1
kind: ConfigMap
metadata:
name: eveai-chat-headers
namespace: eveai-staging
data:
X-Forwarded-Prefix: /chat-client

View File

@@ -0,0 +1,36 @@
# Ingress for /admin prefix with X-Forwarded-Prefix header
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: eveai-admin-ingress
namespace: eveai-staging
labels:
app: eveai
environment: staging
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
cert-manager.io/cluster-issuer: letsencrypt-staging
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: "/$2"
nginx.ingress.kubernetes.io/proxy-set-headers: "eveai-staging/eveai-admin-headers"
spec:
ingressClassName: nginx
tls:
- hosts:
- evie-staging.askeveai.com
secretName: evie-staging-tls
rules:
- host: evie-staging.askeveai.com
http:
paths:
- path: /admin(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: eveai-app-service
port:
number: 80

View File

@@ -0,0 +1,36 @@
# Ingress for /api prefix with X-Forwarded-Prefix header (optional but consistent)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: eveai-api-ingress
namespace: eveai-staging
labels:
app: eveai
environment: staging
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
cert-manager.io/cluster-issuer: letsencrypt-staging
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: "/$2"
nginx.ingress.kubernetes.io/proxy-set-headers: "eveai-staging/eveai-api-headers"
spec:
ingressClassName: nginx
tls:
- hosts:
- evie-staging.askeveai.com
secretName: evie-staging-tls
rules:
- host: evie-staging.askeveai.com
http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: eveai-api-service
port:
number: 80

View File

@@ -0,0 +1,36 @@
# Ingress for /chat-client prefix with X-Forwarded-Prefix header (optional but consistent)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: eveai-chat-client-ingress
namespace: eveai-staging
labels:
app: eveai
environment: staging
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
cert-manager.io/cluster-issuer: letsencrypt-staging
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: "/$2"
nginx.ingress.kubernetes.io/proxy-set-headers: "eveai-staging/eveai-chat-headers"
spec:
ingressClassName: nginx
tls:
- hosts:
- evie-staging.askeveai.com
secretName: evie-staging-tls
rules:
- host: evie-staging.askeveai.com
http:
paths:
- path: /chat-client(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: eveai-chat-client-service
port:
number: 80

View File

@@ -16,10 +16,6 @@ metadata:
cert-manager.io/cluster-issuer: letsencrypt-staging
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: "/$2"
nginx.ingress.kubernetes.io/server-snippet: |
location = / {
return 301 /admin/;
}
spec:
ingressClassName: nginx
tls:
@@ -30,28 +26,12 @@ spec:
- host: evie-staging.askeveai.com
http:
paths:
# Application services (strip prefix)
- path: /admin(/|$)(.*)
pathType: ImplementationSpecific
- path: /verify
pathType: Prefix
backend:
service:
name: eveai-app-service
port:
number: 80
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: eveai-api-service
port:
number: 80
- path: /chat-client(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: eveai-chat-client-service
name: verify-service
port:
number: 80
# Application services (strip prefix) are now defined in dedicated ingress files

View File

@@ -31,6 +31,9 @@ spec:
# Alle keys uit eveai-object-storage secret
- extract:
key: name:eveai-object-storage
# Alle keys uit eveai-tem secret
- extract:
key: name:eveai-tem
data:
# Certificaat als aparte data entry
- secretKey: REDIS_CERT

View File

@@ -0,0 +1,49 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: redisinsight-redis
namespace: tools
spec:
refreshInterval: 5m
secretStoreRef:
kind: ClusterSecretStore
name: scaleway-secret-store
target:
name: redisinsight-redis
creationPolicy: Owner
data:
- secretKey: REDIS_USER
remoteRef:
key: eveai-redis
property: REDIS_USER
- secretKey: REDIS_PASS
remoteRef:
key: eveai-redis
property: REDIS_PASS
- secretKey: REDIS_URL
remoteRef:
key: eveai-redis
property: REDIS_URL
- secretKey: REDIS_PORT
remoteRef:
key: eveai-redis
property: REDIS_PORT
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: redisinsight-ca
namespace: tools
spec:
refreshInterval: 5m
secretStoreRef:
kind: ClusterSecretStore
name: scaleway-secret-store
target:
name: redisinsight-ca
creationPolicy: Owner
data:
- secretKey: REDIS_CERT
remoteRef:
key: eveai-redis-certificate
property: REDIS_CERT

View File

@@ -0,0 +1,95 @@
apiVersion: v1
kind: Namespace
metadata:
name: tools
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redisinsight-data
namespace: tools
labels:
app: redisinsight
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
# storageClassName: default # uncomment and set if your cluster requires an explicit storage class
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redisinsight
namespace: tools
labels:
app: redisinsight
spec:
replicas: 1
selector:
matchLabels:
app: redisinsight
template:
metadata:
labels:
app: redisinsight
spec:
securityContext:
fsGroup: 1001
containers:
- name: redisinsight
image: redis/redisinsight:2.54.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 5540
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
securityContext:
runAsNonRoot: true
runAsUser: 1001
runAsGroup: 1001
readOnlyRootFilesystem: false
volumeMounts:
- name: data
mountPath: /data
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 30
periodSeconds: 20
timeoutSeconds: 2
volumes:
- name: data
persistentVolumeClaim:
claimName: redisinsight-data
---
apiVersion: v1
kind: Service
metadata:
name: redisinsight
namespace: tools
labels:
app: redisinsight
spec:
type: ClusterIP
selector:
app: redisinsight
ports:
- name: http
port: 5540
targetPort: http