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 SetupLightweight K8s cluster setup locally
Namespace CreationIsolating environments like prod/dev
ConfigMap + SecretsSecure configuration management
Persistent VolumesDurable DB storage with PVCs
StatefulSetReliable DB deployment pattern
Internal NetworkingAccess 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.

1
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.