chart wait-for-secret 240s → 360s + helm timeout 7m → 10m
Some checks failed
__APP_NAME__ — build & deploy / Calidad + build + push (push) Failing after 1m47s
__APP_NAME__ — build & deploy / Helm upgrade --install (push) Has been skipped

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 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 21:19:37 -05:00
parent 5ccfdff8bf
commit 3042c96c6b
4 changed files with 23 additions and 16 deletions

View File

@@ -188,11 +188,15 @@ jobs:
--set tenantId=${TENANT_ID} \ --set tenantId=${TENANT_ID} \
--set tenantIdNodashes=${TENANT_ID_NODASHES} \ --set tenantIdNodashes=${TENANT_ID_NODASHES} \
--set tier=${TENANT_TIER} \ --set tier=${TENANT_TIER} \
--wait --timeout 7m --wait --timeout 10m
# 7m absorbe el peor caso del reconcile de addon-provisioner # 10m absorbe el peor caso del reconcile de addon-provisioner
# (RECONCILE_INTERVAL 300s + initial_delay 60s) + StatefulSet MariaDB # (RECONCILE_INTERVAL 60s + initial_delay 60s + 3 ticks ≈ 240s) +
# ready (~60s) + Job DDL (~10s) + InitContainer wait-for-secret + Alembic. # StatefulSet MariaDB ready (~60s) + Job DDL (~10s) +
# AddonClaim ya fue aplicado en el step previo (ADR-066). # 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 - name: Verificar rollout
run: | run: |

View File

@@ -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. | | `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 `<APP_NAME>-db-creds` (lo consume el InitContainer `wait-for-secret` del Job Alembic) | | `Role` + `RoleBinding` | `role-db-secret-reader.yaml` | `-7` | Permite al SA leer el Secret `<APP_NAME>-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 | | `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) ### 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`. 3. Publica el Secret `__APP_NAME__-db-creds` en el ns `apps`.
4. El workflow corre `helm upgrade --install`. El InitContainer 4. El workflow corre `helm upgrade --install`. El InitContainer
`wait-for-secret` del Job Alembic (hook `pre-install,pre-upgrade`) espera al `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 ### Opt-out — apps stateless

View File

@@ -8,12 +8,15 @@
# - El AddonClaim ya fue aplicado por el workflow del tenant ANTES del # - El AddonClaim ya fue aplicado por el workflow del tenant ANTES del
# `helm upgrade --install` (ADR-066, vive FUERA del chart en # `helm upgrade --install` (ADR-066, vive FUERA del chart en
# manifests/addonclaim.yaml). addon-provisioner es timer-based # 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. # `{{ .Values.database.secretName }}` de forma asincrona.
# - El InitContainer hace busy-wait hasta que el Secret existe — absorbe la # - El InitContainer hace busy-wait hasta que el Secret existe — absorbe la
# latencia del reconcile dentro del pod, sin tocar el operator ni # latencia del reconcile dentro del pod, sin tocar el operator.
# bajar RECONCILE_INTERVAL global. # - Loop: 72 iteraciones x 5s = 360s — margen ~3x el peor caso esperado
# - Loop: 48 iteraciones x 5s = 240s — encaja dentro del helm timeout 7m. # (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 apiVersion: batch/v1
kind: Job kind: Job
metadata: metadata:
@@ -54,12 +57,12 @@ spec:
# caido por instante) NO mate el loop — el retry lo absorbe. # caido por instante) NO mate el loop — el retry lo absorbe.
set -u set -u
# Espera hasta que addon-provisioner publique el Secret tras # 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 }}" SECRET="{{ .Values.database.secretName }}"
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
i=1 i=1
while [ "$i" -le 48 ]; do while [ "$i" -le 72 ]; do
# || echo "000": si curl falla (exit 6 DNS, etc.) capturamos # || echo "000": si curl falla (exit 6 DNS, etc.) capturamos
# un codigo HTTP "000" para que el retry siga corriendo. # un codigo HTTP "000" para que el retry siga corriendo.
HTTP=$(curl -s -o /dev/null -w '%{http_code}' \ HTTP=$(curl -s -o /dev/null -w '%{http_code}' \
@@ -71,11 +74,11 @@ spec:
echo "Secret $SECRET encontrado en intento $i" echo "Secret $SECRET encontrado en intento $i"
exit 0 exit 0
fi 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 sleep 5
i=$((i + 1)) i=$((i + 1))
done 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 exit 1
env: env:
- name: NAMESPACE - name: NAMESPACE

View File

@@ -6,7 +6,7 @@
# repetido no lo toca. Idempotente. # repetido no lo toca. Idempotente.
# #
# Lifecycle gobernado por addon-provisioner (CRD idp.coralware.cloud/v1alpha1): # 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. # - crea BD logica + user + GRANT via Job DDL efimero en cluster tenant.
# - publica Secret `${RELEASE_NAME}-db-creds` en ns `apps`. # - publica Secret `${RELEASE_NAME}-db-creds` en ns `apps`.
# - agrega finalizer `addon-provisioner.idp.coralware.cloud/cleanup-logical`. # - agrega finalizer `addon-provisioner.idp.coralware.cloud/cleanup-logical`.