Kubernetes: Fundamentals
Master the core building blocks of Kubernetes including Pods, Deployments, Services, and cluster architecture.
Getting Started with Kubernetes
Before diving into commands and configurations, it helps to understand what Kubernetes actually does. Think of it as a distributed operating system: just as your laptop’s OS manages programs, memory, and files on a single machine, Kubernetes manages containers, resources, and storage across many machines.
Why does this matter? When you run kubectl apply -f myapp.yaml, you are not just starting a container. You are telling Kubernetes: “Here is what I want my application to look like. Make it happen and keep it that way.” Kubernetes then handles container placement, networking, restarts, and scaling automatically.
This guide walks you through the fundamentals, building from your first deployment to production-ready configurations.
Quick Start Guide
The fastest way to understand Kubernetes is to use it. This section gets you deploying an application in minutes.
Requirements
- Container technology knowledge (Docker)
- Kubernetes cluster access (minikube, kind, k3s, or cloud provider)
- kubectl CLI v1.28+ installed
- Optional: Helm 3.x for package management
Your First Deployment
Let us deploy a web server and see Kubernetes in action:
# Deploy nginx and expose it
kubectl create deployment hello-world --image=nginx:alpine
kubectl expose deployment hello-world --type=LoadBalancer --port=80
# Verify it is running
kubectl get pods
kubectl get services
Now try the self-healing feature that makes Kubernetes valuable:
# Scale to 3 replicas and delete one pod
kubectl scale deployment hello-world --replicas=3
kubectl delete pod <pod-name>
kubectl get pods # A new pod automatically replaces the deleted one
Clean up when done:
kubectl delete deployment hello-world
kubectl delete service hello-world
Core Concepts at a Glance
Before going deeper, here is how the key pieces fit together:
| Concept | What It Is | Analogy |
|---|---|---|
| Pod | Smallest deployable unit; wraps one or more containers | An apartment unit in a building |
| Deployment | Manages pod replicas and updates | A property manager ensuring units are occupied |
| Service | Stable network address for pods | The building’s front desk that routes visitors |
| Node | A machine (physical or virtual) running pods | An apartment building |
| Cluster | A group of nodes managed together | The entire apartment complex |
The key insight: You rarely work with pods directly. Instead, you tell a Deployment “I want 3 copies of my app” and it creates and manages the pods for you. Services then route traffic to those pods, regardless of which nodes they run on.
The rest of this guide explores each concept in depth, showing you how to build production-ready systems.
Understanding Kubernetes: From Containers to Orchestration
Consider the following evolution in how we run applications:
| Era | Approach | Trade-off |
|---|---|---|
| Bare Metal | One application per server | Wasted resources; most servers idle |
| Virtual Machines | Multiple VMs per server | Better utilization but heavy overhead |
| Containers | Many containers per server | Lightweight but manual management at scale |
| Orchestration | Kubernetes manages containers | Automated, scalable, self-healing |
Each step solved the previous era’s problems while creating new challenges. Containers solved VM overhead but introduced complexity: How do you run hundreds of containers across dozens of servers? How do you ensure they stay healthy? How do you update them without downtime?
Kubernetes answers these questions with a declarative approach and automated operations.
What Kubernetes Provides
Rather than listing features, consider what problems each capability solves:
| Challenge | Kubernetes Solution | Benefit |
|---|---|---|
| “My container crashed” | Self-healing | Automatic restart and replacement |
| “How do services find each other?” | Service discovery | Built-in DNS and load balancing |
| “I need to deploy without downtime” | Rolling updates | Gradual replacement of old pods |
| “Traffic is spiking” | Horizontal scaling | Add replicas automatically or manually |
| “I need to store passwords securely” | Secrets | Encrypted storage with access controls |
| “Different apps need different storage” | Storage classes | Abstract storage provisioning |
Core Concepts
Now that you understand why Kubernetes exists, let us explore how it works. The architecture consists of two main parts: the control plane that makes decisions and the worker nodes that run your applications.
Consider the following: When you run kubectl apply -f deployment.yaml, your request travels through several components. The API Server receives it, stores the desired state in etcd, the Scheduler decides which node should run the pods, and the Controller Manager ensures reality matches your specification. Understanding this flow helps you troubleshoot when things go wrong.
Architecture Overview
Kubernetes follows a master-worker architecture. The control plane manages the cluster while worker nodes run your applications.
Control Plane Components
Node Components
Kubernetes Objects: The Building Blocks
With the architecture understood, let us explore the objects you will work with daily. Each object type solves a specific problem, and choosing the right one depends on your application’s needs.
When to use each object type:
| Object | Use Case | Example |
|---|---|---|
| Pod | Rarely used directly; foundation for other objects | Testing, debugging |
| Deployment | Stateless applications that can scale horizontally | Web servers, APIs |
| StatefulSet | Stateful applications needing stable identity | Databases, message queues |
| DaemonSet | Run one pod per node | Log collectors, monitoring agents |
| Job | Run-to-completion tasks | Database migrations, batch processing |
| CronJob | Scheduled tasks | Nightly backups, report generation |
Let us examine each object type, starting with the foundation.
Pods
The smallest deployable unit in Kubernetes:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
Key Features:
Deployments
Manages replica sets and provides declarative updates:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
Features:
Rolling Updates
Zero-downtime deployments
Rollback
Revert to previous versions
Scaling
Adjust replica count
Self-healing
Automatic pod recovery
Services
Provides stable network endpoint for pods:
Service Types
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: LoadBalancer
Namespaces
Logical isolation within a cluster:
apiVersion: v1
kind: Namespace
metadata:
name: development
Default Namespaces:
default
Default namespace for objects
kube-system
Kubernetes system objects
kube-public
Publicly accessible data
kube-node-lease
Node heartbeat data
Workload Resources: Beyond Basic Deployments
Deployments work well for stateless applications, but real-world systems have varied requirements. Kubernetes provides specialized controllers for different workload patterns.
Consider the following decision tree:
- Need to scale horizontally with identical replicas? Use a Deployment
- Need stable identity and persistent storage per pod? Use a StatefulSet
- Need exactly one pod on every node? Use a DaemonSet
- Need to run a task to completion? Use a Job
- Need to run tasks on a schedule? Use a CronJob
Deployment vs StatefulSet vs DaemonSet
| Characteristic | Deployment | StatefulSet | DaemonSet |
|---|---|---|---|
| Pod identity | Random names | Ordered names (app-0, app-1) | One per node |
| Scaling | Any order | Sequential (0, 1, 2…) | Tied to node count |
| Storage | Shared or none | Dedicated per pod | Usually none |
| Network | Random IPs | Stable DNS per pod | Per-node |
| Use case | Web apps, APIs | Databases, Kafka | Logging, monitoring |
StatefulSets: When Order and Identity Matter
StatefulSets solve the “pets vs cattle” problem. While Deployments treat pods as interchangeable (cattle), StatefulSets give each pod a stable identity (pets). This matters for applications like databases that need to know their role in a cluster.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 3
selector:
matchLabels:
app: postgres
template:
spec:
containers:
- name: postgres
image: postgres:13
volumeClaimTemplates:
- metadata:
name: postgres-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
What StatefulSets guarantee:
- Pods named sequentially: postgres-0, postgres-1, postgres-2
- Each pod gets its own persistent volume
- Pods created in order (0 before 1 before 2) and deleted in reverse
- Stable DNS: postgres-0.postgres.default.svc.cluster.local
DaemonSets: One Pod Per Node
Some workloads need to run everywhere: log collectors that capture output from all containers, monitoring agents that track node health, or network plugins. DaemonSets ensure exactly one pod runs on each node automatically.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
selector:
matchLabels:
app: fluentd
template:
spec:
containers:
- name: fluentd
image: fluentd:v1.14
Common DaemonSet applications:
- Logging: Fluentd, Filebeat collecting container logs
- Monitoring: Node Exporter, Datadog agent
- Networking: Calico, Cilium CNI plugins
- Storage: CSI node plugins
Jobs and CronJobs: Task Automation
Not all workloads run continuously. Jobs handle run-to-completion tasks, while CronJobs run tasks on a schedule.
Job - runs once until successful:
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
spec:
template:
spec:
containers:
- name: migrate
image: myapp:latest
command: ["./migrate.sh"]
restartPolicy: OnFailure
backoffLimit: 3 # Retry up to 3 times
CronJob - runs on a schedule (standard cron syntax):
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-backup
spec:
schedule: "0 2 * * *" # 2 AM daily
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:latest
restartPolicy: OnFailure
Real-world Job use cases: database migrations, data imports, report generation, sending batch emails, cleanup tasks.
Networking: Connecting Your Applications
Kubernetes networking follows a simple principle: every pod gets its own IP address, and all pods can communicate with each other without NAT. This flat network model makes it easy to reason about connectivity.
Consider the following networking layers:
| Layer | Purpose | Kubernetes Object |
|---|---|---|
| Pod-to-Pod | Direct communication | Flat network (automatic) |
| Pod-to-Service | Stable endpoint for pods | Service |
| External-to-Service | Traffic from outside cluster | Ingress, LoadBalancer |
| Service-to-External | Outbound connections | NetworkPolicy (egress) |
Ingress: Your Cluster’s Front Door
While Services handle internal routing, Ingress manages external HTTP/HTTPS traffic. Instead of creating multiple LoadBalancer services (each with its own IP and cost), Ingress provides a single entry point that routes to different services based on hostnames and paths.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
When to use Ingress vs LoadBalancer:
- Use Ingress when you have multiple services that need HTTP/HTTPS routing
- Use LoadBalancer for non-HTTP traffic or single services
- Ingress typically requires an Ingress Controller (nginx, traefik, or cloud-provided)
Network Policies: Microsegmentation for Security
By default, all pods can communicate freely. Network Policies let you restrict this, implementing defense-in-depth by controlling which pods can talk to each other.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow-frontend-only
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080
This policy says: “Only allow traffic to the API pods from frontend pods on port 8080.”
Important: Network Policies require a CNI plugin that supports them (Calico, Cilium, Weave Net). The default kubenet does not enforce policies.