Right, so you’ve just thrown a bunch of YAML at kubeadm or clicked a few buttons on your cloud provider’s console. The install script finished with a triumphant “Happy hacking!” and you’re left staring at a blank terminal. Did it work? Is anything actually running? Let’s not guess. Let’s ask the cluster itself, using the primary tool you’ll have a love-hate relationship with: kubectl.

First things first, let’s get the big picture. Run this:

kubectl cluster-info

This is the equivalent of asking your cluster, “You alive in there?” A healthy response looks something like this:

Kubernetes control plane is running at https://172.18.0.3:6443
CoreDNS is running at https://172.18.0.3:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

See what it did there? It told you the address of the boss, the control plane (the API server), and it was even kind enough to tell you that CoreDNS, the cluster’s phone book, is up and running. This command is your first-line sanity check. If this comes back with an error, especially a connection error, your kubeconfig file (usually at ~/.kube/config) is probably pointing at the wrong place or doesn’t have the right credentials. It’s the most common “it’s not working” moment, and it’s almost always a local configuration issue, not the cluster being down.

What cluster-info Doesn’t Tell You

Here’s the catch: cluster-info is a bit of a politician. It gives you a nice, high-level answer, but it’s only checking on one specific thing: can it talk to the API server? And even then, it’s a superficial check. The API server could be up but having a catastrophic existential crisis, and this command might still report it as “running.” It’s a good start, but it’s not the whole story. That’s why we need to get our hands dirty.

The Ground Truth: kubectl get nodes

If cluster-info is the glossy brochure, kubectl get nodes is the unvarnished, on-the-ground report from the trenches. Run it:

kubectl get nodes

You want to see a beautiful sight: a list of all your nodes, each with a status of Ready.

NAME       STATUS   ROLES           AGE     VERSION
control-plane   Ready    control-plane   5m27s   v1.27.4
node-1     Ready    <none>          4m58s   v1.27.4
node-2     Ready    <none>          4m57s   v1.27.4

The ROLES column shows control-plane (or historically master) for the node running the API server, scheduler, and controller manager, and <none> for worker nodes. The most important column is STATUS. If it doesn’t say Ready, you’ve got a problem.

When Things Go Sideways

Let’s talk about what happens when it’s not ready, because it will happen. The -o wide flag is your best friend for troubleshooting. It adds crucial intel.

kubectl get nodes -o wide

This will show you the node’s internal IP, the OS image it’s running, and the exact version of the container runtime (like containerd or CRI-O). If a node is NotReady, the first thing to do is ask Kubernetes why it’s throwing a tantrum. Use the describe command to get the full drama:

kubectl describe node node-1

Scroll down to the Conditions section. This is where the node’s various components file their status reports. You’re looking for Ready status to be False and reading the Message right next to it. It might tell you:

  • Kubelet stopped posting node status.: The kubelet (the primary node agent) on that machine has probably crashed or can’t talk to the API server. Time to SSH into that node and run journalctl -u kubelet to see its logs.
  • Container runtime is down: Well, there’s your problem. Docker or containerd isn’t running on the node.
  • Network plugin is not ready: Your CNI (Container Network Interface) plugin like Calico or Flannel hasn’t been installed correctly or is failing. Without this, pods can’t talk to each other, and the node will rightly be marked as not ready.

Best Practices and the Obvious Joke

Always, and I mean always, run get nodes after setting up a cluster. It’s the bare minimum. The joke here is that every single tutorial, including this one, has to tell you to do this because everyone is so excited to run a deployment that they forget to see if the foundation is poured. Don’t be that person.

A pro tip: get used to using the -o wide flag. The extra information is almost always worth the screen real estate. And if you’re automating anything, the -o json or -o yaml flags will let you pipe the output into other tools like jq to parse it programmatically. For now, just make sure all your nodes are Ready. Once they are, you’ve officially got a working cluster. Now the real fun begins.