01-local-kubernetes-setup-options
A complete guide to understanding local Kubernetes options — Minikube, KIND, Docker Desktop, and MicroK8s — with detailed comparisons, architecture explanations, and hands-on setup instructions.
What You Will Learn
By the end of this guide you will:
- Understand what a local Kubernetes environment is and why you need one
- Know the four major local Kubernetes tools in depth
- Be able to choose the right tool for your specific use case
- Understand Minikube’s internal architecture completely
- Know exactly how each tool spins up a cluster on your machine
Why Run Kubernetes Locally?
Before learning the tools, understand why you need a local Kubernetes environment at all.
flowchart LR
subgraph PROBLEM["❌ Without Local K8s"]
P1["Deploy every change\nto cloud cluster"]
P2["Pay cloud bills\nfor development"]
P3["Slow feedback loop\n5-10 min per deploy"]
P4["Risk breaking\nshared dev environment"]
P1 --- P2 --- P3 --- P4
end
subgraph SOLUTION["✅ With Local K8s"]
S1["Test changes\non your laptop"]
S2["Zero cloud cost\nfor local development"]
S3["Instant feedback\n30 sec per deploy"]
S4["Isolated environment\nonly you are affected"]
S1 --- S2 --- S3 --- S4
end
PROBLEM -->|"Local K8s solves this"| SOLUTION
style PROBLEM fill:#f8d7da,stroke:#dc3545
style SOLUTION fill:#d1e7dd,stroke:#198754
Real benefits of running Kubernetes locally:
- Learn without risk — break things freely without affecting production or teammates
- Offline development — work on trains, planes, and places without internet
- Faster iteration — test manifests, Helm charts, and operators in seconds
- Cost savings — a full local cluster costs $0 vs $100–$500/month on EKS/GKE
- CI/CD testing — test your GitHub Actions pipelines locally before pushing
The Four Local Kubernetes Options
There are four major tools for running Kubernetes locally. Each takes a fundamentally different approach:
flowchart TD
LOCAL["🖥️ Local Kubernetes Tools"]
LOCAL --> MK["🟢 Minikube\nRuns K8s inside a VM\nor container\nBest for learning"]
LOCAL --> KIND["🔵 KIND\nK8s IN Docker\nRuns nodes as\nDocker containers\nBest for CI/CD"]
LOCAL --> DD["🟣 Docker Desktop\nBuilt-in K8s\ntoggle in UI\nBest for beginners"]
LOCAL --> MK8S["🟠 MicroK8s\nSnap-based install\nLightweight daemon\nBest for Ubuntu/Linux"]
style MK fill:#d1e7dd,stroke:#198754
style KIND fill:#cff4fc,stroke:#0dcaf0
style DD fill:#e2d9f3,stroke:#6f42c1
style MK8S fill:#fff3cd,stroke:#ffc107
1. Overview of Each Tool
🟢 Minikube
Created by: Google / Kubernetes community First released: 2016 Current version: v1.33+
Minikube is the official Kubernetes tool for local development, maintained by the Kubernetes project itself. It creates a single-node Kubernetes cluster inside a Virtual Machine or Docker container on your laptop.
Minikube was the first widely adopted local Kubernetes tool and remains the most feature-complete. It ships with a built-in addon system that lets you enable monitoring, ingress, dashboard, and metrics-server with a single command.
# What Minikube gives you out of the box
minikube addons list
# |-----------------------------|----------|
# | addon | profile |
# |-----------------------------|----------|
# | dashboard | disabled |
# | default-storageclass | enabled |
# | ingress | disabled |
# | metrics-server | disabled |
# | registry | disabled |
# | volumesnapshots | disabled |
How it works in one sentence:
Minikube downloads a VM image (or uses Docker), boots it, installs Kubernetes inside it, and configures your local kubectl to talk to it.
🔵 KIND (Kubernetes IN Docker)
Created by: Kubernetes SIGs (Special Interest Groups) First released: 2019 Stands for: Kubernetes IN Docker
KIND was built specifically for testing Kubernetes itself — the Kubernetes team uses KIND to run their own CI/CD tests. It runs entire Kubernetes nodes as Docker containers instead of VMs.
Each Docker container is a fully functional Kubernetes node with systemd, kubelet, and all other node components running inside it. This makes KIND extremely fast to start and stop, and perfect for automated testing pipelines.
# KIND can create multi-node clusters with a config file
cat kind-config.yaml
# kind: Cluster
# apiVersion: kind.x-k8s.io/v1alpha4
# nodes:
# - role: control-plane
# - role: worker
# - role: worker
# - role: worker
kind create cluster --config kind-config.yaml
# A 4-node cluster (1 control plane + 3 workers) in ~60 seconds
How it works in one sentence: KIND pulls a specially built Docker image that contains everything needed to run a Kubernetes node, starts it as a container, and bootstraps a full cluster inside those containers.
🟣 Docker Desktop
Created by: Docker Inc. First released: 2018 (K8s support added) Platforms: macOS and Windows only
Docker Desktop is the most beginner-friendly option — Kubernetes is built in and enabled with a single checkbox in the application settings. There is nothing to install separately.
When you enable Kubernetes in Docker Desktop, it runs a single-node cluster that shares the same Docker daemon you use for regular container work. This means images you build locally are immediately available to the Kubernetes cluster without any import step.
Docker Desktop → Preferences → Kubernetes → Enable Kubernetes → Apply
The trade-off is control. Docker Desktop manages everything for you — which means you have less visibility into what is happening and fewer configuration options. You also cannot run multiple clusters or choose Kubernetes versions easily.
How it works in one sentence: Docker Desktop runs a pre-configured single-node Kubernetes cluster inside its own Linux VM (on macOS/Windows), and exposes it through the same Docker context you already have.
🟠 MicroK8s
Created by: Canonical (makers of Ubuntu) First released: 2018 Distribution method: Snap package
MicroK8s is Canonical’s lightweight, opinionated Kubernetes distribution designed for Ubuntu and Linux. Unlike the others, MicroK8s installs Kubernetes as a proper system service using Ubuntu’s Snap package manager — it runs directly on your host OS without a VM layer.
This makes MicroK8s the most resource-efficient option and the best choice if you are running Kubernetes on a Raspberry Pi, a Linux server, or a resource-constrained environment.
# Installation is a single command on Ubuntu
sudo snap install microk8s --classic
# It installs its own kubectl variant
microk8s kubectl get nodes
# Or alias it
alias kubectl='microk8s kubectl'
MicroK8s also has an addon system similar to Minikube and supports HA (high-availability) multi-node clusters, which the others do not.
How it works in one sentence: MicroK8s installs Kubernetes binaries directly on your Ubuntu/Linux system as a Snap, running all components as host-level daemons without any VM or container overhead.
2. Comparison — Pros and Cons of Each
Quick Decision Matrix
flowchart TD
START["What is your situation?"]
START --> Q1{"What OS\nare you using?"}
Q1 -->|Windows/macOS\nand want simplest setup| DD["✅ Docker Desktop\nJust tick a checkbox"]
Q1 -->|Ubuntu/Linux| Q2{"What do you\nneed it for?"}
Q1 -->|Any OS| Q3{"Do you need\nmulti-node cluster?"}
Q2 -->|Learning Kubernetes| MK["✅ Minikube\nBest learning tool"]
Q2 -->|Production-like on Linux| MK8S["✅ MicroK8s\nLightest on Linux"]
Q3 -->|Yes for CI/CD testing| KIND["✅ KIND\nFastest multi-node"]
Q3 -->|No single node is fine| MK["✅ Minikube\nMost features"]
style DD fill:#e2d9f3,stroke:#6f42c1
style MK fill:#d1e7dd,stroke:#198754
style KIND fill:#cff4fc,stroke:#0dcaf0
style MK8S fill:#fff3cd,stroke:#ffc107
Detailed Feature Comparison Table
| Feature | Minikube | KIND | Docker Desktop | MicroK8s |
|---|---|---|---|---|
| OS Support | Windows, macOS, Linux | Windows, macOS, Linux | Windows, macOS only | Linux primary (snap) |
| Setup Difficulty | Easy | Medium | Very Easy | Easy (on Ubuntu) |
| Startup Time | 2–3 minutes | 30–60 seconds | 1–2 minutes | Instant (after install) |
| Resource Usage | Medium (512MB+) | Low (depends on nodes) | High (shares Docker VM) | Very Low (no VM) |
| Multi-Node Support | Limited (profiles) | ✅ Yes (native) | ❌ No | ✅ Yes |
| Multiple Clusters | ✅ Yes (profiles) | ✅ Yes (named clusters) | ❌ No | ✅ Limited |
| Addon System | ✅ Rich addon ecosystem | ❌ Manual | ❌ Manual | ✅ Good addons |
| Dashboard Built-in | ✅ minikube dashboard | ❌ Manual | ❌ Manual | ✅ microk8s dashboard |
| LoadBalancer Support | ✅ minikube tunnel | ❌ Manual (MetalLB) | ✅ Basic | ✅ MetalLB addon |
| Ingress Built-in | ✅ One command | ❌ Manual | ❌ Manual | ✅ addon |
| GPU Support | ✅ Yes | ❌ No | ❌ No | ✅ Yes |
| K8s Version Choice | ✅ Any version | ✅ Any version | ❌ Fixed | ✅ Channel-based |
| Container Runtime | Docker, containerd, CRI-O | Docker (containerd) | containerd | containerd |
| Offline Use | ✅ After first pull | ✅ After first pull | ✅ Yes | ✅ Yes |
| Production Parity | High | High | Medium | High |
| CI/CD Suitability | Good | Excellent | Poor | Good |
| Official K8s Tool | ✅ Yes | ✅ Yes | ❌ No | ❌ No |
🟢 Minikube — Pros and Cons
flowchart LR
subgraph PROS["✅ Minikube Pros"]
P1["Rich addon ecosystem\n30+ addons built-in"]
P2["Official Kubernetes tool\nGuaranteed compatibility"]
P3["Multiple driver options\nDocker, VM, none"]
P4["Built-in LoadBalancer\nminikube tunnel"]
P5["Dashboard in one command\nminikube dashboard"]
P6["Any K8s version\n--kubernetes-version flag"]
P7["GPU support\nfor ML workloads"]
end
subgraph CONS["❌ Minikube Cons"]
C1["Slower startup\n2-3 minutes with VM"]
C2["Higher resource usage\nVM overhead"]
C3["Single node only\n(by default)"]
C4["Not ideal for CI/CD\ntoo slow for pipelines"]
end
style PROS fill:#d1e7dd,stroke:#198754
style CONS fill:#f8d7da,stroke:#dc3545
Best for:
- Learning Kubernetes from scratch
- Following official Kubernetes tutorials
- Testing Helm charts and operators locally
- Developers who need a full-featured local cluster
Not ideal for:
- CI/CD pipelines (too slow)
- Multi-node topology testing
- Teams on Windows without WSL2
🔵 KIND — Pros and Cons
flowchart LR
subgraph PROS["✅ KIND Pros"]
P1["Extremely fast startup\n30-60 seconds"]
P2["Multi-node clusters\ncontrol-plane + N workers"]
P3["Native CI/CD support\nGitHub Actions plugin"]
P4["Multiple clusters\ndifferent names"]
P5["Minimal resource usage\njust Docker containers"]
P6["Any K8s version\nvia node image tag"]
end
subgraph CONS["❌ KIND Cons"]
C1["No addon system\nmanual installation required"]
C2["No built-in LoadBalancer\nneed MetalLB manually"]
C3["Local images need loading\nkind load docker-image"]
C4["Less beginner friendly\nmore manual setup"]
C5["Requires Docker\nmust be running"]
end
style PROS fill:#d1e7dd,stroke:#198754
style CONS fill:#f8d7da,stroke:#dc3545
Best for:
- CI/CD pipelines and automated testing
- Testing multi-node cluster behaviour
- Developers already comfortable with Kubernetes
- Running Kubernetes integration tests in GitHub Actions
Not ideal for:
- Absolute beginners (more manual setup)
- Persistent storage testing (ephemeral by default)
🟣 Docker Desktop — Pros and Cons
flowchart LR
subgraph PROS["✅ Docker Desktop Pros"]
P1["Zero configuration\none checkbox to enable"]
P2["Shared Docker context\nlocal images available instantly"]
P3["Familiar GUI\nfor Docker users"]
P4["Automatic updates\nhandles K8s version updates"]
P5["Perfect for beginners\nno command line setup"]
end
subgraph CONS["❌ Docker Desktop Cons"]
C1["macOS and Windows only\nnot available on Linux"]
C2["High resource usage\nshares Docker Desktop VM"]
C3["Single node only\nno multi-node support"]
C4["Limited configuration\nblack box experience"]
C5["Paid for teams\nlicense cost for companies"]
C6["Fixed K8s version\ncannot choose version"]
C7["Poor production parity\nmissing enterprise features"]
end
style PROS fill:#d1e7dd,stroke:#198754
style CONS fill:#f8d7da,stroke:#dc3545
Best for:
- Absolute beginners who just want to try Kubernetes
- Developers already using Docker Desktop for containers
- Quick demos and tutorials on macOS or Windows
- Teams who want zero-friction setup
Not ideal for:
- Linux developers
- CI/CD pipelines
- Testing specific K8s versions
- Multi-node topology testing
🟠 MicroK8s — Pros and Cons
flowchart LR
subgraph PROS["✅ MicroK8s Pros"]
P1["Lowest resource usage\nno VM overhead"]
P2["Instant startup\nalready running as service"]
P3["Native Linux service\nrestarts automatically"]
P4["Multi-node HA support\nfor serious testing"]
P5["Great addon system\nobservability, Istio, etc."]
P6["Edge/IoT ready\nworks on Raspberry Pi"]
P7["Automatic updates\nCanonical maintains it"]
end
subgraph CONS["❌ MicroK8s Cons"]
C1["Linux/Ubuntu focused\npoor Windows/macOS experience"]
C2["Snap dependency\nsnap must be available"]
C3["Custom kubectl\nmicrok8s kubectl (not standard)"]
C4["Less community content\nfewer tutorials target it"]
C5["Opinionated setup\nharder to customise"]
end
style PROS fill:#d1e7dd,stroke:#198754
style CONS fill:#f8d7da,stroke:#dc3545
Best for:
- Ubuntu/Linux developers
- Raspberry Pi and edge computing
- Resource-constrained machines
- Developers who want Kubernetes as a persistent background service
Not ideal for:
- macOS or Windows users
- Developers wanting full control and portability
Side-by-Side Resource Usage
xychart-beta
title "Resource Usage Comparison (Idle Cluster)"
x-axis ["Minikube (VM)", "Minikube (Docker)", "KIND", "Docker Desktop", "MicroK8s"]
y-axis "RAM Usage (MB)" 0 --> 3000
bar [2048, 900, 700, 2500, 400]
3. Minikube Architecture — Deep Dive
Minikube is the recommended starting point for learning Kubernetes, so understanding its architecture deeply gives you insight into how Kubernetes itself works.
High-Level Architecture
flowchart TD
subgraph HOST["🖥️ Host Machine (Your Laptop)"]
KC["kubectl\n(Kubernetes CLI)"]
MC["minikube\n(CLI tool)"]
KCONFIG["~/.kube/config\n(cluster credentials)"]
KC --> KCONFIG
MC --> KCONFIG
end
subgraph DRIVER["🔧 Driver Layer"]
direction LR
DOCKER_D["Docker Driver\n(default on Linux/macOS)\nK8s runs in a container"]
VM_D["VM Drivers\nVirtualBox, HyperKit, HyperV\nK8s runs in a VM"]
NONE_D["None Driver\n(Linux only)\nK8s runs on host OS"]
end
subgraph MINIKUBE_NODE["☸️ Minikube Node (VM or Container)"]
subgraph CONTROL["Control Plane"]
API["kube-apiserver\nPort 8443"]
ETCD["etcd\nCluster state storage"]
SCHED["kube-scheduler\nPod placement"]
CTRL["kube-controller-manager\nReconciliation loops"]
API <--> ETCD
API --> SCHED
API --> CTRL
end
subgraph NODE_COMP["Node Components"]
KUBELET["kubelet\nManages pods"]
PROXY["kube-proxy\nNetwork rules"]
CRI["Container Runtime\n(Docker/containerd)"]
KUBELET --> CRI
end
subgraph PODS["Running Pods"]
COREDNS["CoreDNS\nCluster DNS"]
STORAGE["storage-provisioner\nLocal PV provisioner"]
MIRROR["kube-apiserver mirror\n(apiserver in pod form)"]
end
API --> KUBELET
KUBELET --> COREDNS
KUBELET --> STORAGE
end
HOST --> DRIVER
DRIVER --> MINIKUBE_NODE
KC -->|"HTTPS :8443"| API
style HOST fill:#e8f4fd,stroke:#0d6efd
style DRIVER fill:#fff3cd,stroke:#ffc107
style MINIKUBE_NODE fill:#d1e7dd,stroke:#198754
style CONTROL fill:#cff4fc,stroke:#0dcaf0
style NODE_COMP fill:#e2d9f3,stroke:#6f42c1
The Driver Layer — How Minikube Creates a Cluster
The driver is the most important architectural concept in Minikube. It decides where and how the Kubernetes node runs.
flowchart LR
subgraph DRIVERS["Minikube Drivers"]
direction TB
subgraph DOCKER_DRIVER["Docker Driver (Recommended)"]
DD1["Creates a Docker container\nwith systemd inside"]
DD2["Container acts as a\nfull Kubernetes node"]
DD3["Fast, no VM overhead\nShares host Docker daemon"]
DD1 --> DD2 --> DD3
end
subgraph VM_DRIVER["VM Drivers"]
VM1["VirtualBox / HyperKit /\nHyperV / QEMU"]
VM2["Downloads a Linux VM image\n(Buildroot-based)"]
VM3["Boots full Linux VM\nKubernetes runs inside"]
VM4["More isolated but\nslower and more RAM"]
VM1 --> VM2 --> VM3 --> VM4
end
subgraph NONE_DRIVER["None Driver (Linux only)"]
N1["No VM, no container"]
N2["Runs Kubernetes\ndirectly on host OS"]
N3["Fastest option\nbut least isolated"]
N1 --> N2 --> N3
end
end
style DOCKER_DRIVER fill:#d1e7dd,stroke:#198754
style VM_DRIVER fill:#fff3cd,stroke:#ffc107
style NONE_DRIVER fill:#f8d7da,stroke:#dc3545
Choose your driver:
# Use Docker driver (default, recommended for most users)
minikube start --driver=docker
# Use VirtualBox (full VM isolation)
minikube start --driver=virtualbox
# Use HyperKit (macOS native hypervisor)
minikube start --driver=hyperkit
# Use Hyper-V (Windows native hypervisor)
minikube start --driver=hyperv
# No driver — runs directly on Linux host (fastest)
minikube start --driver=none
Control Plane Components Inside Minikube
Minikube runs a single-node cluster where the same node acts as both the control plane and the worker. Here is what runs inside:
flowchart TD
subgraph SINGLE_NODE["Minikube Single Node — Does Everything"]
subgraph CP["Control Plane (normally on separate servers in production)"]
API["kube-apiserver\n\nThe front door — all kubectl\ncommands hit this REST API\nPort: 8443 (HTTPS)"]
ETCD["etcd\n\nDistributed key-value store\nStores ALL cluster state\nPod specs, deployments, secrets, etc."]
SCH["kube-scheduler\n\nWatches for unscheduled pods\nDecides which node gets each pod\n(only one node here — easy job)"]
CTRL["kube-controller-manager\n\nRuns all controller loops:\nDeployment controller\nReplicaSet controller\nNode controller, etc."]
end
subgraph WN["Worker Node (normally separate servers in production)"]
KUBELET["kubelet\n\nNode agent — talks to API server\nEnsures pods run as specified\nReports node health back"]
PROXY["kube-proxy\n\nMaintains iptables rules\nEnables Service networking\nLoad balances across pod IPs"]
CRI["Container Runtime\ncontainerd / Docker\n\nActually starts and stops\ncontainers when kubelet asks"]
end
subgraph SYSTEM_PODS["System Pods (run by Kubernetes itself)"]
DNS["CoreDNS\nPod-to-pod DNS resolution\nsvc.cluster.local names"]
PROV["storage-provisioner\nAutomatic PersistentVolume\nprovisioning on local disk"]
TUNNEL["minikube tunnel\n(optional) — creates\nLoadBalancer routes"]
end
API <-->|"Reads/Writes\ncluster state"| ETCD
API -->|"Pod assignments"| SCH
API -->|"Control loops"| CTRL
API -->|"Watch & report"| KUBELET
KUBELET -->|"Start/stop pods"| CRI
KUBELET --> DNS
KUBELET --> PROV
PROXY -->|"iptables rules"| CRI
end
style CP fill:#cff4fc,stroke:#0dcaf0
style WN fill:#d1e7dd,stroke:#198754
style SYSTEM_PODS fill:#fff3cd,stroke:#ffc107
Request Flow — What Happens When You Run kubectl
sequenceDiagram
actor You
participant kubectl
participant kubeconfig as ~/.kube/config
participant apiserver as kube-apiserver (inside Minikube)
participant etcd
participant scheduler as kube-scheduler
participant kubelet
participant runtime as Container Runtime
You->>kubectl: kubectl apply -f deployment.yaml
kubectl->>kubeconfig: Read cluster address + credentials
kubeconfig-->>kubectl: https://192.168.49.2:8443 + client cert
kubectl->>apiserver: POST /apis/apps/v1/deployments
apiserver->>apiserver: Authenticate (client cert)
apiserver->>apiserver: Authorise (RBAC check)
apiserver->>apiserver: Validate (schema check)
apiserver->>etcd: Store deployment object
etcd-->>apiserver: Stored ✅
apiserver-->>kubectl: 201 Created
Note over apiserver,scheduler: Deployment controller detects new deployment
apiserver->>scheduler: Unscheduled pods detected
scheduler->>apiserver: Assign pods to minikube node
apiserver->>etcd: Store pod assignments
Note over kubelet: kubelet watches API server continuously
kubelet->>apiserver: New pods assigned to this node
apiserver-->>kubelet: Pod specs
kubelet->>runtime: Pull image + start container
runtime-->>kubelet: Container running
kubelet->>apiserver: Update pod status = Running
Networking Inside Minikube
Minikube creates its own network namespace. Understanding this helps you know how to access services:
flowchart LR
subgraph YOUR_MACHINE["🖥️ Your Machine"]
BROWSER["Browser\nlocalhost:8080"]
KUBECTL["kubectl"]
end
subgraph MINIKUBE_NET["Minikube Network\n192.168.49.0/24"]
NODE_IP["Minikube Node IP\n192.168.49.2"]
subgraph CLUSTER_NET["Pod Network\n10.244.0.0/16"]
POD1["Pod: frontend\n10.244.0.5"]
POD2["Pod: backend\n10.244.0.6"]
POD3["Pod: database\n10.244.0.7"]
end
subgraph SERVICES["Service Network\n10.96.0.0/12"]
SVC1["frontend-svc\nClusterIP: 10.96.0.10"]
SVC2["backend-svc\nClusterIP: 10.96.0.20"]
end
KPROXY["kube-proxy\niptables rules"]
end
BROWSER -->|"minikube service frontend-svc\nor kubectl port-forward"| NODE_IP
KUBECTL -->|"HTTPS 192.168.49.2:8443"| NODE_IP
NODE_IP --> KPROXY
KPROXY --> SVC1 --> POD1
KPROXY --> SVC2 --> POD2
POD1 --> POD2
POD2 --> POD3
style YOUR_MACHINE fill:#e8f4fd,stroke:#0d6efd
style MINIKUBE_NET fill:#d1e7dd,stroke:#198754
style CLUSTER_NET fill:#fff3cd,stroke:#ffc107
style SERVICES fill:#e2d9f3,stroke:#6f42c1
Accessing services from your host machine:
# Method 1 — NodePort: access via minikube IP + NodePort
minikube ip
# 192.168.49.2
# Access at http://192.168.49.2:30080
# Method 2 — minikube service (opens browser automatically)
minikube service frontend-service
# Method 3 — kubectl port-forward
kubectl port-forward svc/frontend-service 8080:80
# Access at http://localhost:8080
# Method 4 — minikube tunnel (for LoadBalancer type services)
minikube tunnel
# Service gets a real IP on your host
Storage Architecture in Minikube
flowchart TD
subgraph HOST_FS["Host Machine Filesystem"]
HOST_DIR["~/.minikube/machines/\nminikube/disk.vmdk\n(or Docker volume)"]
end
subgraph MK_NODE["Minikube Node"]
subgraph PROVISIONER["storage-provisioner"]
SP["Watches for PVC creation\nCreates directories\nautomatically"]
end
subgraph STORAGE["Local Storage"]
PV1["PersistentVolume\n/data/pvc-abc123\n(inside minikube node)"]
PV2["PersistentVolume\n/data/pvc-def456"]
end
subgraph PODS_STORAGE["Pods Using Storage"]
DB_POD["postgres pod\nmounts /data/pvc-abc123\nat /var/lib/postgresql"]
end
SP --> PV1
SP --> PV2
PV1 --> DB_POD
end
HOST_FS --> MK_NODE
style HOST_FS fill:#fff3cd,stroke:#ffc107
style MK_NODE fill:#d1e7dd,stroke:#198754
style PROVISIONER fill:#cff4fc,stroke:#0dcaf0
# Storage works automatically in Minikube
# Just create a PVC and it provisions automatically
kubectl apply -f - << 'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF
# PVC is immediately bound (no cloud provisioner needed)
kubectl get pvc
# NAME STATUS VOLUME CAPACITY STORAGECLASS
# my-pvc Bound pvc-abc123... 1Gi standard
Minikube Profiles — Multiple Clusters
One of Minikube’s powerful features is profiles — you can run multiple completely separate Kubernetes clusters simultaneously:
# Default cluster (profile: minikube)
minikube start
# Create a second cluster with different K8s version
minikube start -p dev-cluster --kubernetes-version=v1.28.0
# Create a third cluster for testing
minikube start -p test-cluster --kubernetes-version=v1.29.0
# List all clusters
minikube profile list
# |----------------|-----------|---------|--------------|------|---------|---------|
# | Profile | VM Driver | Runtime | IP | Port | Version | Status |
# |----------------|-----------|---------|--------------|------|---------|---------|
# | minikube | docker | docker | 192.168.49.2 | 8443 | v1.30.0 | Running |
# | dev-cluster | docker | docker | 192.168.49.3 | 8443 | v1.28.0 | Running |
# | test-cluster | docker | docker | 192.168.49.4 | 8443 | v1.29.0 | Stopped |
# |----------------|-----------|---------|--------------|------|---------|---------|
# Switch between clusters
minikube profile dev-cluster
kubectl config use-context dev-cluster
# Stop specific cluster
minikube stop -p dev-cluster
# Delete specific cluster
minikube delete -p test-cluster
Minikube Addon Architecture
Minikube’s addon system installs additional components as Kubernetes deployments and DaemonSets on the cluster:
flowchart TD
subgraph ADDON_SYSTEM["Minikube Addon System"]
CLI["minikube addons enable <name>"]
MANIFEST["Addon Manifest\n(stored in minikube binary)"]
CLI --> MANIFEST
MANIFEST -->|"kubectl apply"| K8S
end
subgraph K8S["Kubernetes Cluster"]
subgraph ADDONS["Installed Addons"]
ING["Ingress\n(nginx ingress controller)\nNamespace: ingress-nginx"]
DASH["Dashboard\n(web UI)\nNamespace: kubernetes-dashboard"]
MET["Metrics Server\n(HPA support)\nNamespace: kube-system"]
REG["Registry\n(local Docker registry)\nNamespace: kube-system"]
PROM["Prometheus\n(monitoring)\nNamespace: monitoring"]
end
end
style ADDON_SYSTEM fill:#cff4fc,stroke:#0dcaf0
style K8S fill:#d1e7dd,stroke:#198754
# Enable common addons
minikube addons enable ingress # NGINX Ingress Controller
minikube addons enable dashboard # Kubernetes Web Dashboard
minikube addons enable metrics-server # Enable HPA
minikube addons enable registry # Local Docker registry
minikube addons enable storage-provisioner-gluster # Better storage
# Open dashboard in browser instantly
minikube dashboard
# List all available addons with status
minikube addons list
Hands-On Setup — Getting Started with Each Tool
Installing and Starting Minikube
# --- Linux ---
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# --- macOS ---
brew install minikube
# --- Windows (PowerShell as Admin) ---
winget install minikube
# Start cluster with recommended resources
minikube start \
--driver=docker \
--cpus=4 \
--memory=4096 \
--disk-size=20g \
--kubernetes-version=v1.30.0
# Verify everything is working
minikube status
kubectl get nodes
kubectl get pods -A
Installing and Starting KIND
# --- Linux ---
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.23.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# --- macOS ---
brew install kind
# --- Windows ---
winget install Kubernetes.kind
# Create single-node cluster
kind create cluster --name my-cluster
# Create multi-node cluster
cat > kind-config.yaml << 'EOF'
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
kind create cluster --name multi-node --config kind-config.yaml
# Verify
kubectl get nodes
Installing MicroK8s (Ubuntu/Linux)
# Install
sudo snap install microk8s --classic
# Add your user to microk8s group
sudo usermod -aG microk8s $USER
newgrp microk8s
# Wait for it to be ready
microk8s status --wait-ready
# Enable essential addons
microk8s enable dns storage dashboard ingress metrics-server
# Use kubectl via microk8s
microk8s kubectl get nodes
# Or set an alias
alias kubectl='microk8s kubectl'
echo "alias kubectl='microk8s kubectl'" >> ~/.bashrc
When Minikube Is the Right Choice — Real Scenarios
flowchart TD
S1["📚 Scenario: Preparing for CKA exam"]
S2["🧪 Scenario: Testing a Helm chart you wrote"]
S3["🔄 Scenario: CI/CD pipeline tests"]
S4["🍓 Scenario: Running on Raspberry Pi"]
S5["🪟 Scenario: Windows developer, just starting"]
S1 -->|"Best choice"| MK1["✅ Minikube\nMatches exam environment\nFull kubeadm-like cluster"]
S2 -->|"Best choice"| MK2["✅ Minikube\nAddon system handles\ningress, metrics easily"]
S3 -->|"Best choice"| KIND1["✅ KIND\nFastest startup\nGitHub Actions support"]
S4 -->|"Best choice"| MK8S1["✅ MicroK8s\nLowest resource usage\nSnap available on Pi"]
S5 -->|"Best choice"| DD1["✅ Docker Desktop\nOne checkbox setup\nno CLI required"]
style MK1 fill:#d1e7dd,stroke:#198754
style MK2 fill:#d1e7dd,stroke:#198754
style KIND1 fill:#cff4fc,stroke:#0dcaf0
style MK8S1 fill:#fff3cd,stroke:#ffc107
style DD1 fill:#e2d9f3,stroke:#6f42c1
Summary Tables
Architecture Comparison
| Component | Minikube | KIND | Docker Desktop | MicroK8s |
|---|---|---|---|---|
| Isolation | VM or Container | Docker Container | VM | None (host) |
| Control Plane | Inside node | Inside container | Inside VM | On host |
| Worker Nodes | Same as control | Separate containers | Same as control | Same as control |
| Networking | Host-only network | Docker network | NAT | Host network |
| Storage | hostPath (auto) | hostPath (manual) | hostPath (auto) | hostPath (auto) |
| DNS | CoreDNS pod | CoreDNS pod | CoreDNS pod | CoreDNS pod |
Command Comparison
| Action | Minikube | KIND | Docker Desktop | MicroK8s |
|---|---|---|---|---|
| Start | minikube start | kind create cluster | GUI checkbox | (auto on install) |
| Stop | minikube stop | kind delete cluster | GUI checkbox | microk8s stop |
| Status | minikube status | kind get clusters | GUI indicator | microk8s status |
| Dashboard | minikube dashboard | Manual | Manual | microk8s dashboard-proxy |
| Tunnel | minikube tunnel | Manual (MetalLB) | Automatic | microk8s enable metallb |
| kubectl | Standard | Standard | Standard | microk8s kubectl |
| Addons | minikube addons enable | Manual | Manual | microk8s enable |
Key Takeaways
| Topic | Key Takeaway |
|---|---|
| Local K8s purpose | Learn, test, and develop without cloud costs or risk |
| Minikube | Most feature-complete, best for learning, official K8s tool |
| KIND | Fastest startup, best for CI/CD, multi-node support |
| Docker Desktop | Easiest setup, macOS/Windows only, limited features |
| MicroK8s | Lightest on resources, best for Ubuntu/Linux |
| Minikube architecture | Single node acts as both control plane and worker via a driver layer |
| Minikube networking | Cluster gets its own subnet, access via minikube service or tunnel |
| Minikube profiles | Run multiple clusters simultaneously with different K8s versions |
| Driver choice | Docker driver is default and recommended for most users |