6.9 KiB
Database Namespace — Setup & On-Premise Replication Guide
Covers PostgreSQL 16 and MongoDB 7 deployed in the database Kubernetes namespace.
Verified working on: minikube (local dev). On-premise steps are in Section 4.
1. What's Deployed
| Resource | Namespace | Details |
|---|---|---|
StatefulSet postgres |
database |
postgres:16, 1 replica, 5 Gi PVC |
StatefulSet mongodb |
database |
mongo:7, 1 replica, 5 Gi PVC, no auth |
Service postgres |
database |
ClusterIP, port 5432 |
Service mongodb |
database |
ClusterIP, port 27017 |
Secret postgres-secret |
database |
DB name, user, password, DATABASE_URL |
PVC postgres-pvc |
database |
5 Gi, ReadWriteOnce |
PVC mongodb-pvc |
database |
5 Gi, ReadWriteOnce |
ConfigMap tcp-services |
ingress-nginx |
TCP passthrough for external PostgreSQL access |
2. Connection Strings
| Consumer | URL |
|---|---|
| Backend pod (in-cluster) | postgresql://vaishnavi:admin@postgres.database.svc.cluster.local:5432/vaishnavi_db?schema=public |
| Backend pod (in-cluster) | mongodb://mongodb.database.svc.cluster.local:27017/vaishnavi_products |
| External / pgAdmin (host) | postgresql://vaishnavi:admin@postgres.local:5432/vaishnavi_db |
3. File Structure
k8s/database/
├── 00-namespace.yaml # database namespace
├── postgres-secret.yaml # base64-encoded credentials + DATABASE_URL
├── postgres-pvc.yaml # 5 Gi PVC
├── postgres-statefulset.yaml # postgres:16 StatefulSet
├── postgres-service.yaml # ClusterIP :5432
├── mongodb-pvc.yaml # 5 Gi PVC
├── mongodb-statefulset.yaml # mongo:7 StatefulSet, no auth
├── mongodb-service.yaml # ClusterIP :27017
└── nginx-tcp-configmap.yaml # TCP passthrough for postgres.local:5432
4. On-Premise Replication
4.1 Prerequisites
- Kubernetes cluster (kubeadm, k3s, RKE2, or similar) with at least 1 worker node
kubectlconfigured with cluster-admin rights- A StorageClass that supports
ReadWriteOncePVCs Common options:local-path(Rancher Local Path Provisioner — simplest for single-node)longhorn(multi-node HA storage)- NFS provisioner
- Ingress-NGINX controller deployed (
kubectl get pods -n ingress-nginx)
4.2 StorageClass: Install Local Path Provisioner (if needed)
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
# Set as default if no other default exists
kubectl patch storageclass local-path \
-p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
4.3 Deploy the Databases
cd vaishnavi-ecommerce-backend/k8s/database
kubectl apply -f 00-namespace.yaml
kubectl apply -f postgres-secret.yaml
kubectl apply -f postgres-pvc.yaml
kubectl apply -f postgres-statefulset.yaml
kubectl apply -f postgres-service.yaml
kubectl apply -f mongodb-pvc.yaml
kubectl apply -f mongodb-statefulset.yaml
kubectl apply -f mongodb-service.yaml
Wait for both pods to reach Running:
kubectl get pods -n database -w
# Expected:
# mongodb-0 1/1 Running 0
# postgres-0 1/1 Running 0
4.4 External PostgreSQL Access via TCP Ingress (optional)
This lets you connect to PostgreSQL from outside the cluster using postgres.local:5432.
Step 1 — Apply the TCP ConfigMap:
kubectl apply -f nginx-tcp-configmap.yaml
Step 2 — Expose port 5432 on the ingress-nginx Service:
kubectl patch svc ingress-nginx-controller -n ingress-nginx \
--type='json' \
-p='[{"op":"add","path":"/spec/ports/-","value":{"name":"postgres","port":5432,"targetPort":5432,"protocol":"TCP"}}]'
Step 3 — Add --tcp-services-configmap arg to the ingress-nginx Deployment:
kubectl patch deployment ingress-nginx-controller -n ingress-nginx \
--type='json' \
-p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--tcp-services-configmap=ingress-nginx/tcp-services"}]'
Step 4 — Add to /etc/hosts on every machine that needs external access:
<NODE_IP> postgres.local
Replace <NODE_IP> with the IP of any cluster node (or load balancer IP if using MetalLB).
4.5 Credentials / Secret Values
The secret values are baked into postgres-secret.yaml. To change them:
# Generate new base64 values
echo -n "your_password" | base64
# Or use kubectl to create the secret directly (bypasses base64 manual encoding)
kubectl create secret generic postgres-secret \
--namespace=database \
--from-literal=POSTGRES_DB=vaishnavi_db \
--from-literal=POSTGRES_USER=vaishnavi \
--from-literal=POSTGRES_PASSWORD=admin \
--from-literal=DATABASE_URL="postgresql://vaishnavi:admin@postgres.database.svc.cluster.local:5432/vaishnavi_db?schema=public" \
--dry-run=client -o yaml > postgres-secret.yaml
4.6 Backend ConfigMap / Secret Reference
The backend reads DATABASE_URL and MONGODB_URI from its own configmap/secret in the ecommerce namespace. Ensure these point to the database namespace services:
DATABASE_URL: postgresql://vaishnavi:admin@postgres.database.svc.cluster.local:5432/vaishnavi_db?schema=public
MONGODB_URI: mongodb://mongodb.database.svc.cluster.local:27017/vaishnavi_products
5. Verification
# Both pods Running
kubectl get pods -n database
# PVCs Bound
kubectl get pvc -n database
# Services present
kubectl get svc -n database
# PostgreSQL accepting connections
kubectl exec -n database postgres-0 -- pg_isready -U vaishnavi -d vaishnavi_db
# PostgreSQL — list databases
kubectl exec -n database postgres-0 -- psql -U vaishnavi -d vaishnavi_db -c '\l'
# MongoDB ping
kubectl exec -n database mongodb-0 -- mongosh --eval "db.adminCommand('ping')" --quiet
# In-cluster connectivity test (PostgreSQL)
kubectl run psql-test --rm -it --image=postgres:16 --restart=Never -n database -- \
psql postgresql://vaishnavi:admin@postgres.database.svc.cluster.local:5432/vaishnavi_db -c '\l'
# In-cluster connectivity test (MongoDB)
kubectl run mongo-test --rm -it --image=mongo:7 --restart=Never -n database -- \
mongosh mongodb://mongodb.database.svc.cluster.local:27017/vaishnavi_products --eval "db.stats()"
# External PostgreSQL (after TCP ingress setup + /etc/hosts)
psql postgresql://vaishnavi:admin@postgres.local:5432/vaishnavi_db -c '\l'
6. Teardown
# Remove databases (data is lost when PVCs are deleted)
kubectl delete namespace database
# Remove TCP ingress config (if applied)
kubectl delete configmap tcp-services -n ingress-nginx
To preserve data before teardown, dump first:
# PostgreSQL dump
kubectl exec -n database postgres-0 -- \
pg_dump -U vaishnavi vaishnavi_db > vaishnavi_db_backup.sql
# MongoDB dump
kubectl exec -n database mongodb-0 -- \
mongodump --db vaishnavi_products --archive > vaishnavi_products_backup.archive