Deploying PostgreSQL on Kubernetes with NodePort: A Complete Guide - Explore

Kubernetes
PostgreSQL
NodePort
Helm
Cloud Native
DevOps
Container Orchestration
Deploying PostgreSQL on Kubernetes with NodePort: A Complete Guide

by: Ashish Sharma

April 18, 2025

titleImage

Introduction

PostgreSQL is one of the most popular open-source relational databases, and deploying it on Kubernetes (K8s) ensures scalability, high availability, and fault tolerance. This guide walks you through deploying PostgreSQL on Kubernetes using a NodePort service, allowing external access to the database.

We will also cover common issues faced during deployment and how to resolve them.




Step 1: Setting Up PostgreSQL on Kubernetes

1.1 Create a Persistent Volume (PV)

A Persistent Volume (PV) ensures PostgreSQL data persists even if the pod restarts.
Save the following YAML as psql-pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-volume
  labels:
    type: local
    app: postgres
spec:
  storageClassName: manual
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: /data/postgresql

💡 Explanation:

  • 20Gi storage is allocated for PostgreSQL.
  • ReadWriteMany (RWX) allows multiple pods to read and write.
  • hostPath ensures data persistence on the node.

Apply the PV:

kubectl apply -f psql-pv.yaml



1.2 Create a Persistent Volume Claim (PVC)

A Persistent Volume Claim (PVC) allows the PostgreSQL pod to request storage.
Save the following as psql-claim.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-volume-claim
  labels:
    app: postgres
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 20Gi

Apply the PVC:

kubectl apply -f psql-claim.yaml

💡 PVC will bind to the Persistent Volume (postgres-volume) automatically.




1.3 Create a ConfigMap for PostgreSQL Environment Variables

The ConfigMap stores database configuration parameters.
Save the following as postgres-configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-secret
  labels:
    app: postgres
data:
  POSTGRES_DB: core_mdm_dev
  POSTGRES_USER: app_user
  POSTGRES_PASSWORD: =MFIck)d]#F;vE98ffmR

Apply the ConfigMap:

kubectl apply -f postgres-configmap.yaml



1.4 Deploy PostgreSQL

Now, create the PostgreSQL Deployment file and save it as ps-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: 'postgres:16'
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 5432
          envFrom:
            - configMapRef:
                name: postgres-secret
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgresdata
      volumes:
        - name: postgresdata
          persistentVolumeClaim:
            claimName: postgres-volume-claim

Apply the deployment:

kubectl apply -f ps-deployment.yaml



1.5 Expose PostgreSQL Using NodePort

A NodePort service allows external access to the PostgreSQL database.
Save the following as ps-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: postgres
  labels:
    app: postgres
spec:
  type: NodePort
  selector:
    app: postgres
  ports:
    - name: postgres
      port: 5432           # The port PostgreSQL uses
      targetPort: 5432      # The port on the container (should be the same as 'port')
      nodePort: 31543       # NodePort that Kubernetes should expose
      protocol: TCP

Apply the service:

kubectl apply -f ps-service.yaml



Step 2: Verify PostgreSQL Deployment

Check if the PostgreSQL pod is running:

kubectl get pods -n postgres

If running successfully, you should see:

NAME                        READY   STATUS    RESTARTS   AGE
postgres-xxxxxxxxxx-xxxxx   1/1     Running   0          10s

Now, connect to PostgreSQL inside the pod:

kubectl exec -it $(kubectl get pods -n postgres -l app=postgres -o jsonpath='{.items[0].metadata.name}') -n postgres -- psql -U app_user -d postgres

List available databases:

\l



Common Issues and How to Fix Them

1.1 PostgreSQL Pod in CrashLoopBackOff or Error State

Cause: Corrupt WAL (Write-Ahead Log)

PANIC: could not locate a valid checkpoint record

Solution: Reset WAL Logs

  1. Start a recovery pod:
kubectl apply -f postgres-recovery.yaml
  1. Connect and reset WAL logs:
kubectl exec -it postgres-recovery -n postgres -- bash
su - postgres
/usr/lib/postgresql/16/bin/pg_resetwal -f /var/lib/postgresql/data
  1. Delete the recovery pod and restart PostgreSQL:
kubectl delete pod postgres-recovery -n postgres
kubectl rollout restart deployment postgres -n postgres



1.2 Cannot Delete a Database (Ghost Database)

Cause: Active connections or system corruption

ERROR:  database "lgn_section_dev" does not exist

Solution:

  1. Terminate active connections:
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'lgn_section_dev';
  1. Manually delete the corrupted database entry:
DELETE FROM pg_database WHERE datname = 'lgn_section_dev';
  1. Remove database files from storage (inside pod):
rm -rf /var/lib/postgresql/data/base/<OID>
  1. Restart PostgreSQL:
kubectl rollout restart deployment postgres -n postgres



1.3 External Connection Failing

Cause: PostgreSQL is not accepting external connections

Check if PostgreSQL is listening on all IPs:

SHOW listen_addresses;

If not, update postgresql.conf:

ALTER SYSTEM SET listen_addresses TO '*';

Restart PostgreSQL:

kubectl rollout restart deployment postgres -n postgres



Conclusion

Deploying PostgreSQL on Kubernetes with NodePort is a powerful way to manage database workloads in a containerized environment. By setting up Persistent Volumes, ConfigMaps, and a NodePort Service, we ensure data persistence and external access.

contact us

Get started now

Get a quote for your project.
logofooter
title_logo

USA

Edstem Technologies LLC
254 Chapman Rd, Ste 208 #14734
Newark, Delaware 19702 US

INDIA

Edstem Technologies Pvt Ltd
Office No-2B-1, Second Floor
Jyothirmaya, Infopark Phase II
Ernakulam, Kerala 682303
iso logo

© 2024 — Edstem All Rights Reserved

Privacy PolicyTerms of Use