Installing minikube + kubectl, Your First Cluster

K
Kai··4 min read

Enough theory — in this article we stand up a cluster of our own. Two tools to install: kubectl (the client that issues commands) and minikube (stands up the cluster). Once that's done, you have a real Kubernetes to play with.

What you need first

minikube needs a "driver" to stand up the cluster — the most common and lightest is Docker (the cluster runs inside a Docker container). If you followed the Docker series, you already have it. Besides Docker, minikube also supports VM drivers (HyperKit, VirtualBox, QEMU...), but Docker is the leanest option for learning.

Install kubectl and minikube

On macOS, use Homebrew:

brew install kubectl minikube

(Linux/Windows: see the official installation page at kubernetes.io — there are packages for apt/dnf, or download the binary directly.)

Check that they installed:

minikube version
kubectl version --client
minikube version: v1.38.1
Client Version: v1.35.2

kubectl is a client: it doesn't do anything on its own, it only sends commands to the cluster's API server (remember Article 1 — everything goes through the API server). So once kubectl is installed but you don't have a cluster yet, it has no one to talk to.

Start the cluster

minikube start --driver=docker

The first run takes a while because minikube pulls the base image. Trimmed output:

* minikube v1.38.1 on Darwin
* Using the docker driver based on user configuration
* Starting "minikube" primary control-plane node in "minikube" cluster
* Pulling base image ...
* Configuring bridge CNI (Container Networking Interface) ...
* Verifying Kubernetes components...
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

The last line matters: minikube configures kubectl for you to point at the cluster it just created. You don't have to declare anything else.

Check the cluster is alive:

minikube status
kubectl get nodes
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running

NAME       STATUS   ROLES           AGE     VERSION
minikube   Ready    control-plane   2m53s   v1.35.1

One node named minikube, status Ready, role control-plane. As mentioned in Article 1: minikube is single-node, so that node plays both roles.

kubeconfig and context: how kubectl knows which cluster to talk to

How does kubectl know where to send commands? Through the kubeconfig file (default ~/.kube/config). This file holds the list of clusters, the authentication info, and the contexts — each context is a triple (cluster + user + namespace). minikube start already added a context named minikube and set it as the default.

kubectl config current-context
minikube

Here's a detail that trips people up in practice: if your machine has ever connected to another cluster (say an EKS at work), kubectl might be pointing at the wrong cluster. Always check current-context before running commands, and switch with:

kubectl config use-context minikube

A small tip: the kubectl command is fairly long, so many people set an alias k=kubectl. In this series I write out the full kubectl for clarity.

First pod: "hello world"

Enough ceremony — let's run something. The kubectl run command quickly creates a pod (we'll understand pods properly in Article 3):

kubectl run hello-nginx --image=nginx:alpine
pod/hello-nginx created

Look at it:

kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE
hello-nginx   1/1     Running   0          1s    10.244.0.4   minikube   <none>

For the first few seconds you might see STATUS as ContainerCreating (pulling the image, building the container) before it switches to Running. The READY 1/1 column means 1 of 1 container in the pod is ready, and the pod was assigned the internal IP 10.244.0.4 on node minikube. The whole chain from Article 1 just happened: apiserver writes to etcd → scheduler picks a node → kubelet starts the container.

Clean up the test pod:

kubectl delete pod hello-nginx
pod "hello-nginx" deleted from default namespace

A few handy minikube commands

minikube dashboard      # open the web UI for managing the cluster (Article 13)
minikube addons list    # list addons (ingress, metrics-server...) — enable as needed
minikube ip             # the cluster's IP
minikube stop           # stop the cluster (keeps data, restarts fast)
minikube delete         # wipe the cluster completely

stop differs from delete: stop only shuts down the VM/container (restart with start very quickly, keeping everything you created); delete removes it all. When you're done with the whole series, a single minikube delete leaves your machine as clean as if nothing had been there.

Wrap-up

Install kubectl (the command client) and minikube (stands up the cluster), then minikube start --driver=docker gives you a real single-node Kubernetes cluster — minikube configures kubectl to point at it for you. kubectl routes commands through the kubeconfig/context, so always check current-context (especially when the machine has multiple clusters). kubectl run quickly creates your first pod, kubectl get pods to view it, kubectl delete to clean up. minikube stop pauses it, minikube delete wipes it clean.

We just ran a pod without really understanding what it is. Article 3 dissects the Pod — the smallest unit, and the concept you'll meet every day in Kubernetes.