PostgreSQL es un sistema de gestión de bases de datos relacional (RDBMS) muy popular que ofrece funciones de alta disponibilidad como replicación en streaming, replicación lógica y soluciones de failover. Implementar PostgreSQL en Kubernetes permite construir sistemas resilientes con mínimo tiempo de inactividad y alta disponibilidad de datos.
Con los StatefulSets de Kubernetes, puedes escalar el despliegue de PostgreSQL según la demanda.
Choose hour server now!
Asegúrate de tener lo siguiente:
Cluster de Kubernetes (en la nube o local): puedes crear uno rápidamente en Hostman. Para usar un entorno local, instala herramientas como k3s, minikube, microk8s o kind.

Descárgalo desde el panel de control de Hostman y luego establece la variable de entorno:

Para conectarse, debe configurar la variable de entorno KUBECONFIG según corresponda.
export KUBECONFIG=/absolute/path/to/file/k8s-cluster-config.yaml
Helm: la CLI de Helm es necesaria para instalar charts. Se requiere Helm versión 3.
Helm es el gestor de paquetes de Kubernetes, similar a apt en Ubuntu/Debian. En lugar de crear múltiples archivos YAML (Pods, Services, Volúmenes, Secrets, etc.), puedes hacerlo todo con un solo comando.
helm repo add bitnami https://charts.bitnami.com/bitnami
Para sincronizar su repositorio Helm local con el remoto:
helm repo update
PostgreSQL necesita almacenamiento persistente para que los datos se mantengan incluso si un pod falla o se reprograma.
Crea el archivo postgres-local-pv.yaml:
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgresql-local-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /mnt/data/postgresql
⚠️ Advertencia: hostPath apunta a una ruta local en un nodo específico, lo cual no es recomendable en producción. Para entornos productivos, usa almacenamiento nativo en la nube (Ceph, Portworx, OpenEBS, GlusterFS) para mayor fiabilidad y escalabilidad.
Crea la PVC (PersistentVolumeClaim) — archivo postgres-local-pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgresql-local-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: manual
El modo ReadWriteOnce significa que solo un nodo puede montar el volumen en modo lectura/escritura al mismo tiempo. Usar ReadWriteMany no aumenta la alta disponibilidad en PostgreSQL y puede causar corrupción o inconsistencia de datos.
Aplica los manifiestos:
kubectl apply -f postgres-local-pv.yaml
kubectl apply -f postgres-local-pvc.yaml
helm install tutorial-db bitnami/postgresql --set auth.username=bhuwan \
--set auth.password=”AeSeigh2gieshe” \
--set auth.database=k8s-tutorial \
--set auth.postgresPassword=”Ze4hahshez6dop9vaing” \
--set primary.persistence.existingClaim=postgresql-local-pvc \
--set volumePermissions.enabled=true
Verifica el despliegue:
kubectl get all

export POSTGRES_PASSWORD=$(kubectl get secret --namespace default tutorial-db-postgresql -o jsonpath="{.data.password}" | base64 -d)
kubectl run tutorial-db-postgresql-client --rm --tty -i --restart='Never' \
--image docker.io/bitnami/postgresql:17.2.0-debian-12-r6 \
--env="PGPASSWORD=$POSTGRES_PASSWORD" \
--command -- psql --host tutorial-db-postgresql \
-U bhuwan -d k8s-tutorial -p 5432
El pod se eliminará automáticamente al finalizar la sesión gracias al parámetro --rm. Si cambiaste el nombre del release, el usuario o la base de datos, ajusta los comandos.
Un StatefulSet es el tipo de recurso ideal para aplicaciones con estado, como PostgreSQL, ya que asigna identidades de red y volúmenes persistentes a cada pod.
Limpia y recrea las configuraciones:
helm delete tutorial-db
kubectl delete pvc postgresql-local-pvc
kubectl delete pv postgresql-local-pv
kubectl apply -f postgres-local-pv.yaml -f postgres-local-pvc.yaml
Crea el archivo postgres-statefulset.yaml:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres-statefulset
labels:
app: postgres
spec:
serviceName: "postgresql-headless-svc"
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:17.2
envFrom:
- secretRef:
name: postgresql-secret
ports:
- containerPort: 5432
name: postgresdb
volumeMounts:
- name: pv-data
mountPath: /var/lib/postgresql/db
volumes:
- name: pv-data
persistentVolumeClaim:
claimName: postgresql-local-pvc
Crea el Secret con las credenciales:
kubectl create secret generic postgresql-secret --from-literal=POSTGRES_PASSWORD=Ze4hahshez6dop9vaing
kubectl apply -f postgres-statefulset.yaml
Si el pod queda en estado Pending, crea una StorageClass:
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: manual
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
Verifica los detalles:
kubectl describe pod postgres-statefulset-0
Crea un Headless Service para el acceso interno — archivo postgres-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: postgresql-headless-svc
spec:
type: ClusterIP
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432
clusterIP: None
Conéctate para probar:
kubectl run tutorial-db-postgresql-client --rm --tty -i --restart='Never' \
--image docker.io/bitnami/postgresql:17.2.0-debian-12-r6 \
--env="PGPASSWORD=Ze4hahshez6dop9vaing" \
--command -- psql --host postgres-statefulset-0.postgresql-headless-svc \
-U postgres -p 5432
Escalar un StatefulSet:
kubectl scale statefulset postgres-statefulset --replicas=3

Choose your server now!
El chart Helm es la forma recomendada para implementaciones complejas o en producción. Helm automatiza la gestión de versiones y simplifica la configuración de recursos. Con helm template, puedes generar los YAML localmente y personalizarlos antes del despliegue.
Kubernetes ofrece escalabilidad, flexibilidad y automatización para PostgreSQL. Con StatefulSets, PVCs, PDBs y gestión de Secrets, puedes tener una base de datos lista para producción, segura y resiliente.