Phase 1 : Local Cluster with KIND + PostgreSQL Setup


Welcome, DevOps Learners!
In this hands-on series, we’re learning by building. No boring theory—just real projects, exactly how they are built in production.
We’ll start simple, deploy PostgreSQL on a local Kubernetes cluster using KIND, and scale our stack with secrets, monitoring, CI/CD, backups, and more as we go.
What You’ll Learn in Phase 1
By the end of this phase, you'll:
🎯 Task | 🔍 What It Covers |
KIND Setup | Lightweight K8s cluster setup locally |
Namespace Creation | Isolating environments like prod/dev |
ConfigMap + Secrets | Secure configuration management |
Persistent Volumes | Durable DB storage with PVCs |
StatefulSet | Reliable DB deployment pattern |
Internal Networking | Access PostgreSQL inside K8s |
Tasks Completed in Phase 1 (with snippets)
Created a Local Kubernetes Cluster with KIND
Instead of using heavy tools like Minikube, we chose KIND (Kubernetes IN Docker)—a production-grade local cluster tool perfect for DevOps prototyping.
Cluster Config Preview:
# kind-config.yaml
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080
hostPort: 8080
Command:
kind create cluster --name pg-devops --config kind-config.yaml
Created a Dedicated Namespace for PostgreSQL
Namespaces simulate real-world multi-env setups (like dev
, staging
, prod
):
kubectl create namespace postgres-dev
Secured PostgreSQL Credentials using Secrets
We base64 encoded our DB credentials to store safely in Kubernetes Secrets.
Code Snippet:
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
type: Opaque
data:
POSTGRES_USER: cG9zdGdyZXM=
POSTGRES_PASSWORD: c2VjdXJlcGFzcw==
Used ConfigMaps for Environment Configuration
We added a database name using a ConfigMap—great for non-sensitive environment variables.
Snippet:
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-config
data:
POSTGRES_DB: devdb
Provisioned Persistent Volumes
We created a PersistentVolumeClaim to retain database data even if the container crashes or restarts.
resources:
requests:
storage: 1Gi
Deployed PostgreSQL using StatefulSet
PostgreSQL isn’t just another app—it's stateful. So we used StatefulSet instead of Deployment, which helps with persistent identity and volume consistency.
Interesting bit:
volumeClaimTemplates:
- metadata:
name: postgres-storage
Created a Headless Service
This enables network identity for StatefulSet pods. We used clusterIP: None
to make sure it works as a stable DNS for the DB instance.
clusterIP: None
Where’s the Full Code?
I’ve structured the full codebase day-by-day for learners. You can explore it in my GitHub repo:
👉 Kubernetes Diaries PostgreSQL – GitHub Repository
🌟 Star the repo if it helps you. Each ⭐ motivates me to build more content for you!
Navigate to branches like day1-setup
, day2-secret-config
for complete code walkthroughs!
What’s Coming in Phase 2?
In the next phase, we will:
Deploy pgAdmin to visualize and manage our DB
Connect to PostgreSQL from inside the cluster
Prepare for cloud migration and backups
Start documenting each phase visually with Grafana
💬 Final Words
This isn’t just a project—it’s a journey to become production-ready. Whether you're a student, DevOps beginner, or aspiring cloud engineer, this project will grow with you.
So don’t just copy—understand, break, fix, and deploy. That's how real DevOps is done.
Subscribe to my newsletter
Read articles from Digpal Singh Rathore directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Digpal Singh Rathore
Digpal Singh Rathore
Cloud Engineer passionate about automation, scalability, and AI. On a journey to become an MLOps Engineer—bridging the gap between machine learning and reliable deployment. Sharing what I learn along the way.