Let's think about it this way for a moment
A real-world app runs as separate layers — frontend (static UI, nginx), backend (API server), and database (persistent data). Each layer gets its own Deployment + Service, and the layers talk to each other through Service names (DNS) — the frontend calls backend-service, and the backend calls db-service. The database layer needs a PVC attached (to persist data), and config/passwords should be split out into ConfigMaps/Secrets.
Let's connect this to a real scenario
Create a dedicated namespace (`three-tier-app`) and deploy things one step at a time: database (with a PVC attached) → backend (wired to the database service via an env variable) → frontend (wired to the backend service as its API URL) — only move to the next layer once the current one is Ready. Expose the frontend through a NodePort Service (or an Ingress) so you can reach it from a browser.
Let's look at it together
kubectl create namespace three-tier-app
# 1. Database (with PVC + Secret)
kubectl apply -f db-secret.yaml -n three-tier-app
kubectl apply -f db-pvc.yaml -n three-tier-app
kubectl apply -f db-deployment.yaml -n three-tier-app
kubectl apply -f db-service.yaml -n three-tier-app
# 2. Backend (connects to db-service)
kubectl apply -f backend-configmap.yaml -n three-tier-app
kubectl apply -f backend-deployment.yaml -n three-tier-app
kubectl apply -f backend-service.yaml -n three-tier-app
# 3. Frontend (connects to backend-service)
kubectl apply -f frontend-deployment.yaml -n three-tier-app
kubectl apply -f frontend-service.yaml -n three-tier-app
# Verify all three layers
kubectl get pods -n three-tier-appNAME READY STATUS AGE
db-7c9b8-x1a2b 1/1 Running 2m
backend-6f5d9-c3d4e 1/1 Running 1m
frontend-8a1e2-f5g6h 1/1 Running 30s5-minute try-it
Write the YAML for a full three-tier app (frontend/backend/db) yourself and deploy it — verify all the way through to confirming the frontend can reach the backend (check `kubectl logs` for connection errors).
A quick word of caution
Instead of letting the backend throw an error and crash-loop when it can't connect to the database yet, you should add retry-with-backoff logic — the database layer can take a little while to become Ready.