Namespace: spring-microservices
Internet ──> gateway-service (LoadBalancer :80 → :5000)
├──> auth-service (:5001) ──┐
└──> user-service (:5002) ──┼──> postgres-service (:5432)
│ ├─ auth_db
│ └─ user_db
- gateway-service: único punto de entrada expuesto (Spring Cloud Gateway). Enruta
/api/auth/**→ auth-service y/api/users/**→ user-service. No toca la base de datos (bloqueado explícitamente por NetworkPolicy). - auth-service: login/registro, emite y firma JWT. Habla con user-service vía HTTP interno (header
X-Internal-Api-Key) para consultar/crear usuarios. - user-service: dueño de los datos de usuario, valida JWT, expone endpoints internos protegidos por
X-Internal-Api-Key, siembra un usuario super-admin al arrancar. - postgres: una sola instancia (
Recreate+ PVCReadWriteOnce), con dos bases:auth_db(default) yuser_db(creada por un init script).
.
├── kustomization.yaml
├── .env # Secret compartido: app-secrets
├── user-service/
│ └── .env # Secret exclusivo de user-service: user-service-env
└── k8s/
├── 00-namespace.yaml
├── 01-configmap.yaml # ConfigMap: app-config (no sensible)
├── 02-postgres-deployment.yaml
├── 03-auth-deployment.yaml
├── 04-user-deployment.yaml
├── 05-gateway-deployment.yaml
└── 06-networkpolicy.yaml
auth_service/.env y gateway_service/.env ya no existen — se eliminaron junto con sus secretGenerator/secretRef, porque ninguno de esos dos servicios necesitaba variables propias que no pudieran vivir en app-config o app-secrets.
| Origen | Tipo | Contenido | Quién lo consume |
|---|---|---|---|
k8s/01-configmap.yaml → ConfigMap app-config |
No sensible | AUTH_MICROSERVICE, USER_MICROSERVICE, JWT_ISSUER |
auth-service, user-service, gateway-service |
.env (raíz) → Secret app-secrets |
Sensible | DB_USERNAME, DB_PASSWORD, INTERNAL_API_KEY, JWT_SECRET |
postgres, auth-service, user-service, gateway-service |
user-service/.env → Secret user-service-env |
Sensible, exclusivo | SUPER_ADMIN_EMAIL, SUPER_ADMIN_PASSWORD, SUPER_ADMIN_USERNAME |
solo user-service |
Directo en cada Deployment (env:) |
Fijo, no secreto | SERVER_PORT, DB_URL |
cada servicio, por separado |
Regla de diseño aplicada: lo que no es secreto va en ConfigMap; lo que es secreto y compartido va en app-secrets; lo que es secreto y exclusivo de un servicio va en su propio Secret. Nada queda duplicado entre ConfigMap y Secret.
#db auth
DB_PASSWORD=12345678
DB_USERNAME=postgres
#header endpoint config
INTERNAL_API_KEY=S0RGSkZHS0dHSkZER0tETUtEw5FPUFNSR0pFV0dQRUlKRVBJRkpQRklKUzM0OTU4MzQwOTU4QUtTRkpTRExLTkFTTEtGTkpBS0ZKQUzDkVNLU0RGSkFT
JWT_SECRET=R0VSMzQwUlVXUTA4OVJVUU1XRElPUVdKUkpFV09QUklFV0RCR0RCR0hKR0hKR0hOR0hOR0dGR1NHVkRSRVNIRkRLTlZTRE5GRFNLRk5EU0ZERktEU0FGS1NESkZTQURMS0pGU0RLRkRTS0xGSlNETEtGU0pGTEtTREFKRkxLDB_USERNAME/DB_PASSWORD: credenciales de Postgres. Los usa el propio Postgres (POSTGRES_USER/POSTGRES_PASSWORD) y también auth-service/user-service para conectarse (spring.datasource.username/password).INTERNAL_API_KEY: debe ser exactamente igual en auth-service y user-service — auth-service la manda en el headerX-Internal-Api-Keyal llamar endpoints internos de user-service, que la compara byte a byte. Como ambos la leen del mismo Secret, siempre coinciden.JWT_SECRET: debe ser exactamente igual en auth-service (firma tokens) y user-service (los valida). Misma razón: al venir del mismo Secret, no hay riesgo de desincronización.
SUPER_ADMIN_EMAIL=correo88@sadmin.com
SUPER_ADMIN_PASSWORD=mipass2423-
SUPER_ADMIN_USERNAME=super.adminSolo lo lee user-service (siembra una cuenta admin al arrancar). No tiene sentido exponerlo a auth-service ni gateway-service, por eso vive separado.
Ya está resuelto en el propio código YAML, no lo dupliques en un .env:
JWT_ISSUER,AUTH_MICROSERVICE,USER_MICROSERVICE→ van enk8s/01-configmap.yaml, no en ningún Secret.SERVER_PORT,DB_URL→ hardcodeados en cada Deployment (03-,04-,05-).
-
.env(raíz) existe, conDB_USERNAME,DB_PASSWORD,INTERNAL_API_KEY,JWT_SECRET. -
user-service/.envexiste, con los 3SUPER_ADMIN_*. - Ninguno de los dos está en git (agrégalos a
.gitignore). -
k8s/01-configmap.yamltiene elJWT_ISSUERque realmente quieres usar (ej.auth-token-microservice-issuer).
kubectl apply -k .Verificar:
kubectl get all -n spring-microservices
kubectl get pods -n spring-microservices -w
kubectl get secrets -n spring-microservicesLos pods de auth-service y user-service pueden tardar 15–30s en pasar a 1/1 Running mientras Spring Boot termina de levantar el contexto y conectarse a Postgres — el startupProbe les da hasta ~2.5 minutos de margen antes de reiniciarlos, así que un 0/1 Running de los primeros segundos es normal, no un error.
Obtener acceso al gateway:
kubectl get svc gateway-service -n spring-microservices
kubectl port-forward svc/gateway-service -n spring-microservices 8080:80
minikube service gateway-service -n spring-microservices| Qué cambió | Comando |
|---|---|
| Un YAML (deployment, probes, recursos) | kubectl apply -k . |
El .env raíz o user-service/.env |
kubectl apply -k . (Kustomize regenera el Secret con hash nuevo y dispara rollout automático de quien lo use) |
| Versión de una imagen | editar image: + kubectl apply -k ., o kubectl set image deployment/auth-service auth-service=loza64/auth-service:1.0.3 -n spring-microservices |
| Seguir un rollout | kubectl rollout status deployment/auth-service -n spring-microservices |
| Revertir un rollout | kubectl rollout undo deployment/auth-service -n spring-microservices |
| Forzar reinicio sin cambiar nada | kubectl rollout restart deployment/auth-service -n spring-microservices |
| Escalar réplicas (no en Postgres) | kubectl scale deployment/user-service -n spring-microservices --replicas=3 |
kubectl delete -k .
kubectl delete deployment auth-service -n spring-microservices
kubectl delete namespace spring-microservicesPersistentVolume subyacente tenga reclaimPolicy: Retain.
- Crea
k8s/07-<nombre>-deployment.yaml(Deployment + Service), siguiendo el patrón de03-auth-deployment.yaml:envFromconconfigMapRef: app-configysecretRef: app-secretscomo mínimo. - Regístralo en
kustomization.yaml, dentro deresources. - Si necesita secretos propios (como hicimos con
user-service): agrega un<nombre>/.env, una entrada ensecretGenerator, y unsecretRefextra en su Deployment. - Si necesita hablar con Postgres, agrégalo al
podSelectordepostgres-allow-only-servicesen06-networkpolicy.yaml. kubectl apply -k .
Para quitarlo: elimina su entrada de resources/secretGenerator y borra el recurso aparte con kubectl delete -f k8s/07-<nombre>-deployment.yaml -n spring-microservices (Kustomize no lo borra solo).
kubectl apply -f k8s/00-namespace.yaml
kubectl create secret generic app-secrets \
-n spring-microservices --from-env-file=.env
kubectl create secret generic user-service-env \
-n spring-microservices --from-env-file=user-service/.env
kubectl apply -f k8s/(Los nombres 00-, 01-... ya garantizan que se apliquen en ese orden si usas el directorio completo.)
kubectl apply -f k8s/03-auth-deployment.yaml
kubectl create secret generic app-secrets \
-n spring-microservices --from-env-file=.env \
--dry-run=client -o yaml | kubectl apply -f -
kubectl rollout restart deployment/auth-service -n spring-microservices
kubectl rollout restart deployment/user-service -n spring-microservices
kubectl rollout restart deployment/gateway-service -n spring-microserviceskubectl delete -f k8s/
kubectl delete secret app-secrets user-service-env -n spring-microserviceskubectl create secret generic <nombre>-env \
-n spring-microservices --from-env-file=<nombre>/.env
kubectl apply -f k8s/07-<nombre>-deployment.yamlkubectl exec -it deploy/user-service -n spring-microservices -- printenv | grep DB_URL
kubectl exec -it deploy/user-service -n spring-microservices -- printenv | Select-String DB_URL
kubectl exec -it deploy/user-service -n spring-microservices -- printenv | findstr DB_URL
kubectl logs deploy/auth-service -n spring-microservices
kubectl describe pod -n spring-microservices -l app=auth-service
kubectl get secrets -n spring-microservicesnamespace: spring-microservices
resources:
- k8s/00-namespace.yaml
- k8s/01-configmap.yaml
- k8s/02-postgres-deployment.yaml
- k8s/03-auth-deployment.yaml
- k8s/04-user-deployment.yaml
- k8s/05-gateway-deployment.yaml
- k8s/06-networkpolicy.yaml
secretGenerator:
- name: app-secrets
envs:
- .env
- name: user-service-env
envs:
- user-service/.envapiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: spring-microservices
data:
AUTH_MICROSERVICE: "http://auth-service:5001"
USER_MICROSERVICE: "http://user-service:5002"
JWT_ISSUER: "auth-token-microservice-issuer" envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
- secretRef:
name: user-service-env envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets