Running Kubernetes Locally
Kubernetes (often shortened to “K8s” — the “8” stands for the eight letters between “K” and “s”) is the system most teams use to run containers across many servers. Learning it on a real production cluster is risky and expensive, so the smart way to start is to run a tiny Kubernetes cluster on your own laptop or Ubuntu server. This page shows you how to install and start a local cluster with minikube or kind, deploy a sample app, open it in your browser, and tear it all down again. Think of it as a safe sandbox where mistakes cost nothing.
Why run Kubernetes locally
A local cluster gives you the exact same kubectl commands and YAML files you’d use in production, but on a throwaway machine. You can break it, reset it, and try again in seconds. This is the best possible way to practice before you touch a shared or paid cluster.
When to use this: learning Kubernetes, testing your app’s manifests (the YAML files that describe your app), or developing locally before deploying. When NOT to use this: running real production traffic. A local cluster lives on one machine, so it has no real high availability and disappears when you delete it.
What you need first
You need a working container runtime — software that actually runs containers. On Ubuntu, Docker is the easiest choice. If you don’t have it yet, install it:
sudo apt update
sudo apt install -y docker.io
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
Log out and back in (or run
newgrp docker) after theusermodline so your user can talk to Docker withoutsudo. Skipping this is the number one reasonminikube startfails for beginners.
Confirm Docker works:
docker run --rm hello-world
Output:
Hello from Docker!
This message shows that your installation appears to be working correctly.
minikube vs kind vs k3s — which one
All three give you a local cluster, but they suit different jobs. Here is the honest comparison.
| Tool | What it is | Best for | Watch out for |
|---|---|---|---|
| minikube | A single, full-featured local cluster, very beginner friendly | First-time learners; needs add-ons like a dashboard or LoadBalancer | Uses more RAM (~2 GB); one cluster at a time by default |
| kind | ”Kubernetes IN Docker” — runs the cluster nodes as Docker containers | CI pipelines and testing; spinning up many small clusters fast | No built-in dashboard; exposing apps needs extra config |
| k3s | A lightweight, production-capable Kubernetes from Rancher/SUSE | Small servers, edge devices, Raspberry Pi, lightweight home labs | Slightly different defaults; more “real cluster” than sandbox |
Recommendation: start with minikube to learn, use kind when you want fast disposable clusters in scripts, and reach for k3s when you want a small but genuinely usable cluster on a real server.
Install and start minikube
Install the kubectl command-line tool (how you talk to any cluster) and minikube:
# kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -m 0755 kubectl /usr/local/bin/kubectl
rm kubectl
# minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
rm minikube-linux-amd64
Start a cluster using Docker as the backend:
minikube start --driver=docker
Output:
😄 minikube v1.34.0 on Ubuntu 24.04
✨ Using the docker driver based on user configuration
🐳 Preparing Kubernetes v1.31.0 on Docker 27.2.0 ...
🏄 Done! kubectl is now configured to use "minikube" cluster
Check that the single node is ready:
kubectl get nodes
Output:
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 45s v1.31.0
Deploy and access a sample app
Now deploy a real app. We’ll run the small kicbase/echo-server web app, expose it, and open it.
kubectl create deployment hello --image=kicbase/echo-server:1.0
kubectl expose deployment hello --type=NodePort --port=8080
A Deployment keeps your app’s containers (called Pods) running. A Service of type NodePort opens a port on the node so you can reach the app. With minikube, the easiest way to open it is:
minikube service hello --url
Output:
http://192.168.49.2:31790
Test it:
curl http://192.168.49.2:31790
Output:
Request served by hello-7d9c...
HTTP/1.1 GET /
Host: 192.168.49.2:31790
You can also open the visual dashboard in a browser:
minikube dashboard
Doing the same with kind
If you prefer kind, install it and create a cluster instead:
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64
sudo install -m 0755 kind /usr/local/bin/kind
rm kind
kind create cluster --name sandbox
To reach an app from your host with kind, you map a port when creating the cluster. Save this config file:
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080
hostPort: 8080
kind create cluster --name sandbox --config kind-config.yaml
Now a Service with nodePort: 30080 is reachable at http://localhost:8080 on your machine.
Cleaning up
A local cluster uses RAM and disk, so stop or delete it when you’re done.
# minikube
minikube stop # pause, keep the cluster
minikube delete # remove it completely
# kind
kind delete cluster --name sandbox
Deleting and recreating is normal and cheap here. If your cluster gets into a weird state, don’t debug for hours — just
deleteandstartagain. That freedom is the whole point of a local sandbox.
Best Practices
- Start with minikube while learning; switch to kind only when you need fast, scriptable, throwaway clusters.
- Always use the Docker driver on Ubuntu unless you have a specific reason not to — it avoids virtual machine setup pain.
- Practice writing real YAML manifests and applying them with
kubectl apply -f, not justkubectl create, so your skills transfer to production. - Give the cluster enough resources (
minikube start --memory=4096 --cpus=2) if Pods keep getting evicted. - Treat the local cluster as disposable:
deleteand rebuild instead of fighting a broken state. - Never expose a local sandbox cluster’s API to the public internet; it is not hardened for that.
- Match the local Kubernetes version (
--kubernetes-version) to your production cluster so behavior lines up.