Toolmingo
Guides13 min read

What Is Kubernetes? A Complete Beginner's Guide (2025)

Learn what Kubernetes is, how container orchestration works, the difference between Docker and Kubernetes, and key concepts like Pods, Services, and Deployments — with practical examples.

Kubernetes (also written k8s) is an open-source system for automating the deployment, scaling, and management of containerized applications. Originally built by Google and now maintained by the CNCF (Cloud Native Computing Foundation), Kubernetes is the de-facto standard for running containers in production.

If Docker lets you package an application into a container, Kubernetes answers the next question: how do you run hundreds of those containers reliably, keep them healthy, scale them up under load, and roll out updates without downtime?


Kubernetes in 30 seconds

Concept What it means
Pod Smallest deployable unit — one or more containers sharing storage/network
Node A physical or virtual machine that runs Pods
Cluster A set of Nodes managed by Kubernetes
Deployment Declares how many Pod replicas to run and how to update them
Service A stable network endpoint (IP + DNS name) that routes traffic to Pods
Namespace A virtual cluster inside a cluster — used for isolation/organisation
ConfigMap / Secret Inject configuration and sensitive data into Pods
Ingress HTTP(S) routing rules (like a reverse proxy) into the cluster
# Check your cluster is reachable
kubectl cluster-info

# List all running Pods in default namespace
kubectl get pods

# Deploy a containerised app
kubectl apply -f deployment.yaml

# Scale to 5 replicas
kubectl scale deployment my-app --replicas=5

Why does Kubernetes exist?

Running one container on your laptop is easy. Running 50 microservices across 100 servers in production is a different problem entirely. Kubernetes solves:

Problem Kubernetes solution
Container crashes Automatically restarts failed containers
Traffic spike Auto-scales Pods up (or down) based on CPU/memory
Rolling updates Replaces old Pods gradually, zero downtime
Service discovery Built-in DNS so services find each other by name
Load balancing Distributes traffic across healthy Pod replicas
Secret management Stores passwords/tokens encrypted, injects into Pods
Multi-host scheduling Places Pods on the best available Node automatically
Self-healing Replaces or reschedules Pods on failed Nodes

Kubernetes architecture

Kubernetes has two types of machines in a cluster: the Control Plane (the brain) and Worker Nodes (where your apps actually run).

┌─────────────────────────────────────────────────────────┐
│                    CONTROL PLANE                        │
│  ┌────────────┐  ┌──────────┐  ┌────────────────────┐  │
│  │ API Server │  │Scheduler │  │Controller Manager  │  │
│  └────────────┘  └──────────┘  └────────────────────┘  │
│  ┌──────────────────────────────────────────────────┐   │
│  │                    etcd (key-value store)         │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘
         │              │              │
┌────────▼──┐   ┌───────▼──┐   ┌──────▼────┐
│  Worker   │   │  Worker  │   │  Worker   │
│  Node 1   │   │  Node 2  │   │  Node 3   │
│ ┌───────┐ │   │ ┌──────┐ │   │ ┌───────┐ │
│ │ Pod A │ │   │ │ Pod B│ │   │ │ Pod A │ │
│ │ Pod B │ │   │ │ Pod C│ │   │ │ Pod D │ │
│ └───────┘ │   │ └──────┘ │   │ └───────┘ │
│  kubelet  │   │ kubelet  │   │  kubelet  │
│  kube-    │   │  kube-   │   │  kube-    │
│  proxy    │   │  proxy   │   │  proxy    │
└───────────┘   └──────────┘   └───────────┘

Control Plane components

Component Role
API Server The front door to Kubernetes — all kubectl commands go through here
etcd Distributed key-value store that holds all cluster state
Scheduler Decides which Node to place a new Pod on
Controller Manager Runs control loops to keep the actual state matching the desired state
Cloud Controller Manager Integrates with cloud provider APIs (AWS, GCP, Azure)

Worker Node components

Component Role
kubelet Agent on each Node that ensures Pods are running as expected
kube-proxy Maintains network rules for Service routing
Container Runtime Runs the actual containers (containerd, CRI-O)

Core Kubernetes objects

Pod

The smallest unit you can deploy. Usually one container, sometimes a sidecar pattern (main container + helper).

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
    - name: app
      image: nginx:1.25
      ports:
        - containerPort: 80

Pods are ephemeral — when they die, they're replaced. Never hardcode a Pod's IP address. Use a Service instead.


Deployment

The standard way to run a stateless application. Manages a ReplicaSet (set of identical Pods).

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3                    # Run 3 copies
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: my-app:v2.0
          resources:
            requests:
              memory: "64Mi"
              cpu: "250m"
            limits:
              memory: "128Mi"
              cpu: "500m"

Key Deployment capabilities:

Feature How it works
Rolling update Replaces old Pods one at a time — zero downtime by default
Rollback kubectl rollout undo deployment/my-app reverts to previous version
Scale kubectl scale deployment my-app --replicas=10 instantly
Self-healing If a Pod crashes, Deployment recreates it to maintain replica count

Service

A stable virtual IP + DNS name that routes traffic to Pods. Even when Pods are replaced (and get new IPs), the Service address never changes.

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app          # Routes to all Pods with this label
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP        # Internal only (default)

Service types:

Type Accessible from Use case
ClusterIP Inside the cluster only Internal microservice communication
NodePort Outside via <NodeIP>:<port> Simple external access / dev
LoadBalancer Cloud provider's external LB Production public-facing services
ExternalName DNS alias to external service Pointing to an external database

ConfigMap and Secret

Decouple configuration from container images.

# ConfigMap — non-sensitive config
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DATABASE_URL: "postgres://db-service:5432/mydb"
  LOG_LEVEL: "info"

---
# Secret — sensitive data (base64-encoded)
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
stringData:
  DATABASE_PASSWORD: "super-secret-password"
  API_KEY: "sk_live_abcdef123456"

Inject into a Pod as environment variables:

spec:
  containers:
    - name: app
      envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: app-secrets

Ingress

Routes external HTTP(S) traffic to Services based on host/path rules — like a smart reverse proxy at the cluster edge.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80

How Kubernetes handles updates

Zero-downtime rolling updates are built in by default:

v1 Pods:  [●][●][●]        3 running

Rolling update starts (maxUnavailable: 1, maxSurge: 1):
Step 1:   [●][●][●][○]     1 v2 Pod created
Step 2:   [●][●][ ][○]     1 v1 Pod terminated
Step 3:   [●][●][○][○]     1 v2 Pod created
Step 4:   [●][ ][○][○]     1 v1 Pod terminated
Step 5:   [○][○][○]        All v2, update complete

● = v1 Pod   ○ = v2 Pod

To rollback:

kubectl rollout history deployment/my-app     # See revision history
kubectl rollout undo deployment/my-app        # Rollback to previous
kubectl rollout undo deployment/my-app --to-revision=2  # Specific revision

Auto-scaling

Horizontal Pod Autoscaler (HPA)

Scales the number of Pods based on CPU/memory (or custom metrics):

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70   # Scale out when CPU > 70%

Vertical Pod Autoscaler (VPA)

Adjusts CPU/memory requests for existing Pods (right-sizes containers).

Cluster Autoscaler

Adds or removes Nodes from the cluster when Pods can't be scheduled (cloud only).


Namespaces: multi-tenancy in one cluster

Namespaces provide isolation between teams, environments, or projects:

# Create namespaces
kubectl create namespace staging
kubectl create namespace production

# Deploy to a specific namespace
kubectl apply -f deployment.yaml -n production

# List everything in a namespace
kubectl get all -n staging

Common namespace pattern:

Namespace Usage
default Where resources land if no namespace is specified
kube-system Kubernetes internal components
kube-public Public cluster information
monitoring Prometheus, Grafana
staging / production Environment isolation

Essential kubectl commands

# ── Cluster info ─────────────────────────────────────────
kubectl cluster-info
kubectl get nodes
kubectl get nodes -o wide            # With IP addresses

# ── Pods ─────────────────────────────────────────────────
kubectl get pods
kubectl get pods -n kube-system      # In a specific namespace
kubectl describe pod <name>          # Detailed info + events
kubectl logs <pod-name>              # Container logs
kubectl logs <pod-name> -f           # Follow (tail -f)
kubectl exec -it <pod-name> -- bash  # Shell into a running Pod

# ── Deployments ──────────────────────────────────────────
kubectl get deployments
kubectl apply -f deployment.yaml     # Create or update
kubectl delete -f deployment.yaml    # Delete
kubectl scale deployment my-app --replicas=5
kubectl rollout status deployment/my-app
kubectl rollout undo deployment/my-app

# ── Services ─────────────────────────────────────────────
kubectl get services
kubectl port-forward svc/my-service 8080:80   # Local port-forward

# ── Debugging ────────────────────────────────────────────
kubectl get events --sort-by='.lastTimestamp'
kubectl top pods                     # CPU/memory usage (needs metrics-server)
kubectl top nodes
kubectl describe node <node-name>    # Node capacity + allocated resources

Kubernetes vs Docker: what's the difference?

A common point of confusion — Docker and Kubernetes are complementary, not alternatives:

Docker Kubernetes
What it does Builds and runs containers Orchestrates containers across many machines
Scale Single host Multi-host clusters
Self-healing No (you restart manually) Yes (auto-restarts, reschedules)
Load balancing Via docker-compose (basic) Built-in Services + Ingress
Rolling updates Manual Built-in, zero-downtime
Auto-scaling No HPA / VPA / Cluster Autoscaler
Networking Bridge network per compose project Flat Pod network across all Nodes
Learning curve Low Steep
Best for Local dev, simple single-server deploys Production, microservices, cloud

The simple mental model: Docker packages your app; Kubernetes runs it in production.


Managed Kubernetes options

You don't have to manage your own control plane. Cloud providers offer fully managed Kubernetes:

Service Provider Notes
GKE (Google Kubernetes Engine) Google Cloud Most mature, auto-pilot mode
EKS (Elastic Kubernetes Service) AWS Largest cloud provider, most integrations
AKS (Azure Kubernetes Service) Microsoft Azure Strong enterprise/Windows container support
DigitalOcean Kubernetes DigitalOcean Simpler, cheaper, great for startups
Civo Civo Lightweight k3s-based, very fast provisioning
k3s Rancher/SUSE Lightweight self-hosted, great for edge/homelab

The Kubernetes ecosystem

Tool Purpose
Helm Package manager for Kubernetes (like apt/npm for k8s)
Kustomize Template-free YAML customisation
Argo CD GitOps continuous deployment
Flux GitOps alternative to Argo CD
Prometheus + Grafana Monitoring and dashboards
Istio / Linkerd Service mesh (mTLS, traffic management, observability)
Cert-Manager Automatic TLS certificates (Let's Encrypt)
Karpenter Intelligent Node provisioning on AWS
Velero Cluster backup and restore
OPA / Gatekeeper Policy enforcement
Lens Kubernetes IDE / desktop GUI
k9s Terminal UI for Kubernetes

When to use Kubernetes — and when not to

Use Kubernetes when:

  • Running microservices that need independent scaling
  • You need zero-downtime deployments out of the box
  • Your team is operating at scale (many services, many instances)
  • You need sophisticated scheduling (GPU nodes, spot instances, etc.)
  • You want GitOps / IaC-driven infrastructure
  • Running on managed cloud (GKE/EKS/AKS removes most ops burden)

Don't use Kubernetes when:

Situation Better alternative
Single small app Docker Compose + a cheap VPS
Simple static site Vercel, Netlify, GitHub Pages
One or two APIs Railway, Render, Fly.io
Very early-stage startup The overhead isn't worth it yet
Tiny team with no k8s experience Learning curve > benefit until you need scale
Serverless workloads AWS Lambda, Google Cloud Run

Rule of thumb: If you're asking "do I need Kubernetes?", you probably don't yet. When you genuinely feel the pain of managing containers at scale, Kubernetes becomes the obvious answer.


Kubernetes compared to alternatives

Kubernetes Docker Swarm Nomad ECS (AWS) Cloud Run
Complexity High Low Medium Medium Low
Ecosystem Massive Small Medium AWS-only GCP-only
Multi-cloud Yes Yes Yes No No
Auto-scaling Yes (HPA) Limited Yes Yes Yes
Service mesh Istio, Linkerd No Consul Connect App Mesh No
Stateful apps StatefulSets Limited Yes EFS No
Best for Large-scale microservices Simple swarms Mixed workloads AWS-native Serverless containers

Common Kubernetes mistakes

Mistake Better approach
No resource limits set on containers Always set requests and limits; prevents one Pod from starving others
Running as root inside containers Add securityContext: runAsNonRoot: true
Storing secrets in ConfigMaps Use Secrets (or External Secrets Operator + Vault)
One giant monolith namespace Separate namespaces per team/environment
Skipping liveness/readiness probes K8s can't detect stuck apps without them
Hard-coding image tags as latest Pin to specific digest or semver tag
No Pod Disruption Budget Deployments can have all Pods evicted at once during node drain
No network policies All Pods can talk to all Pods by default — tighten with NetworkPolicy

Frequently asked questions

Is Kubernetes only for large companies? No — but the operational overhead makes more sense at scale. Managed services (GKE Autopilot, EKS, AKS) dramatically reduce that overhead. Startups often adopt Kubernetes earlier than they should; many find a simple Fly.io or Railway setup better until they outgrow it.

Do I need to know Docker before Kubernetes? Yes. Kubernetes orchestrates containers, so you need to understand what a container is, how to write a Dockerfile, and how images/registries work first.

What language is Kubernetes written in? Go (Golang). Most of the Kubernetes ecosystem tooling (kubectl, Helm, etc.) is also written in Go.

What is a "manifest" in Kubernetes? A YAML (or JSON) file describing a Kubernetes object — Pod, Deployment, Service, etc. You apply manifests with kubectl apply -f.

What is Helm? Helm is the package manager for Kubernetes. A "Helm chart" is a reusable, parameterised package of Kubernetes manifests. Instead of maintaining 10 raw YAML files for Postgres, you run helm install postgres bitnami/postgresql --set auth.password=secret.

How is Kubernetes different from serverless? Serverless (Lambda, Cloud Functions) abstracts away servers completely — you deploy functions, not containers. Kubernetes gives you containers (more control, more operational responsibility). Cloud Run bridges the gap: containerised apps with serverless-style auto-scaling.


Quick start: local Kubernetes

The easiest ways to run Kubernetes locally:

# Option 1: Docker Desktop (enable Kubernetes in Settings)
# Built in — no install needed if you have Docker Desktop

# Option 2: minikube
brew install minikube       # macOS
minikube start
kubectl get nodes

# Option 3: kind (Kubernetes IN Docker)
go install sigs.k8s.io/kind@latest
kind create cluster
kubectl cluster-info --context kind-kind

# Option 4: k3d (k3s in Docker)
brew install k3d
k3d cluster create mycluster
kubectl get nodes

Deploy your first app:

# Create a Deployment
kubectl create deployment hello-k8s --image=nginx:1.25

# Expose it as a Service
kubectl expose deployment hello-k8s --port=80 --type=NodePort

# Open in browser (minikube)
minikube service hello-k8s

# Or port-forward manually
kubectl port-forward svc/hello-k8s 8080:80
# Visit http://localhost:8080

Kubernetes has a steep learning curve — but once it clicks, it fundamentally changes how you think about running software in production. The concepts (desired state, self-healing, declarative config) apply well beyond Kubernetes itself.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools