Installing Kubernetes with Minikube

By Vishvesh Patel ยท DevOps EngineerUpdated September 12, 2026

Set up a local Kubernetes cluster with minikube. Drivers, sizing, add-ons for Ingress and metrics, minikube tunnel, and using its Docker daemon for fast builds.

Minikube runs a local Kubernetes cluster in a VM or a Docker container. Its distinguishing feature is the add-on system: Ingress, metrics-server and a dashboard are one command each, rather than a Helm install and a configuration file.

Install

# macOS
brew install minikube

# Linux
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Windows
winget install Kubernetes.minikube

You also need a driver. Docker is the usual choice and works everywhere.

Start a cluster

minikube start --cpus=4 --memory=8192
๐Ÿ˜„  minikube v1.34.0 on Darwin 15.0
โœจ  Using the docker driver based on existing profile
๐Ÿ„  Done! kubectl is now configured to use "minikube" cluster

Set --cpus and --memory explicitly. The defaults of 2 CPUs and 2GB are enough for a bare cluster and not enough once you add an ingress controller or anything else. Insufficient cpu on a fresh minikube is nearly always this.

kubectl get nodes
minikube status

Other options worth knowing at start time:

minikube start --kubernetes-version=v1.31.2      # match a target cluster
minikube start --driver=docker                   # pick the driver explicitly
minikube start --nodes=3                         # multi-node

A multi-node cluster is worth creating. Single-node hides every scheduling, affinity and anti-affinity problem you will eventually meet in a real cluster.

Add-ons

This is why people choose minikube.

minikube addons list
minikube addons enable ingress
minikube addons enable metrics-server
Add-onWhat it gives you
ingressAn NGINX ingress controller, ready to use
metrics-serverMakes kubectl top and the HPA work
dashboardThe web UI
registryA local image registry inside the cluster
csi-hostpath-driverDynamic PersistentVolume provisioning

metrics-server is the one to enable immediately, without it kubectl top fails and every HorizontalPodAutoscaler reports <unknown>.

minikube dashboard

Reaching your services

A local cluster has no cloud load balancer, so there are three ways in.

NodePort, with a helper to give you the URL:

minikube service payments-api --url
http://192.168.49.2:31847

LoadBalancer, which needs minikube tunnel running in a separate terminal:

minikube tunnel

Without it, LoadBalancer Services sit at <pending> forever. The tunnel creates a route to the cluster and assigns them addresses, and it usually asks for a password because it modifies network routes.

Ingress, once the add-on is enabled:

minikube ip                    # e.g. 192.168.49.2
# Add to /etc/hosts
192.168.49.2  payments.local

Or skip all of it for quick checks:

kubectl port-forward service/payments-api 8080:80

Building images without a registry

Minikube's cluster cannot see your host's Docker images. Rather than pushing to a registry, point your shell at minikube's own Docker daemon:

eval $(minikube docker-env)
docker build -t myapp:dev .

The image is now built inside the cluster's daemon and immediately available. Set imagePullPolicy: IfNotPresent, with Always, or an unpinned latest tag which defaults to Always, the kubelet tries the registry anyway and fails.

eval $(minikube docker-env -u)     # switch back to your normal Docker

The alternative, if you prefer not to change your shell environment:

minikube image load myapp:dev

Profiles

Several independent clusters, useful for keeping projects apart or testing across Kubernetes versions:

minikube start -p payments --cpus=4 --memory=8192
minikube start -p legacy --kubernetes-version=v1.28.0

minikube profile list
minikube profile payments        # set the default
kubectl config use-context payments

Each profile is a separate VM or container with its own resources. They are not free, so delete the ones you are not using.

Housekeeping

minikube stop                  # keep the cluster, free the resources
minikube start                 # resume it
minikube delete                # remove it entirely
minikube delete --all          # every profile

stop then start is much faster than recreating, and preserves everything you deployed.

When something is genuinely wrong, minikube delete && minikube start is usually quicker than debugging the local cluster itself.

minikube logs                  # cluster component logs
minikube ssh                   # shell onto the node

Quick reference

TaskCommand
Start sized properlyminikube start --cpus=4 --memory=8192
Specific versionminikube start --kubernetes-version=v1.31.2
Multi-nodeminikube start --nodes=3
Enable an add-onminikube addons enable ingress
Service URLminikube service <name> --url
Make LoadBalancer workminikube tunnel
Node IPminikube ip
Build into the clustereval $(minikube docker-env)
Load a built imageminikube image load <image>
New profileminikube start -p <name>
Stop / deleteminikube stop / minikube delete

Key takeaways

  • Always pass --cpus and --memory. The 2GB default causes scheduling failures as soon as you add anything.
  • Add-ons are the reason to pick minikube: ingress and metrics-server in one command each.
  • minikube tunnel is what makes LoadBalancer Services work. Without it they stay <pending>.
  • eval $(minikube docker-env) builds straight into the cluster, with imagePullPolicy: IfNotPresent.
  • Create a multi-node cluster. Single-node hides scheduling behaviour you need to understand.
  • Profiles give you independent clusters, each consuming real resources.
  • minikube stop beats delete when you just want the resources back.

Check your understanding

Exercise

A locally built image that will not run

You run eval $(minikube docker-env), build myapp:dev, and deploy it. The Pod still reports ImagePullBackOff. What is the most likely cause?

Exercise

Pods pending on a fresh cluster

Immediately after minikube start with default settings, enabling the ingress add-on leaves Pods Pending with "Insufficient cpu". What is wrong?


Frequently Asked Questions

How much memory and CPU should I give minikube?

At least 4 CPUs and 8GB if your machine allows it, passed as minikube start --cpus=4 --memory=8192. The defaults of 2 CPUs and 2GB are enough for an empty cluster and run out as soon as you enable an ingress controller or deploy a few workloads, producing Insufficient cpu errors that look like a misconfiguration but are simply a lack of capacity. The setting only applies at creation, so changing it means deleting and recreating the cluster.

How do I access a service running in minikube?

For a NodePort Service, minikube service <name> --url prints a working URL. For a LoadBalancer Service you need minikube tunnel running in a separate terminal, otherwise the external IP stays <pending> indefinitely. With the ingress add-on enabled, minikube ip gives the address to point a hosts-file entry at. For a quick check none of that is necessary, kubectl port-forward service/<name> 8080:80 works immediately.

Why is my LoadBalancer Service stuck pending in minikube?

There is no cloud provider to create a load balancer, so nothing ever assigns the external IP. minikube tunnel fills that role by creating a network route into the cluster and assigning addresses to LoadBalancer Services. It has to keep running in its own terminal, and it usually prompts for a password because it modifies system routes.

How do I use a locally built Docker image in minikube?

Run eval $(minikube docker-env) to point your shell at minikube's own Docker daemon, then build normally. The image lands directly in the cluster with no registry involved. Set imagePullPolicy: IfNotPresent on the container, since Always, which is also the default for an unpinned or latest tag, makes the kubelet attempt a registry pull that fails. eval $(minikube docker-env -u) switches your shell back. Alternatively, minikube image load myapp:dev copies an already-built image in.

What is the difference between minikube stop and minikube delete?

stop shuts the cluster down while preserving its state, so minikube start brings everything back including your deployments. Much faster than recreating. delete removes the cluster and all its data permanently. Use stop to reclaim memory and CPU between work sessions, and delete when you want a clean slate or when troubleshooting the local cluster itself has become slower than rebuilding it.

Can I run more than one minikube cluster?

Yes, using profiles: minikube start -p payments and minikube start -p legacy --kubernetes-version=v1.28.0 create independent clusters, each with its own kubectl context. minikube profile list shows them and minikube profile <name> sets the default for minikube commands. Each profile is a separate VM or container consuming real CPU and memory, so delete profiles you are not actively using.

Continue Learning

Explore Related Topics

Try the Tool

Practise this in the browser

Kubernetes Playground

Practise kubectl against a simulated cluster in your browser.

When it breaks

Related Resources