TL;DR: Kubernetes (K8s) is a container orchestrator that automates deployment, scaling, and management of containerized apps. This guide covers the big picture, architecture, ready-to-use YAMLs, day-to-day commands, and a mini-project to bring up a web service with Ingress in minutes.
What is Kubernetes?|#
Kubernetes is an open-source platform for orchestrating containers (usually Docker) across clusters. It handles:
- Auto scaling (HPA, VPA, Cluster Autoscaler)
- High availability and self-healing (ReplicaSet, probes)
- Predictable deploys (rolling update, canary/blue-green)
- Networking, internal DNS, and load balancing (Services/Ingress)
- Configuration and secrets (ConfigMaps/Secrets)
- Persistent storage (PV/PVC/StorageClass)
Architecture (Quick View)#
Control Plane:
- kube-apiserver: entry point for all cluster interactions.
- etcd: key-value store that persists cluster state.
- scheduler: decides which node should run a Pod.
- controller-manager / cloud-controller-manager: reconciles desired vs. current state; cloud integrations.
Worker Nodes:
- kubelet: node agent; ensures Pods are running.
- kube-proxy: networking rules and Service load balancing.
- Container runtime: e.g.,
containerd.
Core Objects#
- Pod: smallest deployable unit (one or more containers).
- ReplicaSet/Deployment: replicas + update strategy.
- StatefulSet: stable identity/state (databases, queues, etc.).
- DaemonSet: one Pod per node (e.g., log/monitoring agents).
- Job/CronJob: one-off tasks or scheduled jobs.
- Service: exposes a set of Pods (ClusterIP/NodePort/LoadBalancer).
- Ingress: external HTTP/HTTPS routing to Services.
- ConfigMap/Secret: configuration and credentials.
- Namespace/RBAC: logical isolation and permissions.
- PV/PVC/StorageClass: persistent storage and dynamic provisioning.
Hands-on: bring up a web app#
Below is an NGINX app with Deployment, Service, and Ingress.
Local prerequisites:
kubectl+ a cluster (e.g., minikube or kind) and an Ingress Controller (for minikube:minikube addons enable ingress).
##1) Deployment + Service (deploy.yaml)**#
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deploy
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "250m"
memory: "128Mi"
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 15
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP
### **2) Ingress (`ingress.yaml` file)**
> For local clusters, use the Minikube addon or install the NGINX Ingress Controller.
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: web.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
### **3) Applying and Testing**
```bash
kubectl apply -f deploy.yaml
kubectl apply -f ingress.yaml
kubectl get pods -w
kubectl get svc,ingress
Minikube:
minikube addons enable ingress
# Map local host
echo "$(minikube ip) web.local" | sudo tee -a /etc/hosts
# Test
curl -I http://web.local
kind:
- Create the cluster with mapped ports (e.g., 80/443) and install an ingress controller (NGINX). Refer to the ingress-nginx project documentation.
Configuration and Secrets#
ConfigMap + Secret (example)#
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MESSAGE: "Hello from ConfigMap"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
stringData:
DB_PASSWORD: supersecreta
Usage in Pod (Deployment snippet):
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MESSAGE: "Hello from ConfigMap"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
stringData:
DB_PASSWORD: supersecreta
Persistent Storage#
Generic PVC (default StorageClass)#
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-pvc
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
Usage in Pod:
volumes:
- name: data
persistentVolumeClaim:
claimName: data-pvc
containers:
- name: app
volumeMounts:
- name: data
mountPath: /var/lib/data
Tip: In cloud environments, use the provider’s StorageClass (EBS/GCE PD/Azure Disk). Locally, Minikube provides a default class.
Autoscaling#
Horizontal Pod Autoscaler (HPA)#
Requires
metrics-serverinstalled.
kubectl autoscale deployment web-deploy --cpu-percent=70 --min=3 --max=10
kubectl get hpa
VPA (Vertical) and Cluster Autoscaler (nodes) complement HPA.
Deployment Strategies#
RollingUpdate (default): gradual updates with
maxSurge/maxUnavailable.Recreate: shuts down all pods before starting the new version (downtime).
Blue/Green / Canary: gradual routing via Ingress/Service + labels/selectors.
Example: Strategy adjustment in Deployment:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
Observability & Debug (Cheat Sheet)#
# Explore resources
kubectl get nodes
kubectl get ns
kubectl get all -n default
# Describe and inspect
kubectl describe pod <pod>
kubectl logs <pod>
kubectl logs -f <pod> -c <container>
# Pod access
kubectl exec -it <pod> -- sh
kubectl port-forward svc/web-svc 8080:80
# Deploys and rollouts
kubectl rollout status deploy/web-deploy
kubectl rollout history deploy/web-deploy
kubectl rollout undo deploy/web-deploy
# Apply/Validate YAML
kubectl apply -f file.yaml
kubectl diff -f file.yaml
kubectl delete -f file.yaml
Security Best Practices#
- Use minimal RBAC; assign a dedicated
ServiceAccountper app. - Create namespaces per team/product for isolation +
ResourceQuota/LimitRange. - Always define Requests/Limits for each container.
- Use Secrets for credentials; avoid exposing them in
ConfigMap/envs in light. - Apply NetworkPolicies to restrict L3/L4 traffic between Pods.
- Enforce PSA/PSS (Pod Security Standards) for stricter execution policies.
- Use trusted images and scan them (Trivy/Grype) + prefer digest-based pulls.
Production Checklist#
- Ingress with TLS (LetsEncrypt/ACME) + HTTP→HTTPS redirect
- metrics-server + HPA
- Centralized logs (Loki/ELK) and metrics (Prometheus/Grafana)
- Backups for etcd and volumes
- Alerts (Alertmanager) and dashboards
- Policies: NetworkPolicy, RBAC, PSS
- Namespace quotas;
reviewed requests/limits - CI/CD with versioned manifests (Kustomize/Helm/GitOps)
Common Errors and Solutions#
- Pods in CrashLoopBackOff: check
kubectl logsand probes (possibly shortinitialDelaySeconds). - ImagePullBackOff: check image name/tag/registry/credentials (
imagePullSecret). - Service not responding: verify Pod
selectorand labels; check port mappings. - Ingress 404: incorrect rule/host or missing Ingress Controller.
- No metrics in HPA: install/configure
metrics-server.
Next Steps#
- Convert YAMLs into Helm charts or Kustomize.
- Add canary deployments via Ingress + traffic weight.
- Create CI/CD pipelines with linting,
kubectl diff, and automated deployment.
Useful references: Kubernetes official documentation; ingress-nginx, metrics-server, Prometheus, Grafana, Loki, Kustomize, and Helm projects.
Appendix — Creating a Local Cluster Quickly#
minikube:
minikube start --driver=docker
minikube addons enable ingress
kind: (minimal config example kind-config.yaml)
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: ClusterConfiguration
apiServer:
extraArgs:
enable-admission-plugins: NodeRestriction
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
kind create cluster --name k8s-lab --config kind-config.yaml
# install the NGINX Ingress Controller as per the project documentation
Final Note: This post was written for the Hugo Relearn theme. Sections, TOC, and sidebar navigation are automatically generated by the theme. If your Hugo version is outdated, upgrade to ≥ 0.126.3 to avoid compatibility warnings.

