| Tested on | Rocky Linux 10.2 (Red Quartz) workstation |
|---|---|
| Package | kubectl 1.36.3kubeadm 1.36.3kubelet 1.36.3containerd 2.2.5 |
| Applies to | Any host with kubectl configured; any Kubernetes cluster |
| Cert prep | CKA · CKAD · CKS |
| Lab environment | Multi-node kubeadm cluster with containerd — install Kubernetes with kubeadm |
| Privilege | kubectl identity with permission to query the API server, list Nodes, and list Pods in kube-system; root or sudo on control-plane nodes for kubeadm upgrade plan and static manifest inspection |
| Scope | Identify API-server, kubectl client, kubelet, kubeadm, container runtime, and control-plane component versions; read version skew rules and common misreads. Does not cover full cluster upgrades, managed-provider CLIs, or cluster-health troubleshooting. |
When someone asks for the Kubernetes version, they usually mean the API-server release your current kubeconfig context reaches. The kubectl binary on your laptop, the kubelet on each node, kubeadm on a control-plane host, and the container runtime are separate values that can legitimately differ during or after an upgrade.
Quick commands to check Kubernetes versions
| What you need | Command |
|---|---|
| kubectl client and API-server versions | kubectl version |
| kubectl client only | kubectl version --client |
| Versions as JSON | kubectl version -o json |
| Versions as YAML | kubectl version -o yaml |
| API-server version only | Parse .serverVersion.gitVersion from JSON |
| kubelet version on every node | kubectl get nodes |
| Kubelet and runtime details | Query .status.nodeInfo |
| Local kubelet binary | kubelet --version |
| Local kubeadm binary | kubeadm version |
| kubeadm upgrade compatibility | sudo kubeadm upgrade plan |
The API-server version is normally what people mean by the Kubernetes cluster version. The kubectl, kubelet, kubeadm, container runtime, and individual control-plane component versions are separate values.
Understand which Kubernetes version you are checking
| Version | What it represents |
|---|---|
| Server version | kube-apiserver reached through the current kubeconfig context |
| Client version | Local kubectl binary |
| Node version | Kubelet version reported by each Node |
| kubeadm version | Local cluster-bootstrap and upgrade tool |
| Runtime version | containerd, CRI-O, or another CRI runtime |
| Component image version | API server, scheduler, controller manager, etcd, CoreDNS, or kube-proxy |
| API versions | Supported API groups such as apps/v1; not the Kubernetes release |
Kubernetes releases use semantic-style notation:
v1.36.3
│ │ └── patch
│ └───── minor
└─────── majorA cluster does not necessarily run one identical version across every binary. During a rolling upgrade, control-plane images, kubelets, and your workstation kubectl can sit on different supported minors until you finish the sequence. For how those pieces fit together, see Kubernetes architecture.
Check the cluster and kubectl versions
Start with the command that prints both sides of the conversation between your workstation and the API server.
kubectl versionSample output:
Client Version: v1.36.3
Kustomize Version: v5.8.1
Server Version: v1.36.3The three lines answer different questions:
- Client Version is the local
kubectlbinary. - Kustomize Version is the Kustomize library bundled with kubectl.
- Server Version is the API server selected by the current kubeconfig context.
In an HA cluster during a rolling upgrade, Server Version identifies the API-server instance that answered the request. Other API-server instances may temporarily run another supported version. Inspect every kube-apiserver mirror Pod when you need the complete control-plane inventory.
kubectl get pods -n kube-system -l component=kube-apiserver -o custom-columns='NODE:.spec.nodeName,POD:.metadata.name,IMAGE:.spec.containers[0].image'Sample output:
NODE POD IMAGE
k8s-cp kube-apiserver-k8s-cp registry.k8s.io/kube-apiserver:v1.36.3kubeadm runs API server components as static Pods whose mirror Pods are visible through the API server.
Before you interpret Server Version, confirm which cluster you are talking to.
kubectl config current-contextSample output:
kubernetes-admin@kuberneteskubectl cluster-infoSample output:
Kubernetes control plane is running at https://192.168.56.108:6443
CoreDNS is running at https://192.168.56.108:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxyThe context name and control-plane URL should match the cluster you intend to inspect. A mismatched kubeconfig is a common reason operators report the wrong release—confirm context, credentials, and server URL with install kubectl and configure kubeconfig if you are still wiring workstation access.
Check only the kubectl client version
When you only need the workstation binary and do not have API-server access, omit the server query.
kubectl version --clientSample output:
Client Version: v1.36.3
Kustomize Version: v5.8.1This command succeeds without a reachable cluster.
Get JSON or YAML output
Machine-readable output is easier to script than the default text lines.
kubectl version -o jsonThe JSON object includes clientVersion, optional kustomizeVersion, and serverVersion when the API server responds. Use the same flag with yaml when your tooling prefers YAML.
kubectl version -o yamlSample output (trimmed):
clientVersion:
gitVersion: v1.36.3
major: "1"
minor: "36"
kustomizeVersion: v5.8.1
serverVersion:
gitVersion: v1.36.3
major: "1"
minor: "36"Parse JSON in scripts instead of grepping the human-readable lines.
Print only the server version
Pipe JSON to a parser and read .serverVersion.gitVersion.
kubectl version -o json | python3 -c "import sys,json; print(json.load(sys.stdin)['serverVersion']['gitVersion'])"Sample output:
v1.36.3On hosts with jq installed, the same path is:
kubectl version -o json | jq -r '.serverVersion.gitVersion'For the client only:
kubectl version --client -o json | python3 -c "import sys,json; print(json.load(sys.stdin)['clientVersion']['gitVersion'])"Sample output:
v1.36.3You can also query the version endpoint directly when you already have authenticated API access:
kubectl get --raw='/version' | python3 -c "import sys,json; print(json.load(sys.stdin)['gitVersion'])"Sample output:
v1.36.3That path returns the same API-server release as Server Version in kubectl version; use it when a script already speaks to the API and you want one small JSON document.
Why kubectl version --short no longer works
Older kubectl releases supported or deprecated --short. Current kubectl no longer lists that flag.
kubectl version --shortSample output:
error: unknown flag: --short
See 'kubectl version --help' for usage.Use the default output, -o json, or -o yaml instead. Do not rely on --short=true examples from older blog posts.
Check kubelet and runtime versions on every node
Listing Nodes and kube-system Pods requires cluster-scoped RBAC beyond a configured kubeconfig. Confirm your identity can perform the reads before you rely on the output.
kubectl auth can-i list nodesSample output:
yeskubectl auth can-i list pods -n kube-systemSample output:
yeskubectl auth can-i is the supported command for checking whether the current identity may perform an API action.
The VERSION column in a node list shows kubelet releases, not the API-server or your kubectl binary.
kubectl get nodes -o wideSample output:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-cp Ready control-plane 4d17h v1.36.3 192.168.56.108 <none> Rocky Linux 10.2 (Red Quartz) 6.12.0-211.16.1.el10_2.0.1.x86_64 containerd://2.2.5
worker01 NotReady <none> 4d16h v1.36.3 192.168.56.109 <none> Rocky Linux 10.2 (Red Quartz) 6.12.0-211.34.1.el10_2.x86_64 containerd://2.2.5VERSION is the kubelet version each node reports. CONTAINER-RUNTIME shows the CRI implementation and its release. The Node VERSION and runtime fields come from .status.nodeInfo, which the kubelet publishes to the API server. Node readiness is separate from version reporting. A NotReady node can still display its last reported kubelet and runtime versions, but those values may be stale. Check the binaries directly on that node when you need to confirm its current installed versions.
For a concise inventory across the fleet, project status.nodeInfo fields:
kubectl get nodes -o custom-columns='NAME:.metadata.name,ARCH:.status.nodeInfo.architecture,KUBELET:.status.nodeInfo.kubeletVersion,RUNTIME:.status.nodeInfo.containerRuntimeVersion,OS:.status.nodeInfo.osImage'Sample output:
NAME ARCH KUBELET RUNTIME OS
k8s-cp amd64 v1.36.3 containerd://2.2.5 Rocky Linux 10.2 (Red Quartz)
worker01 amd64 v1.36.3 containerd://2.2.5 Rocky Linux 10.2 (Red Quartz)Versions can differ across nodes for several normal reasons:
- Nodes are being upgraded sequentially.
- A worker upgrade was postponed.
- A new node image ships a different patch level.
- The difference may still fall within the supported skew policy.
- Persistent unexpected gaps should be investigated before the next control-plane upgrade.
For cordon, drain, and replacement workflows that touch node versions, see Kubernetes node lifecycle.
Check one node in detail
Replace k8s-cp with the node name you need.
kubectl get node k8s-cp -o jsonpath='{.status.nodeInfo.kubeletVersion}{"\n"}'Sample output:
v1.36.3kubectl get node k8s-cp -o jsonpath='{.status.nodeInfo.containerRuntimeVersion}{"\n"}'Sample output:
containerd://2.2.5Check the local kubelet binary
On the node itself, the kubelet binary reports what is installed on that host.
kubelet --versionSample output:
Kubernetes v1.36.3That value describes the local kubelet package only. It does not identify the remote API-server release or prove every other node matches.
Check kubeadm and control-plane component versions
Check the local kubeadm version
kubeadm is a node-local bootstrap and upgrade tool. Its version can differ from the running control plane, especially before or during an upgrade.
kubeadm versionSample output:
kubeadm version: &version.Info{Major:"1", Minor:"36", GitVersion:"v1.36.3", GitCommit:"0f29094e5b73085e3802ecc1298ecae13866bfe6", GitTreeState:"clean", BuildDate:"2026-07-22T18:09:52Z", GoVersion:"go1.26.5", Compiler:"gc", Platform:"linux/amd64"}Read GitVersion for the release string.
Use kubeadm upgrade plan only for upgrade planning
kubeadm upgrade plan checks upgrade readiness and available targets. Run it on a kubeadm control-plane node with access to admin.conf when you are assessing an upgrade — not when you only need today's API-server version.
sudo kubeadm upgrade planSample output (trimmed):
[upgrade/versions] Cluster version: 1.36.3
[upgrade/versions] kubeadm version: v1.36.3
[upgrade/versions] Target version: v1.36.3
[upgrade/versions] Latest version in the v1.36 series: v1.36.3The command validates configuration, runs health checks, and may list component targets when a newer patch or minor is available. It does not apply an upgrade. For the full sequencing workflow, follow Upgrade a Kubernetes cluster with kubeadm.
Inspect kubeadm control-plane images
On a kubeadm cluster, static Pods carry image tags that identify component releases.
kubectl get pods -n kube-system -l tier=control-plane -o custom-columns='POD:.metadata.name,IMAGE:.spec.containers[0].image'Sample output:
POD IMAGE
etcd-k8s-cp registry.k8s.io/etcd:3.6.8-0
kube-apiserver-k8s-cp registry.k8s.io/kube-apiserver:v1.36.3
kube-controller-manager-k8s-cp registry.k8s.io/kube-controller-manager:v1.36.3
kube-scheduler-k8s-cp registry.k8s.io/kube-scheduler:v1.36.3You can also read the manifest files on the control-plane node.
sudo grep -H 'image:' /etc/kubernetes/manifests/*.yamlSample output:
/etc/kubernetes/manifests/etcd.yaml: image: registry.k8s.io/etcd:3.6.8-0
/etc/kubernetes/manifests/kube-apiserver.yaml: image: registry.k8s.io/kube-apiserver:v1.36.3
/etc/kubernetes/manifests/kube-controller-manager.yaml: image: registry.k8s.io/kube-controller-manager:v1.36.3
/etc/kubernetes/manifests/kube-scheduler.yaml: image: registry.k8s.io/kube-scheduler:v1.36.3Image tags usually identify the Kubernetes component release. etcd, CoreDNS, and the container runtime follow their own version lines. Managed Kubernetes services may hide control-plane Pods and manifests — use the provider's control-plane version command when you cannot list kube-system static Pods.
Check whether the versions are compatible
Kubernetes publishes a version skew policy. The table below is a practical summary for day-to-day checks; confirm against the current policy before you plan production upgrades.
| Component | Supported relationship to kube-apiserver |
|---|---|
| kubectl | One minor older or newer |
| kubelet | Must not be newer; for modern releases, up to three minors older |
| kube-proxy | Must not be newer; generally up to three minors older |
| Scheduler and controller manager | Must not be newer; normally same minor or one older |
| HA API servers | Oldest and newest within one minor |
HA control planes with mixed API-server versions narrow the supported ranges for the other components.
Example for API server v1.36:
API server: v1.36
kubectl: v1.35, v1.36 or v1.37
kubelet: v1.33 through v1.36When skew looks wrong, finish or roll back an in-progress upgrade before you raise the control plane again.
Common questions and version-check problems
| Symptom or question | Likely cause | What to do |
|---|---|---|
| Which value is the actual cluster version? | Confusion between kubectl, kubelet, and API-server strings | Use Server Version from kubectl version or gitVersion from /version |
| Client Version and Server Version differ | Separate binaries with supported skew | Compare minors against the skew table; upgrade kubectl or the control plane as needed |
kubectl version shows only the client |
No server response | Check current context, kubeconfig path, API-server reachability, authentication, and TLS errors |
kubectl get nodes shows another version |
VERSION column is kubelet, not API server | Run kubectl version for the control-plane release |
| Worker nodes show different versions | Rolling upgrade in progress or delayed worker pass | Compare against skew policy; align workers before the next control-plane jump |
kubectl api-versions looks like a release number |
API group versions are not the cluster release | Use kubectl version or node kubeletVersion instead; see Kubernetes API resources |
| Need cluster version without kubectl | No API client available | Use an authenticated provider CLI or admin UI; local kubelet --version and kubeadm version do not reveal the remote API server |
Used kubeadm upgrade plan for a quick check |
Heavy upgrade preflight, not a lightweight query | Prefer kubectl version for API-server release; reserve kubeadm upgrade plan for upgrade assessment |
| Version command succeeds but workloads fail | Version check only proves the API server answered | Inspect node readiness and component health separately; for NotReady nodes see Fix Kubernetes node NotReady |
| Successful check after context switch | kubeconfig pointed at a different cluster | Re-run kubectl config current-context and kubectl cluster-info before recording the version |
Recommended final command set
Copy the block below when you want the usual checks on one screen.
# Client and server
kubectl version
# Client only
kubectl version --client
# Server only
kubectl version -o json | python3 -c "import sys,json; print(json.load(sys.stdin)['serverVersion']['gitVersion'])"
# Current target cluster
kubectl config current-context
# Kubelet and runtime versions on every node
kubectl get nodes -o custom-columns='NAME:.metadata.name,ARCH:.status.nodeInfo.architecture,KUBELET:.status.nodeInfo.kubeletVersion,RUNTIME:.status.nodeInfo.containerRuntimeVersion,OS:.status.nodeInfo.osImage'
# Local tools
kubelet --version
kubeadm version
# Upgrade assessment on a kubeadm control-plane node
sudo kubeadm upgrade planReferences
Summary
Checking Kubernetes versions starts with kubectl version against the correct kubeconfig context. Server Version is the API-server release people usually mean when they ask for the cluster version; Client Version is your workstation kubectl; and the VERSION column from kubectl get nodes is kubelet on each node, not kubectl or the control plane.
JSON and YAML output keep scripting honest — parse .serverVersion.gitVersion or call /version instead of reviving deprecated --short flags from older posts. Node inventories from status.nodeInfo add container runtime and OS image alongside kubelet, which matters when you are mid-upgrade and patches no longer line up across the fleet.
kubeadm and static control-plane manifests answer bootstrap-tool and component-image questions that kubectl alone does not cover, but kubeadm upgrade plan belongs in upgrade planning, not in everyday version lookups. When numbers disagree, compare them to the current skew policy before you schedule the next control-plane bump, and follow the kubeadm upgrade workflow when you are ready to change releases rather than only read them.

