From 3042c96c6b5b0cbe353723e69a74739b124e324c Mon Sep 17 00:00:00 2001 From: iilc Date: Tue, 26 May 2026 21:19:37 -0500 Subject: [PATCH] =?UTF-8?q?chart=20wait-for-secret=20240s=20=E2=86=92=2036?= =?UTF-8?q?0s=20+=20helm=20timeout=207m=20=E2=86=92=2010m?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync del fix ADDON-PROVISIONER-DB-SECRET-NOT-PUBLISHED (IDP P0). Ver IDP commit 673c16d para contexto completo. El init container wait-for-secret del Job Alembic ahora espera 72×5s=360s (antes 48×5s=240s), dimensionado a 3× el RECONCILE_INTERVAL del addon-provisioner. El controller bajó su default 300s → 60s en el mismo parche. Defense-in-depth: con el controller corriendo a 60s, el delay típico del Secret publish es ~60-180s. Los 360s del init container absorben hasta 3 ticks fallidos del controller (cluster recién Ready, kubeconfig no propagado, etc.). helm timeout 7m → 10m para que el wait extendido del init container + Alembic + StatefulSet ready quepan dentro del comando helm. Co-Authored-By: Claude Opus 4.7 --- .gitea/workflows/APP_NAME-build.yaml | 14 +++++++++----- README.md | 4 ++-- .../templates/job-alembic-upgrade.yaml | 19 +++++++++++-------- manifests/addonclaim.yaml | 2 +- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/.gitea/workflows/APP_NAME-build.yaml b/.gitea/workflows/APP_NAME-build.yaml index dac66b3..0fdb6cf 100644 --- a/.gitea/workflows/APP_NAME-build.yaml +++ b/.gitea/workflows/APP_NAME-build.yaml @@ -188,11 +188,15 @@ jobs: --set tenantId=${TENANT_ID} \ --set tenantIdNodashes=${TENANT_ID_NODASHES} \ --set tier=${TENANT_TIER} \ - --wait --timeout 7m - # 7m absorbe el peor caso del reconcile de addon-provisioner - # (RECONCILE_INTERVAL 300s + initial_delay 60s) + StatefulSet MariaDB - # ready (~60s) + Job DDL (~10s) + InitContainer wait-for-secret + Alembic. - # AddonClaim ya fue aplicado en el step previo (ADR-066). + --wait --timeout 10m + # 10m absorbe el peor caso del reconcile de addon-provisioner + # (RECONCILE_INTERVAL 60s + initial_delay 60s + 3 ticks ≈ 240s) + + # StatefulSet MariaDB ready (~60s) + Job DDL (~10s) + + # InitContainer wait-for-secret 360s + Alembic. Lección 2026-05-28: + # con RECONCILE_INTERVAL=300s y wait 240s el init container moria + # antes (delay observado 577s, ticket + # ADDON-PROVISIONER-DB-SECRET-NOT-PUBLISHED). AddonClaim ya fue + # aplicado en el step previo (ADR-066). - name: Verificar rollout run: | diff --git a/README.md b/README.md index 9b03d33..4c3baa6 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ el orden de creación de SUS recursos (sin AddonClaim — ese vive fuera). | `NetworkPolicy` | `networkpolicy.yaml` | `-8` | Bajo el `default-deny` del namespace `apps`, esta NP permite DNS + apiserver + addons:3306. Debe existir antes que el InitContainer del Job Alembic intente conectarse al apiserver. | | `Role` + `RoleBinding` | `role-db-secret-reader.yaml` | `-7` | Permite al SA leer el Secret `-db-creds` (lo consume el InitContainer `wait-for-secret` del Job Alembic) | | `ServiceAccount` | `serviceaccount.yaml` | `-5` | Lo referencia el pod del Job Alembic — debe existir antes | -| `Job` Alembic | `job-alembic-upgrade.yaml` | `0` | InitContainer `wait-for-secret` espera al Secret publicado por `addon-provisioner` (hasta 240s), luego corre `alembic upgrade head` | +| `Job` Alembic | `job-alembic-upgrade.yaml` | `0` | InitContainer `wait-for-secret` espera al Secret publicado por `addon-provisioner` (hasta 360s — 3× RECONCILE_INTERVAL 60s), luego corre `alembic upgrade head` | ### Por qué el `AddonClaim` vive FUERA del chart (ADR-066) @@ -151,7 +151,7 @@ El Secret lo materializa automáticamente la plataforma vía el flujo 3. Publica el Secret `__APP_NAME__-db-creds` en el ns `apps`. 4. El workflow corre `helm upgrade --install`. El InitContainer `wait-for-secret` del Job Alembic (hook `pre-install,pre-upgrade`) espera al - Secret (hasta 240s), Alembic ejecuta `upgrade head`, y el Deployment rola. + Secret (hasta 360s), Alembic ejecuta `upgrade head`, y el Deployment rola. ### Opt-out — apps stateless diff --git a/helm/APP_NAME/templates/job-alembic-upgrade.yaml b/helm/APP_NAME/templates/job-alembic-upgrade.yaml index c6db81f..adc6d09 100644 --- a/helm/APP_NAME/templates/job-alembic-upgrade.yaml +++ b/helm/APP_NAME/templates/job-alembic-upgrade.yaml @@ -8,12 +8,15 @@ # - El AddonClaim ya fue aplicado por el workflow del tenant ANTES del # `helm upgrade --install` (ADR-066, vive FUERA del chart en # manifests/addonclaim.yaml). addon-provisioner es timer-based -# (RECONCILE_INTERVAL 300s, initial_delay 60s) y materializa el Secret +# (RECONCILE_INTERVAL 60s, initial_delay 60s) y materializa el Secret # `{{ .Values.database.secretName }}` de forma asincrona. # - El InitContainer hace busy-wait hasta que el Secret existe — absorbe la -# latencia del reconcile dentro del pod, sin tocar el operator ni -# bajar RECONCILE_INTERVAL global. -# - Loop: 48 iteraciones x 5s = 240s — encaja dentro del helm timeout 7m. +# latencia del reconcile dentro del pod, sin tocar el operator. +# - Loop: 72 iteraciones x 5s = 360s — margen ~3x el peor caso esperado +# (initial_delay 60s + 2x ticks de RECONCILE_INTERVAL 60s = 180s). Cabe +# en helm timeout 7m. Lección 2026-05-28: con RECONCILE_INTERVAL=300s el +# init container moria a 240s antes de que el Secret se publicara +# (delay observado 577s, ticket ADDON-PROVISIONER-DB-SECRET-NOT-PUBLISHED). apiVersion: batch/v1 kind: Job metadata: @@ -54,12 +57,12 @@ spec: # caido por instante) NO mate el loop — el retry lo absorbe. set -u # Espera hasta que addon-provisioner publique el Secret tras - # reconciliar el AddonClaim (hook weight -10). 48 x 5s = 240s. + # reconciliar el AddonClaim (hook weight -10). 72 x 5s = 360s. SECRET="{{ .Values.database.secretName }}" TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt i=1 - while [ "$i" -le 48 ]; do + while [ "$i" -le 72 ]; do # || echo "000": si curl falla (exit 6 DNS, etc.) capturamos # un codigo HTTP "000" para que el retry siga corriendo. HTTP=$(curl -s -o /dev/null -w '%{http_code}' \ @@ -71,11 +74,11 @@ spec: echo "Secret $SECRET encontrado en intento $i" exit 0 fi - echo "[$i/48] Secret $SECRET aun no publicado (HTTP=$HTTP), esperando 5s..." + echo "[$i/72] Secret $SECRET aun no publicado (HTTP=$HTTP), esperando 5s..." sleep 5 i=$((i + 1)) done - echo "ERROR: Secret $SECRET no aparecio tras 240s — addon-provisioner stuck?" + echo "ERROR: Secret $SECRET no aparecio tras 360s — addon-provisioner stuck?" exit 1 env: - name: NAMESPACE diff --git a/manifests/addonclaim.yaml b/manifests/addonclaim.yaml index d1fd8df..60226a7 100644 --- a/manifests/addonclaim.yaml +++ b/manifests/addonclaim.yaml @@ -6,7 +6,7 @@ # repetido no lo toca. Idempotente. # # Lifecycle gobernado por addon-provisioner (CRD idp.coralware.cloud/v1alpha1): -# - reconcilia cada RECONCILE_INTERVAL (default 300s) por TenantProfile. +# - reconcilia cada RECONCILE_INTERVAL (default 60s) por TenantProfile. # - crea BD logica + user + GRANT via Job DDL efimero en cluster tenant. # - publica Secret `${RELEASE_NAME}-db-creds` en ns `apps`. # - agrega finalizer `addon-provisioner.idp.coralware.cloud/cleanup-logical`.