Lab 02: Configuración externalizada y PostgreSQL propio
Día: martes · Branch de referencia: lab02-start → lab02-solution
Objetivo
Eliminar la connection string hardcodeada de TaskFlow, externalizarla a
ConfigMap (datos no sensibles) + Secret (credenciales), desplegar
PostgreSQL como su propio Deployment/Service (ya no como sidecar), y
verificar que la API es realmente stateless.
Contexto
En el lab01 el pod arrancaba gracias a un sidecar de Postgres: un parche
para que Host=localhost (hardcodeado) siguiera siendo válido. Hoy se
resuelve de raíz: Postgres pasa a ser un componente independiente,
alcanzable por su nombre de Service (DNS interno de OpenShift), y la app
deja de tener ningún valor de configuración hardcodeado.
Este lab aplica dos factores de Twelve-Factor App: III. Config (la configuración vive en el entorno, nunca en el código ni en la imagen) y VI. Processes (el proceso corre stateless; cualquier estado persistente vive en un backing service, acá Postgres).
Pasos
|
Antes de empezar: confirma que ya hiciste |
-
Refactorizar
Program.cs. Buscar el bloque marcado// TODO (lab02)enapp/TaskFlow.Api/Program.csy reemplazarHardcodedConnectionStringpor una connection string construida desde configuración:var dbHost = builder.Configuration["Db:Host"] ?? "localhost"; var dbPort = builder.Configuration["Db:Port"] ?? "5432"; var dbName = builder.Configuration["Db:Name"] ?? "taskflow"; var dbUser = builder.Configuration["Db:Username"] ?? "taskflow"; var dbPassword = builder.Configuration["Db:Password"] ?? ""; var connectionString = new Npgsql.NpgsqlConnectionStringBuilder { Host = dbHost, Port = int.Parse(dbPort), Database = dbName, Username = dbUser, Password = dbPassword }.ConnectionString;Usar
connectionStringenAddDbContexty enAddNpgSql(…)en vez de la constante. QuitarConnectionStrings:Defaultdeappsettings.json: ya no debe quedar ningún valor de conexión en el repo. -
Reconstruir y publicar la imagen con el
Program.csnuevo, con un tag distinto delab01. UnDeploymentque ya corrió contaskflow-api:lab01no vuelve a bajar la imagen solo porque elImageStreamtenga un dígest nuevo bajo ese mismo tag (elimagePullPolicypor defecto de un tag que no eslatestesIfNotPresent).REGISTRY=default-route-openshift-image-registry.apps.workshop.bg.daytwodemo.com NS=$(oc project -q) # tu namespace actual (<tu-usuario>) podman build -t $REGISTRY/$NS/taskflow-api:lab02 -f app/Dockerfile app podman push $REGISTRY/$NS/taskflow-api:lab02 -
Crear el Secret con las credenciales. No lo subas al repo: genéralo directo contra el clúster:
oc create secret generic taskflow-db-credentials \ --from-literal=username=taskflow \ --from-literal=password="$(openssl rand -base64 24)" -
Completar
manifests/configmap.yaml: host (nombre delServicede Postgres,taskflow-db), puerto, nombre de base, y la configuración de OpenTelemetry (Otel__Exporter, hoyconsole). -
Completar
manifests/postgres-deployment.yamlypostgres-service.yaml: Deployment de PostgreSQL usandoregistry.redhat.io/rhel9/postgresql-16:latest, leyendo usuario/password del Secret del paso anterior. -
Completar
manifests/deployment.yaml(reemplaza al del lab01): la imagen publicada arriba (taglab02, nolab01), sin sidecar, conenvFrom/envapuntando alConfigMapy alSecret. -
Aplicar todo y validar:
oc apply -f labs/lab02-config/manifests/ oc rollout status deployment/taskflow-api -
Verificar que la API es stateless. Crear una tarea vía
POST /api/tasks, borrar el pod de la API (oc delete pod -l app=taskflow-api), esperar a que el Deployment lo recree, y confirmar conGET /api/tasksque la tarea sigue ahí: el estado vive en Postgres, no en el pod de la API.
Criterios de "hecho"
-
appsettings.jsonno tiene ningúnConnectionStringsni password. -
taskflow-db-credentialsexiste como Secret, nunca como archivo en el repo. -
El pod de
taskflow-apiya no tiene contenedor sidecar de Postgres. -
Borrar el pod de la API y dejar que se recree no pierde datos.
-
/readyzdevuelve200(el chequeo de conexión a la base pasa).
Pistas
-
Si el pod de
taskflow-apicrashea conFailed to connect to 127.0.0.1:5432(Connection refused), la imagen desplegada sigue siendo la del lab01: repetir el paso de publicar con el taglab02y confirmar quemanifests/deployment.yamlapunta a ese tag. -
Si
/readyzfalla conConnection refusedpero el error menciona el nombretaskflow-db(no127.0.0.1), confirmar que el nombre delServicede Postgres en elConfigMapcoincide exactamente conmetadata.namedepostgres-service.yaml. -
La convención de doble guion bajo (
Db__Host) es la forma en que el proveedor de variables de entorno de .NET mapea a secciones anidadas de configuración (Db:Host), no es un capricho de este lab.