Implementar PostgreSQL en Kubernetes: guía paso a paso
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.
Preparar el entorno de Kubernetes Copiar enlace
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.

- kubectl: la herramienta de línea de comandos para interactuar con el clúster. Necesita un archivo YAML de configuración con los detalles del clúster, que generalmente proporciona tu proveedor.
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.
Desplegar PostgreSQL con un chart de Helm Copiar enlace
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.
Paso 1: Agregar el repositorio Helm Copiar enlace
helm repo add bitnami https://charts.bitnami.com/bitnamiPara sincronizar su repositorio Helm local con el remoto:
helm repo updatePaso 2: Gestionar la persistencia de datos Copiar enlace
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.yamlPaso 3: Instalar PostgreSQL con Helm Copiar enlace
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
Paso 4: Probar la conexión Copiar enlace
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.
Implementar PostgreSQL en Kubernetes desde cero Copiar enlace
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.yamlCrea 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-pvcCrea el Secret con las credenciales:
kubectl create secret generic postgresql-secret --from-literal=POSTGRES_PASSWORD=Ze4hahshez6dop9vaingkubectl apply -f postgres-statefulset.yamlSi 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-0Crea 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
Escalado, replicación y copias de seguridad Copiar enlace
Escalar un StatefulSet:
kubectl scale statefulset postgres-statefulset --replicas=3 
- Puedes acceder a pods individuales, por ejemplo: postgres-statefulset-1.postgresql-headless-svc.
- Para copias de seguridad, crea un CronJob que ejecute pg_dump. También puedes usar VolumeSnapshots si el proveedor lo permite.
Buenas prácticas Copiar enlace
- Requests y Limits: define límites de CPU y memoria adecuados.
- Backups regulares: usa CronJobs y snapshots.
- Monitoreo y logs: Prometheus + Grafana para métricas (rendimiento, uso de disco, replicación).
- Pod Disruption Budgets (PDB): evita que múltiples pods se reinicien al mismo tiempo.
Conclusión Copiar enlace
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.