From 5d51971270135df9665217c83da04995c70c5c2f Mon Sep 17 00:00:00 2001 From: Coralware IDP CI Date: Thu, 21 May 2026 10:04:51 -0500 Subject: [PATCH] =?UTF-8?q?chore:=20migrar=20Ingress=20Traefik=E2=86=92NGI?= =?UTF-8?q?NX=20+=20cascada=20wildcard=20cert=20(sync=20APERTURA=20COVE=20?= =?UTF-8?q?S3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/APP_NAME-build.yaml | 7 ++++- helm/APP_NAME/Chart.yaml | 8 ++++- helm/APP_NAME/templates/ingress.yaml | 35 ++++++++++++++++++++++ helm/APP_NAME/templates/ingressroute.yaml | 19 ------------ helm/APP_NAME/templates/networkpolicy.yaml | 8 +++-- helm/APP_NAME/values.yaml | 18 +++++++++-- 6 files changed, 69 insertions(+), 26 deletions(-) create mode 100644 helm/APP_NAME/templates/ingress.yaml delete mode 100644 helm/APP_NAME/templates/ingressroute.yaml diff --git a/.gitea/workflows/APP_NAME-build.yaml b/.gitea/workflows/APP_NAME-build.yaml index 46761ed..ae7b2d6 100644 --- a/.gitea/workflows/APP_NAME-build.yaml +++ b/.gitea/workflows/APP_NAME-build.yaml @@ -83,8 +83,13 @@ jobs: kubectl -n apps rollout status deploy/__APP_NAME__ --timeout=3m - name: Smoke check post-deploy + # FQDN con tenant-id CON guiones — coincide con el A record que crea + # cloudflare-provisioner (Gap 5) y con el host del Ingress NGINX + # (helm/APP_NAME/values.yaml). Antes usaba TENANT_ID_NODASHES, lo + # que no resolvía al A record canónico — corregido APERTURA COVE + # Sesión 3 (TENANT-INGRESS-CONTROLLER-MISMATCH). env: - INGRESS_HOST: __APP_NAME__-${{ vars.TENANT_ID_NODASHES }}.apps.coralware.cloud + INGRESS_HOST: __APP_NAME__-${{ vars.TENANT_ID }}.apps.coralware.cloud run: | for i in $(seq 1 12); do if wget -q -O - --timeout=10 "https://${INGRESS_HOST}/health" | grep -q '"status":"ok"'; then diff --git a/helm/APP_NAME/Chart.yaml b/helm/APP_NAME/Chart.yaml index 0156f0d..599a6cb 100644 --- a/helm/APP_NAME/Chart.yaml +++ b/helm/APP_NAME/Chart.yaml @@ -1,8 +1,14 @@ apiVersion: v2 name: __APP_NAME__ +# Helm chart del Golden Path web-backend/python. +# 0.2.0 (2026-05-19): cambio Ingress controller Traefik (IngressRoute CRD) +# → rke2-ingress-nginx (networking.k8s.io/v1 Ingress). Razón: +# TENANT-INGRESS-CONTROLLER-MISMATCH (APERTURA COVE Sesión 3). El cluster +# tenant nace con rke2-ingress-nginx y no se quiere instalar Traefik +# adicional. tlsSecretName por default = apps-wildcard-tls (Gap 3). description: Helm chart del Golden Path web-backend/python type: application -version: 0.1.0 +version: 0.2.0 appVersion: "0.1.0" keywords: - fastapi diff --git a/helm/APP_NAME/templates/ingress.yaml b/helm/APP_NAME/templates/ingress.yaml new file mode 100644 index 0000000..cefda32 --- /dev/null +++ b/helm/APP_NAME/templates/ingress.yaml @@ -0,0 +1,35 @@ +{{- if .Values.ingress.enabled }} +# Ingress estándar networking.k8s.io/v1 con ingressClassName=nginx. +# Razón: el cluster tenant nace con rke2-ingress-nginx por default — +# instalar Traefik añade footprint e inconsistencia respecto al control +# plane (donde Traefik sí está). NGINX Ingress es más portable y permite +# que el tenant siga su exit plan sin lock-in. +# Decisión: APERTURA COVE Sesión 3 (2026-05-19) — ADR-053 §11. +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ .Release.Name }} + labels: + {{- include "app.labels" . | nindent 4 }} + annotations: + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-body-size: {{ .Values.ingress.proxyBodySize | default "10m" | quote }} +spec: + ingressClassName: {{ .Values.ingress.className | default "nginx" }} + tls: + - hosts: + - {{ .Values.ingress.host | quote }} + secretName: {{ .Values.ingress.tlsSecretName | default "apps-wildcard-tls" }} + rules: + - host: {{ .Values.ingress.host | quote }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ .Release.Name }} + port: + number: {{ .Values.service.port }} +{{- end }} diff --git a/helm/APP_NAME/templates/ingressroute.yaml b/helm/APP_NAME/templates/ingressroute.yaml deleted file mode 100644 index e85a4dc..0000000 --- a/helm/APP_NAME/templates/ingressroute.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if .Values.ingress.enabled }} -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: {{ .Release.Name }} - labels: - {{- include "app.labels" . | nindent 4 }} -spec: - entryPoints: - - websecure - routes: - - match: Host(`{{ .Values.ingress.host }}`) - kind: Rule - services: - - name: {{ .Release.Name }} - port: {{ .Values.service.port }} - tls: - secretName: {{ .Values.ingress.tlsSecretName }} -{{- end }} diff --git a/helm/APP_NAME/templates/networkpolicy.yaml b/helm/APP_NAME/templates/networkpolicy.yaml index 2a70261..465568b 100644 --- a/helm/APP_NAME/templates/networkpolicy.yaml +++ b/helm/APP_NAME/templates/networkpolicy.yaml @@ -1,7 +1,8 @@ {{- if .Values.networkPolicy.enabled }} # NetworkPolicy mínima del shape: bajo deny-all-default del namespace, permite: -# - Ingress: Traefik (web-backend público) + Prometheus (scrape de /metrics). +# - Ingress: rke2-ingress-nginx (web-backend público) + Prometheus (scrape de /metrics). # - Egress: DNS, Harbor (pull en startup), ns-addons del tenant (BD). +# Nota: el cluster tenant usa rke2-ingress-nginx en kube-system, NO Traefik. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -15,11 +16,12 @@ spec: policyTypes: [Ingress, Egress] ingress: - # Tráfico HTTP desde Traefik (IngressRoute) + # Tráfico HTTP desde rke2-ingress-nginx (Ingress estándar). + # El controller corre en kube-system por default en RKE2. - from: - namespaceSelector: matchLabels: - kubernetes.io/metadata.name: traefik-system + kubernetes.io/metadata.name: {{ .Values.networkPolicy.ingressControllerNamespace | default "kube-system" }} ports: - protocol: TCP port: 8000 diff --git a/helm/APP_NAME/values.yaml b/helm/APP_NAME/values.yaml index 7e6e4fe..8076483 100644 --- a/helm/APP_NAME/values.yaml +++ b/helm/APP_NAME/values.yaml @@ -49,8 +49,19 @@ service: ingress: enabled: true - host: __APP_NAME__-__TENANT_ID_NODASHES__.apps.coralware.cloud - tlsSecretName: __APP_NAME__-tls + # className por defecto = nginx (rke2-ingress-nginx pre-instalado en cluster tenant). + # Cambiar solo si el tenant trae su propio IngressClass. + className: nginx + # Host con tenant-id CON guiones (formato canónico Cove): coincide con + # los A records que crea cloudflare-provisioner (Gap 5) y el wildcard + # cert apps-wildcard-tls (Gap 3). + host: __APP_NAME__-__TENANT_ID__.apps.coralware.cloud + # Secret TLS provisto por el wildcard *.apps.coralware.cloud sembrado + # en el cluster tenant por el agente cloudflare/cert-manager (Gap 3). + # NO se renombra por app — todas las apps del tenant lo comparten. + tlsSecretName: apps-wildcard-tls + # Body size para subidas/uploads de la app — ajustar según necesidad. + proxyBodySize: 10m alembic: enabled: true @@ -67,3 +78,6 @@ serviceMonitor: networkPolicy: enabled: true addonsNamespace: addons # ADR-054: namespace funcional fijo en cluster tenant + # Namespace donde corre el ingress controller del cluster tenant. + # RKE2 instala rke2-ingress-nginx en kube-system por default. + ingressControllerNamespace: kube-system