On this page
In the previous lesson you set up kubeconfig, so kubectl knows which cluster to talk to and who you are. Now it is time to use that connection and look around.
Think of kubectl as the remote control for your cluster. Every button you press becomes a request to the Kubernetes API server, and the API server sends back the answer.
In this lesson you will check that your cluster is reachable and healthy, find out which machines it is made of, and read the details of a single node. By the end you will feel at home in a live cluster from the command line.
What you will learn
- What
kubectlis and how it talks to your cluster - Which control plane components keep a cluster running, and how control-plane nodes differ from worker nodes
- How to check versions, and why kubectl must stay close to the cluster version
- How to list and inspect nodes, including the requests and limits of the Pods running on them
What is kubectl?
kubectl (say "kube-control" or "kube-c-t-l") is the official command-line tool for the Kubernetes API. With it you can:
- Create, update and delete Kubernetes objects such as
Pod,DeploymentandService - Inspect the current state of the cluster
- View logs and debug running workloads
kubectl never changes the machines directly. It sends HTTPS requests to the API server, and the cluster does the rest.
Almost everything you do with Kubernetes day to day goes through kubectl.
What a cluster is made of
The control plane
The control plane is the brain of the cluster. Every request enters through the API server. Behind it, three components do the work you will check in this lesson.
| Component | Responsibility |
|---|---|
| kube-apiserver | The front door. kubectl and every other component talk to it |
| scheduler | Decides which node each new Pod should run on |
| controller-manager | Runs controllers that keep the cluster in the desired state, for example making sure a Deployment has the right number of healthy replicas |
| etcd | The cluster's database. It stores every API object and the cluster state |
Control-plane nodes and worker nodes
A cluster has two kinds of nodes:
- Control-plane nodes run the API server, scheduler, controller-manager and etcd. They manage the cluster itself. Kubernetes keeps your workloads off them to protect cluster stability.
- Worker nodes are the machines where your application containers actually run.
Think of control-plane nodes as the management office and worker nodes as the factory floor.
kubectl get nodes shows only worker nodes. On local clusters such as kind or minikube, a single node often plays both roles.Requests and limits
Each container in a Pod can declare two resource values for CPU and memory. You will see them for every Pod when you describe a node later in this lesson.
| Setting | Meaning |
|---|---|
| Request | The minimum the container is guaranteed. The scheduler only places a Pod on a node that still has this much unreserved capacity. |
| Limit | The maximum the container is allowed to use. Above the CPU limit it is slowed down (throttled); above the memory limit it is killed (OOMKilled). |
If a limit is higher than its request, the extra resources are best effort. They are available when the node has spare capacity, but never guaranteed.
This lets Kubernetes pack workloads tightly onto nodes without reserving the worst case for everyone.
Versions and the version skew policy
Kubernetes uses semantic versioning: MAJOR.MINOR.PATCH, for example 1.31.4. A new minor version comes out about three times a year.
Your local kubectl and the cluster's API server do not have to match exactly. kubectl is supported within one minor version of the API server, older or newer. With a v1.31 API server, kubectl v1.30, v1.31 and v1.32 are all supported.
Commands for exploring a cluster
Check the kubectl and cluster versions
kubectl version prints the version of your local client and of the remote API server:
Expected output (your numbers will differ):
The Kustomize Version line is the Kustomize engine built into kubectl. If the Server Version line is missing and an error appears instead, kubectl could not reach the cluster.
To check only your local tool, without contacting any cluster, add --client:
Check the control plane components
kubectl get componentstatuses (short name cs) gives a quick health report of the scheduler, the controller-manager and etcd:
Expected output:
If every component shows Healthy, the control plane is in good shape.
Unhealthy even when all is well, because the API server cannot reach them directly.The modern check asks the API server for its own readiness report:
Expected output (shortened):
Every line should end in ok, and the last line should say readyz check passed. The sibling endpoint /livez?verbose reports whether the API server is alive.
List the nodes
kubectl get nodes lists every node with its status, role, age and kubelet version:
Expected output:
A node whose ROLES column says control-plane is a control-plane node. <none> means a worker node. Every node should be Ready.
Clusters older than Kubernetes 1.24 also showed a master role here. That label has been removed, so modern clusters show only control-plane.
Add more columns with -o wide
-o wide adds the node IP addresses, the operating system, the kernel and the container runtime:
Expected output:
Describe a single node
kubectl describe gives a deep, human-readable view of one object. For a node it shows labels, health conditions, hardware capacity, the Pods running on it and how much of the node they have reserved.
kubectl accepts node, nodes or the short name no. For example:
Expected output (shortened):
The output is divided into sections. These are the ones you will read most often:
| Section | What it tells you |
|---|---|
| Labels | Metadata tags on the node, such as the OS, CPU architecture and hostname |
| Conditions | Health checks: memory pressure, disk pressure, PID pressure and readiness |
| Capacity / Allocatable | Total CPU, memory and Pod slots, and how much of that is left for Pods after system reservations |
| System Info | Kernel version, OS image, container runtime and kubelet version |
| Non-terminated Pods | Pods running on this node, with their CPU and memory requests and limits |
| Allocated resources | The sum of all requests and limits on the node, as a percentage of what is allocatable |
Limits in Allocated resources can add up to more than 100%. That is normal: it means the node is overcommitted, relying on Pods not all hitting their limits at the same time.
Hands-on: run a full cluster health check
Now combine the commands into a routine you can run on any cluster. Work through the steps in order; each one builds on the last.
Step 1 — Confirm kubectl can reach the cluster
You should see both Client Version and Server Version. If only the client version appears, followed by an error such as The connection to the server ... was refused, kubectl cannot reach the cluster.
In that case run kubectl config current-context and make sure you are on the right context, as shown in the kubeconfig lesson.
Step 2 — Check the control plane
All three components (scheduler, controller-manager and etcd-0) should report Healthy, and the readiness report should end with readyz check passed.
Step 3 — List the nodes and confirm they are Ready
Every node should show Ready. A node that shows NotReady needs investigation, and the next step is where you start.
Step 4 — Inspect a worker node
Look at the Conditions section. MemoryPressure, DiskPressure and PIDPressure should be False (no problems), and Ready should be True.
Step 5 — Check what is running on the node
In the same output, scroll to Non-terminated Pods. You will see system Pods such as coredns (cluster DNS), kube-proxy and a network plugin such as kube-flannel.
These are the cluster's own infrastructure components. They run in system namespaces such as kube-system. Then read Allocated resources to see how much of the node's CPU and memory is already reserved by requests.
Step 6 — List the system Pods
The -n flag picks a namespace; the next lesson covers namespaces properly. List everything in kube-system:
Expected output on a kubeadm cluster (shortened):
On clusters you build yourself, the control plane runs as Pods too: kube-apiserver, kube-scheduler, kube-controller-manager and etcd. All of them should be Running. On a managed cluster you will only see the add-ons, such as coredns and kube-proxy.
Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
Only Client Version is printed, then a connection error | Wrong context, the cluster is stopped, or a network or VPN problem | Run kubectl config current-context, start your local cluster (for example minikube start) or reconnect |
componentstatuses shows Unhealthy on a managed cluster | The API server cannot reach those components directly; this is common and often harmless | Use kubectl get --raw='/readyz?verbose' instead |
A node shows NotReady | The kubelet stopped, the network plugin failed, or the node ran out of resources | Run kubectl describe nodes <name> and read Conditions and Events |
kubectl version prints a warning about the supported minor version skew | kubectl is more than one minor version away from the API server | Install a kubectl version that matches the cluster |
Summary
kubectl is your remote control for the cluster: every command is a request to the API server. A handful of read-only commands tells you whether a cluster is reachable, healthy and ready for work.
kubectl versionconfirms connectivity. Keep kubectl within one minor version of the API server.kubectl get componentstatusesis a quick (deprecated) control plane check;kubectl get --raw='/readyz?verbose'is the modern replacement.- The control plane (API server, scheduler, controller-manager and etcd) manages the cluster; worker nodes run your workloads.
kubectl get nodeslists nodes and their status; add-o widefor IPs, OS and container runtime.kubectl describe nodes <name>shows conditions, capacity, the Pods on the node and their resource usage.- A request is guaranteed and a limit is the maximum. Requests drive scheduling and capacity planning.
Next, you will move from looking at nodes to working with the objects inside the cluster, using the most common kubectl commands.