Minikube
Local Kubernetes cluster running on a single machine for development, testing, and learning.
Minikube Cheatsheet
Local Kubernetes cluster running on a single machine for development, testing, and learning.
Overview
Minikube is a tool that runs a single-node Kubernetes cluster inside a virtual machine, container, or on your local system. Designed for local development and testing, Minikube provides a lightweight, easy-to-use Kubernetes environment without the complexity of multi-node production setups. It supports multiple container runtimes, hypervisors, and platforms, making it ideal for developers learning Kubernetes or testing applications locally.
graph TB
subgraph "Minikube Architecture"
subgraph "Host Machine"
direction TB
MINIKUBE[Minikube Binary]
CONFIG["Config & Status"]
end
subgraph "VM/Container"
API[API Server<br/>Port 6443]
SCHED[Scheduler]
CCM[Controller Manager]
ETCD[("etcd")]
KUBELET[Kubelet]
RUNTIME[Container Runtime<br/>Docker/containerd]
end
subgraph "Built-in Components"
DASHBOARD["Kubernetes Dashboard"]
DNS[CoreDNS]
METRICS["Metrics Server"]
ADDONS["Addons Manager"]
end
MINIKUBE --> VM["Hypervisor/Container<br/>Virtualisation"]
VM --> API
API --> ETCD
API --> KUBELET
KUBELET --> RUNTIME
ADDONS --> DASHBOARD
ADDONS --> METRICS
end
style API fill:#326ce5
style KUBELET fill:#4aa1d8
style ETCD fill:#336791
style RUNTIME fill:#575757
Local Kubernetes Cluster Setup
Key Concepts
- Single-node Cluster: Minikube runs a complete Kubernetes cluster on a single machine
- Virtual Machine/Container: Uses hypervisors (VirtualBox, Hyper-V, KVM) or container runtimes (Docker, Podman)
- kubeconfig Auto-setup: Automatically configures kubectl to access the local cluster
- IP Address: Minikube allocates an IP address accessible from the host machine
- Networking: Supports host network access and port forwarding mechanisms
- Persistent State: Cluster state stored in
~/.minikubedirectory
Common Commands
# Start Minikube (creates cluster if needed)
minikube start
# Start with specific driver
minikube start --driver docker
minikube start --driver virtualbox
minikube start --driver podman
# Start with Kubernetes version
minikube start --kubernetes-version v1.28.0
# Stop cluster without deleting
minikube stop
# Delete cluster and cleanup
minikube delete
# Get cluster status
minikube status
# Get Minikube IP address
minikube ip
# Get cluster info
kubectl cluster-info
# SSH into Minikube node
minikube ssh
# List all Minikube clusters
minikube profile list
# Switch between profiles
minikube profile minikube
minikube profile dev
Examples
# Create multi-node cluster with 3 nodes
minikube start --nodes 3 --driver docker
# Configure persistent cluster profile
minikube start --profile development \
--driver docker \
--cpus 4 \
--memory 4096 \
--kubernetes-version v1.28.0
# Access cluster from command line
kubectl get nodes
kubectl get pods -A
# Mount host directory into cluster
minikube mount /home/user/project:/mnt/project
# Configure kubectl context
kubectl config get-contexts
kubectl config use-context minikube
# Get kubeconfig location
cat ~/.kube/config | grep -A 3 "name: minikube"
# Create namespace and verify access
kubectl create namespace development
kubectl get namespaces
Addons (Dashboard, Metrics-Server)
Key Concepts
flowchart TB
ADDONS["Minikube Addons Manager"]
ADDONS --> DASH["Dashboard<br/>Web UI for cluster<br/>Port 30000"]
ADDONS --> METRICS["Metrics Server<br/>Resource monitoring<br/>CPU/Memory metrics"]
ADDONS --> INGRESS["Ingress Controller<br/>Manage ingress resources"]
ADDONS --> STORAGE["Storage Provisioner<br/>Local storage management"]
ADDONS --> DNS["CoreDNS<br/>Service discovery"]
ADDONS --> REGISTRY["Registry<br/>Local container registry"]
DASH -.-> KUBECTL["kubectl proxy<br/>Access from browser"]
METRICS -.-> HPA["Horizontal Pod Autoscaler<br/>Scale based on metrics"]
style ADDONS fill:#326ce5
style DASH fill:#4aa1d8
style METRICS fill:#4aa1d8
style INGRESS fill:#4aa1d8
- Dashboard: Web-based UI for cluster visualisation and management
- Metrics Server: Collects resource metrics for HPA and monitoring
- Ingress Controller: Manages ingress resources for routing
- Storage Provisioner: Manages persistent volumes and claims
- Container Registry: Local registry for pushing/pulling images
Common Commands
# List available addons
minikube addons list
# Enable addon
minikube addons enable dashboard
minikube addons enable metrics-server
minikube addons enable ingress
# Disable addon
minikube addons disable dashboard
# Check addon status
minikube addons list | grep enabled
# Open Dashboard in browser
minikube dashboard
# Get Dashboard URL
minikube dashboard --url
# Enable multiple addons (one at a time — addons enable only accepts one addon per call)
minikube addons enable dashboard
minikube addons enable metrics-server
minikube addons enable ingress
minikube addons enable storage-provisioner
# View addon configurations
minikube addons configure dashboard
# Check metrics after enabling metrics-server
kubectl top nodes
kubectl top pods -A
Examples
# Enable essential development addons
minikube start --driver docker
minikube addons enable dashboard
minikube addons enable metrics-server
minikube addons enable ingress
# Access metrics
kubectl get deployment -n kube-system metrics-server
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods
# Create HPA with metrics
cat << EOF | kubectl apply -f -
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
EOF
# Port-forward to access services
kubectl port-forward -n kubernetes-dashboard service/kubernetes-dashboard 8001:80
# Enable registry addon and use local images
minikube addons enable registry
docker tag myimage:latest localhost:5000/myimage:latest
docker push localhost:5000/myimage:latest
# Deploy image from local registry
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: localhost:5000/myimage:latest
imagePullPolicy: IfNotPresent
EOF
Persistent Storage (hostPath, Dynamic Provisioning)
Key Concepts
graph TB
subgraph "Storage Architecture"
HOST["Host Machine<br/>Filesystem"]
MOUNT["Minikube Mount<br/>hostPath volumes"]
subgraph "Persistent Volumes"
HOSTPV["hostPath PV<br/>Direct node access"]
DYNPV["Dynamic PV<br/>Storage class provisioning"]
end
subgraph "Applications"
POD1["Pod 1<br/>Using PVC"]
POD2["Pod 2<br/>Using PVC"]
end
subgraph "Claims"
PVC1["PersistentVolumeClaim"]
PVC2["PersistentVolumeClaim"]
end
HOST --> MOUNT
MOUNT --> HOSTPV
HOSTPV --> PVC1
DYNPV --> PVC2
PVC1 --> POD1
PVC2 --> POD2
end
style HOST fill:#f0ad4e
style HOSTPV fill:#5bc0de
style DYNPV fill:#5bc0de
- hostPath Volumes: Direct access to host filesystem from pods
- Minikube Mount: Mount host directory into Minikube VM for accessibility
- Dynamic Provisioning: Automatic PersistentVolume creation via StorageClass
- Storage Classes: Define provisioning policies and parameters
- PersistentVolumeClaims: Request storage resources for applications
Common Commands
# List storage classes
kubectl get storageclass
# Inspect storage class
kubectl describe storageclass standard
# Get persistent volumes
kubectl get pv
# Get persistent volume claims
kubectl get pvc -n default
# Describe PVC
kubectl describe pvc <pvc-name>
# Create hostPath volume
kubectl apply -f - << EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: hostpath-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /data
EOF
# Create PVC with dynamic provisioning
kubectl apply -f - << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 1Gi
EOF
# Mount host directory in Minikube
minikube mount /host/path:/vm/path
# Check volume mounts
kubectl get pv
kubectl get pvc --all-namespaces
# Delete PVC
kubectl delete pvc <pvc-name>
Examples
# Mount host directory and use it in pod
minikube mount /home/user/shared:/mnt/shared &
# Create hostPath PV pointing to mounted directory
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: shared-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/shared
persistentVolumeReclaimPolicy: Retain
EOF
# Create PVC for hostPath volume
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
volumeName: shared-pv
EOF
# Deploy pod using the hostPath PVC
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: data-app
spec:
containers:
- name: app
image: alpine
command: ['sh', '-c', 'while true; do echo "$(date)" >> /data/log.txt; sleep 10; done']
volumeMounts:
- name: shared
mountPath: /data
volumes:
- name: shared
persistentVolumeClaim:
claimName: shared-pvc
EOF
# Create dynamic storage provisioning
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
reclaimPolicy: Delete
EOF
# Create PVC with dynamic provisioning
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 2Gi
EOF
# Deploy StatefulSet with persistent storage
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: password
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: standard
resources:
requests:
storage: 1Gi
EOF
# Check PVC status and verify mount
kubectl get pvc
kubectl describe pvc app-pvc
kubectl get pv
Resource Allocation (CPU, Memory)
Key Concepts
graph TB
subgraph "Resource Management"
MINIKUBE["Minikube Configuration"]
MINIKUBE --> HOST_ALLOC["Host Allocation<br/>CPU & Memory limit<br/>for entire cluster"]
MINIKUBE --> POD_REQ["Pod Requests<br/>Guaranteed resources<br/>for scheduling"]
MINIKUBE --> POD_LIM["Pod Limits<br/>Maximum resource usage<br/>enforced by kubelet"]
HOST_ALLOC --> SCHEDULER["Scheduler<br/>Places pods based<br/>on available resources"]
POD_REQ --> SCHEDULER
POD_LIM --> KUBELET["Kubelet<br/>Enforces resource limits<br/>OOM kills if exceeded"]
SCHEDULER --> PODS["Running Pods"]
KUBELET --> PODS
end
style MINIKUBE fill:#326ce5
style SCHEDULER fill:#5bc0de
style KUBELET fill:#5bc0de
- Minikube Allocation: Total CPU and memory allocated to the cluster
- Pod Requests: Minimum resources needed for pod scheduling
- Pod Limits: Maximum resources a pod can consume
- Resource Classes: Define CPU/memory quotas for namespaces
- Overcommitment: Running more resource requests than available
Common Commands
# Start Minikube with CPU and memory allocation
minikube start --cpus 4 --memory 4096
# Increase existing cluster resources
minikube config set cpus 6
minikube config set memory 8192
# Check current resource allocation
minikube config view
# Check node capacity
kubectl describe node minikube
# View node resource availability
kubectl get nodes -o wide
kubectl describe node minikube | grep -A 10 "Capacity\|Allocatable"
# Check resource usage
kubectl top nodes
kubectl top pods -A
# Create namespace resource quota
kubectl apply -f - << EOF
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: default
spec:
hard:
requests.cpu: "2"
requests.memory: "2Gi"
limits.cpu: "4"
limits.memory: "4Gi"
EOF
# Check resource quota
kubectl describe resourcequota compute-quota
# Create limit range for namespace
kubectl apply -f - << EOF
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-memory-limits
namespace: default
spec:
limits:
- max:
cpu: "1"
memory: "512Mi"
min:
cpu: "100m"
memory: "128Mi"
type: Container
EOF
Examples
# Start Minikube with 4 CPUs and 8GB memory
minikube start --cpus 4 --memory 8192 --driver docker
# Verify allocation
minikube config view
kubectl describe node minikube | grep -A 10 "Capacity"
# Deploy pod with resource requests and limits
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: app
image: nginx
resources:
requests:
cpu: "500m"
memory: "128Mi"
limits:
cpu: "1"
memory: "256Mi"
EOF
# Verify pod resource allocation
kubectl describe pod resource-demo
kubectl get pod resource-demo -o yaml | grep -A 15 "resources:"
# Deploy deployment with resource management
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "500m"
memory: "256Mi"
ports:
- containerPort: 80
EOF
# Monitor resource usage during deployment
kubectl top pods
kubectl get nodes -o wide
kubectl describe nodes minikube | grep -A 20 "Allocated resources"
# Create namespace with resource quota
kubectl create namespace limited
kubectl apply -f - << EOF
apiVersion: v1
kind: ResourceQuota
metadata:
name: namespace-quota
namespace: limited
spec:
hard:
requests.cpu: "1"
requests.memory: "1Gi"
limits.cpu: "2"
limits.memory: "2Gi"
pods: "10"
EOF
# Deploy to resource-limited namespace
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: constrained-pod
namespace: limited
spec:
containers:
- name: app
image: alpine
command: ['sleep', '3600']
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "250m"
memory: "256Mi"
EOF
# Check HPA with metrics
minikube addons enable metrics-server
sleep 30 # Wait for metrics to be collected
cat << EOF | kubectl apply -f -
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
EOF
# Monitor HPA scaling decisions
kubectl get hpa -w
kubectl describe hpa web-hpa
Quick Reference
| Task | Command |
|---|---|
| Start cluster | minikube start |
| Stop cluster | minikube stop |
| Delete cluster | minikube delete |
| Get cluster IP | minikube ip |
| SSH into node | minikube ssh |
| Check status | minikube status |
| List profiles | minikube profile list |
| Set CPU/memory | minikube start --cpus 4 --memory 8192 |
| Enable dashboard | minikube dashboard |
| Enable metrics | minikube addons enable metrics-server |
| Enable ingress | minikube addons enable ingress |
| Mount directory | minikube mount /host/path:/vm/path |
| Open browser URL | minikube service <service-name> |
| Get kubeconfig | cat ~/.kube/config |
| List addons | minikube addons list |
| Enable addon | minikube addons enable <addon-name> |
| Get logs | minikube logs |
| Get node info | kubectl describe node minikube |
| Get PV/PVC | kubectl get pv,pvc |
| Monitor resources | kubectl top nodes,pods |
| Resource quota | kubectl get resourcequota |
| Limit range | kubectl get limitrange |
Common Issues and Solutions
Cluster Won't Start
Problem: Minikube fails to start with error
# Solution 1: Use different driver
minikube start --driver docker
minikube start --driver podman
minikube start --driver virtualbox
# Solution 2: Delete and restart
minikube delete
minikube start
# Solution 3: Check system requirements
minikube config set cpus 2
minikube config set memory 2048
minikube start
# Solution 4: Check logs
minikube logs
minikube logs --length 10
kubectl Cannot Connect to Cluster
Problem: kubectl commands fail with connection errors
# Solution 1: Configure kubeconfig
minikube update-context
kubectl config use-context minikube
# Solution 2: Check cluster status
minikube status
minikube stop
minikube start
# Solution 3: Verify kubeconfig
cat ~/.kube/config
export KUBECONFIG=~/.kube/config
# Solution 4: Reset kubeconfig
rm ~/.kube/config
minikube delete
minikube start
Dashboard Not Accessible
Problem: Dashboard addon enabled but not reachable
# Solution 1: Enable dashboard addon
minikube addons enable dashboard
# Solution 2: Open dashboard directly
minikube dashboard
# Solution 3: Port-forward manually
kubectl proxy
# Access at http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
# Solution 4: Check pod status (dashboard runs in kubernetes-dashboard namespace)
kubectl get pods -n kubernetes-dashboard
kubectl describe pod -n kubernetes-dashboard
# Solution 5: Restart dashboard
kubectl rollout restart deployment kubernetes-dashboard -n kubernetes-dashboard
Metrics Server Not Working
Problem: HPA or kubectl top command fails
# Solution 1: Enable metrics-server addon
minikube addons enable metrics-server
# Solution 2: Wait for metrics collection
sleep 30
kubectl top nodes
kubectl top pods -A
# Solution 3: Check metrics server pod
kubectl get pods -n kube-system | grep metrics-server
kubectl logs -n kube-system deployment/metrics-server
# Solution 4: Verify metrics API
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
# Solution 5: Reinstall metrics server
kubectl delete deployment metrics-server -n kube-system
minikube addons disable metrics-server
minikube addons enable metrics-server
Persistent Volume Claims Stuck in Pending
Problem: PVC cannot bind to PV
# Solution 1: Check available PVs
kubectl get pv
kubectl describe pv
# Solution 2: Verify storage class exists
kubectl get storageclass
kubectl describe storageclass standard
# Solution 3: Check PVC details
kubectl describe pvc <pvc-name>
# Solution 4: Manual PV creation
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: manual-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /tmp/data
EOF
# Solution 5: Update PVC to match PV
kubectl patch pvc <pvc-name> -p '{"spec":{"volumeName":"<pv-name>"}}'
Resource Allocation Issues
Problem: Pods pending due to insufficient resources
# Solution 1: Check node resources
kubectl describe node minikube
kubectl top nodes
# Solution 2: Increase Minikube resources
minikube stop
minikube config set cpus 6
minikube config set memory 8192
minikube start
# Solution 3: Check pod requests/limits
kubectl get pods -o json | grep -A 5 "requests\|limits"
# Solution 4: Reduce pod resource requests
kubectl patch deployment <deployment-name> --type='json' \
-p='[{"op": "replace", "path": "/spec/template/spec/containers/0/resources/requests/cpu", "value":"100m"}]'
# Solution 5: Delete non-essential pods
kubectl delete pod <pod-name>
kubectl delete deployment <deployment-name>
Image Pull Errors
Problem: Pods fail with ImagePullBackOff
# Solution 1: Use local images with registry addon
minikube addons enable registry
docker tag myimage:latest localhost:5000/myimage:latest
docker push localhost:5000/myimage:latest
# Solution 2: Load image directly into Minikube
docker build -t myimage:latest .
minikube image load myimage:latest
# Solution 3: Use imagePullPolicy: IfNotPresent
kubectl set image deployment/<deployment> \
<container>=<image>
# Solution 4: Check image availability
minikube ssh docker images
docker images | grep myimage
# Solution 5: Configure registry credentials
kubectl create secret docker-registry regcred \
--docker-server=<registry> \
--docker-username=<user> \
--docker-password=<password>
Mount Issues
Problem: Mounted directories not accessible in pods
# Solution 1: Start mount before deployment
minikube mount /host/path:/mnt/host &
# Solution 2: Verify mount point
minikube ssh mount | grep /mnt/host
# Solution 3: Check pod volume mounts
kubectl describe pod <pod-name>
# Solution 4: Verify hostPath permissions
minikube ssh ls -la /mnt/host
minikube ssh sudo chmod 777 /mnt/host
# Solution 5: Use different mount point
minikube mount /host/path:/mnt/different --uid=0 --gid=0
Related Topics
- Kubernetes Fundamentals - Core concepts, architecture, and essential API resources for Minikube applications
- kubectl - Command-line tool mastery for interacting with Minikube clusters
- Docker/Podman - Container runtime options and image management for Minikube
- Helm - Package manager for deploying complex applications on Minikube
- Kubernetes Networking - Service types, ingress, and DNS configuration for local testing
- Persistent Volumes & StorageClasses - Advanced storage patterns and best practices for development environments