This commit is contained in:
2026-03-23 11:13:30 -03:00
parent 8186bb5fe6
commit 71fd0510de
34 changed files with 1373 additions and 104 deletions

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: mpr-config
namespace: mpr
data:
REDIS_URL: redis://redis:6379/0
DEBUG: "1"
FASTAPI_PORT: "8702"
DETECTION_UI_PORT: "5175"
GATEWAY_PORT: "8080"

View File

@@ -0,0 +1,44 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: detection-ui
namespace: mpr
spec:
replicas: 1
selector:
matchLabels:
app: detection-ui
template:
metadata:
labels:
app: detection-ui
spec:
containers:
- name: detection-ui
image: mpr-detection
ports:
- containerPort: 5175
envFrom:
- configMapRef:
name: mpr-config
env:
- name: VITE_ALLOWED_HOSTS
value: "k8s.mpr.local.ar"
resources:
requests:
memory: 64Mi
cpu: 50m
limits:
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: detection-ui
namespace: mpr
spec:
selector:
app: detection-ui
ports:
- port: 5175
targetPort: 5175

View File

@@ -0,0 +1,48 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi
namespace: mpr
spec:
replicas: 1
selector:
matchLabels:
app: fastapi
template:
metadata:
labels:
app: fastapi
spec:
containers:
- name: fastapi
image: mpr-fastapi
command: ["sh", "-c", "uvicorn core.api.main:app --host 0.0.0.0 --port $FASTAPI_PORT --reload"]
ports:
- containerPort: 8702
envFrom:
- configMapRef:
name: mpr-config
readinessProbe:
httpGet:
path: /health
port: 8702
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: 128Mi
cpu: 100m
limits:
memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
name: fastapi
namespace: mpr
spec:
selector:
app: fastapi
ports:
- port: 8702
targetPort: 8702

128
ctrl/k8s/base/gateway.yaml Normal file
View File

@@ -0,0 +1,128 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: envoy-gateway-config
namespace: mpr
data:
envoy.yaml: |
static_resources:
listeners:
- name: http
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress
codec_type: AUTO
route_config:
name: local_routes
virtual_hosts:
- name: mpr
domains: ["k8s.mpr.local.ar", "*"]
routes:
# SSE — long timeout, no buffering
- match:
prefix: "/api/detect/stream/"
route:
cluster: fastapi
timeout: 3600s
idle_timeout: 3600s
# FastAPI — strip /api/ prefix
- match:
prefix: "/api/"
route:
cluster: fastapi
prefix_rewrite: "/"
# Detection UI
- match:
prefix: "/detection/"
route:
cluster: detection-ui
# Default
- match:
prefix: "/"
route:
cluster: detection-ui
prefix_rewrite: "/detection/"
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: fastapi
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: fastapi
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: fastapi
port_value: 8702
- name: detection-ui
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: detection-ui
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: detection-ui
port_value: 5175
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway
namespace: mpr
spec:
replicas: 1
selector:
matchLabels:
app: gateway
template:
metadata:
labels:
app: gateway
spec:
containers:
- name: envoy
image: envoyproxy/envoy:v1.28-latest
ports:
- containerPort: 8080
volumeMounts:
- name: config
mountPath: /etc/envoy
resources:
requests:
memory: 64Mi
cpu: 50m
limits:
memory: 256Mi
volumes:
- name: config
configMap:
name: envoy-gateway-config
---
apiVersion: v1
kind: Service
metadata:
name: gateway
namespace: mpr
spec:
selector:
app: gateway
ports:
- port: 80
targetPort: 8080

View File

@@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mpr
resources:
- namespace.yaml
- configmap.yaml
- redis.yaml
- fastapi.yaml
- detection-ui.yaml
- gateway.yaml

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: mpr

43
ctrl/k8s/base/redis.yaml Normal file
View File

@@ -0,0 +1,43 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: mpr
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
readinessProbe:
exec:
command: ["redis-cli", "ping"]
initialDelaySeconds: 2
periodSeconds: 5
resources:
requests:
memory: 64Mi
cpu: 50m
limits:
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: mpr
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379

View File

@@ -0,0 +1,38 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: detection-ui
namespace: mpr
spec:
replicas: 1
selector:
matchLabels:
app: detection-ui
template:
metadata:
labels:
app: detection-ui
spec:
containers:
- name: detection-ui
image: mpr-detection
ports:
- containerPort: 5175
resources:
requests:
memory: 64Mi
cpu: 50m
limits:
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: detection-ui
namespace: mpr
spec:
selector:
app: detection-ui
ports:
- port: 5175
targetPort: 5175

View File

@@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi
namespace: mpr
spec:
replicas: 1
selector:
matchLabels:
app: fastapi
template:
metadata:
labels:
app: fastapi
spec:
containers:
- name: fastapi
image: mpr-fastapi
command: ["uvicorn", "core.api.main:app", "--host", "0.0.0.0", "--port", "8702", "--reload"]
ports:
- containerPort: 8702
env:
- name: REDIS_URL
value: redis://redis:6379/0
- name: DJANGO_ALLOW_ASYNC_UNSAFE
value: "true"
- name: DEBUG
value: "1"
readinessProbe:
httpGet:
path: /health
port: 8702
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: 128Mi
cpu: 100m
limits:
memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
name: fastapi
namespace: mpr
spec:
selector:
app: fastapi
ports:
- port: 8702
targetPort: 8702

View File

@@ -0,0 +1,128 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: envoy-gateway-config
namespace: mpr
data:
envoy.yaml: |
static_resources:
listeners:
- name: http
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress
codec_type: AUTO
route_config:
name: local_routes
virtual_hosts:
- name: mpr
domains: ["k8s.mpr.local.ar", "*"]
routes:
# SSE — disable buffering
- match:
prefix: "/api/detect/stream/"
route:
cluster: fastapi
timeout: 3600s
idle_timeout: 3600s
# FastAPI — strip /api/ prefix
- match:
prefix: "/api/"
route:
cluster: fastapi
prefix_rewrite: "/"
# Detection UI
- match:
prefix: "/detection/"
route:
cluster: detection-ui
# Default — detection UI
- match:
prefix: "/"
route:
cluster: detection-ui
prefix_rewrite: "/detection/"
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: fastapi
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: fastapi
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: fastapi
port_value: 8702
- name: detection-ui
connect_timeout: 5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: detection-ui
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: detection-ui
port_value: 5175
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway
namespace: mpr
spec:
replicas: 1
selector:
matchLabels:
app: gateway
template:
metadata:
labels:
app: gateway
spec:
containers:
- name: envoy
image: envoyproxy/envoy:v1.28-latest
ports:
- containerPort: 8080
volumeMounts:
- name: config
mountPath: /etc/envoy
resources:
requests:
memory: 64Mi
cpu: 50m
limits:
memory: 256Mi
volumes:
- name: config
configMap:
name: envoy-gateway-config
---
apiVersion: v1
kind: Service
metadata:
name: gateway
namespace: mpr
spec:
selector:
app: gateway
ports:
- port: 80
targetPort: 8080

View File

@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mpr
resources:
- namespace.yaml
- redis.yaml
- fastapi.yaml
- detection-ui.yaml
- gateway.yaml

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: mpr

View File

@@ -0,0 +1,43 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: mpr
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
readinessProbe:
exec:
command: ["redis-cli", "ping"]
initialDelaySeconds: 2
periodSeconds: 5
resources:
requests:
memory: 64Mi
cpu: 50m
limits:
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: mpr
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379

View File

@@ -0,0 +1,20 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
# Gateway as cloud LoadBalancer
- target:
kind: Service
name: gateway
patch: |
- op: replace
path: /spec/type
value: LoadBalancer
- op: add
path: /metadata/annotations
value:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-scheme: internal

View File

@@ -0,0 +1,30 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
# Gateway as NodePort for local access
- target:
kind: Service
name: gateway
patch: |
- op: replace
path: /spec/type
value: NodePort
- op: add
path: /spec/ports/0/nodePort
value: 30080
# Redis as NodePort for redis-cli access from host
- target:
kind: Service
name: redis
patch: |
- op: replace
path: /spec/type
value: NodePort
- op: add
path: /spec/ports/0/nodePort
value: 30379

View File

@@ -0,0 +1,15 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
# Gateway as LoadBalancer — MetalLB assigns a LAN IP
- target:
kind: Service
name: gateway
patch: |
- op: replace
path: /spec/type
value: LoadBalancer

15
ctrl/k8s/kind-config.yaml Normal file
View File

@@ -0,0 +1,15 @@
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: mpr
nodes:
- role: control-plane
extraPortMappings:
# Gateway → http://k8s.mpr.local.ar (bind to 127.0.0.2 to avoid conflict with docker-compose on 127.0.0.1:80)
- containerPort: 30080
hostPort: 80
listenAddress: "127.0.0.2"
protocol: TCP
# Redis
- containerPort: 30379
hostPort: 6382
protocol: TCP

View File

@@ -0,0 +1,20 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
# Gateway as cloud LoadBalancer
- target:
kind: Service
name: gateway
patch: |
- op: replace
path: /spec/type
value: LoadBalancer
- op: add
path: /metadata/annotations
value:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-scheme: internal

View File

@@ -0,0 +1,30 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
# Gateway as NodePort for local access
- target:
kind: Service
name: gateway
patch: |
- op: replace
path: /spec/type
value: NodePort
- op: add
path: /spec/ports/0/nodePort
value: 30080
# Redis as NodePort for redis-cli access from host
- target:
kind: Service
name: redis
patch: |
- op: replace
path: /spec/type
value: NodePort
- op: add
path: /spec/ports/0/nodePort
value: 30379

View File

@@ -0,0 +1,15 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
# Gateway as LoadBalancer — MetalLB assigns a LAN IP
- target:
kind: Service
name: gateway
patch: |
- op: replace
path: /spec/type
value: LoadBalancer