skip to content

Can a kubeadm-built Kubernetes cluster on v1.35 be upgraded straight to v1.37, and if not, why not?

level: juniorimportance: nice to knowfreq 38%

answer

  1. middle number of the version
  2. HA apiservers overlap mid-upgrade
  3. mandatory versus skippable preflight
  4. matching kubeadm binary per hop
  5. patches may be skipped

basics

~10 s

No. A Kubernetes control plane is upgraded one minor version at a time, so v1.35 goes to v1.36 and then to v1.37, and kubeadm upgrade apply rejects a two-minor jump for a released version.

solid answer

~40 s

No. Kubernetes only supports moving the control plane from one minor release to the next, so the path is v1.35 → v1.36 → v1.37, ideally to the latest patch of each. `kubeadm upgrade apply` enforces it: its preflight fails with `kubeadm can upgrade only 1 minor version at a time`, and `--force` cannot bypass that check for a released version. The reasons are structural: during a rolling upgrade old and new `kube-apiserver` instances serve together and may differ by only one minor, API changes are staged across consecutive releases, and upgrade testing covers adjacent pairs. Each hop also needs the kubeadm binary of its target minor. Patch versions inside one minor can be skipped freely.

code

bash · 5 lines
bash
kubeadm version -o short
# v1.37.0
sudo kubeadm upgrade apply v1.37.0
# preflight fails on a v1.35 cluster with:
# Specified version to upgrade to "v1.37.0" is too high; kubeadm can upgrade only 1 minor version at a time

go deeper

for a junior

Recall the rule plainly: control plane moves one minor at a time, patches may be skipped, and kubeadm refuses a two-minor jump.

for a middle

Explain why: HA apiservers overlap during a rolling upgrade and may differ by only one minor, and each hop needs the kubeadm binary of its target minor.

for a senior

Show you can plan a multi-hop catch-up: validate cluster health between hops and know which preflight findings --force can and cannot skip.

for a principal

Treat falling behind as the real risk: every missed minor becomes a full validated hop later, which argues for a steady upgrade cadence.

## The rule in one line Kubernetes versions look like `v1.37.2`: the middle number is the **minor version** (a feature release, roughly three a year) and the last is the **patch version** (bug and security fixes for that minor). An in-place upgrade of a cluster's **control plane** - `kube-apiserver`, `kube-controller-manager`, `kube-scheduler` and, in a kubeadm cluster, the etcd static pod - is supported only from one minor to the next. A cluster on v1.35 therefore reaches v1.37 in two hops: v1.35 → v1.36, then v1.36 → v1.37. Patch versions are different: moving from v1.36.1 to the newest v1.36 patch in one step is normal. ## Why adjacent minors only The rule is not kubeadm being cautious; it follows from how Kubernetes releases are built. - **HA API servers overlap during the upgrade.** With several `kube-apiserver` instances, a rolling upgrade leaves old and new instances serving at the same moment. The version skew policy allows the newest and oldest instance to differ by at most one minor. - **API changes are staged across releases.** A new API version is first served, later becomes preferred, and only after a deprecation period can an old version be removed. Each step assumes the previous minor has already run against the same cluster data. - **Upgrade testing covers adjacent pairs.** The project tests upgrades from the previous minor; a jump from two minors back is an untested path. - **kubeadm is version-bound.** A kubeadm binary knows how to render manifests and migrate its own configuration for its minor; it has no idea how to handle a newer minor than itself. ## What kubeadm enforces `kubeadm upgrade apply` runs a version-policy check in its preflight phase. Some findings are **mandatory** - no flag gets past them. Others are **skippable** and only pass with `--force`. | Situation | kubeadm's verdict | |---|---| | Cluster v1.35, released target v1.37 | Mandatory: `is too high; kubeadm can upgrade only 1 minor version at a time` | | Target minor newer than the kubeadm binary | Mandatory: such an upgrade is not supported | | kubeadm binary v1.37, target v1.36 | Skippable: this kubeadm can only upgrade to 1.37 | | Kubelets more than three minors behind the target | Skippable: kubelets in the cluster are too old | | Unstable target (alpha, beta, rc) | Needs `--allow-experimental-upgrades` or `--allow-release-candidate-upgrades` | The practical consequence: **each hop is run with the kubeadm binary of that hop's target minor**, installed first on the node where `kubeadm upgrade apply` runs. ## A two-minor catch-up on the portal cluster Suppose a clinical-records portal runs on a three-node kubeadm cluster at v1.35 and the goal is v1.37. 1. Install the latest v1.36 kubeadm on the first control-plane node and run `kubeadm upgrade plan`; it lists the versions you may move to. 2. Run `kubeadm upgrade apply` with the latest v1.36 patch, then `kubeadm upgrade node` on the other two nodes, and upgrade each node's kubelet. 3. Confirm health before going further: every node `Ready`, portal Pods running, no API errors in the pipelines that deploy it. 4. Repeat the same hop with the latest v1.37 kubeadm and the latest v1.37 patch. Kubelets do not have to follow each hop at once - they may trail `kube-apiserver` by up to three minors - but they may never be newer than it, which is why the control plane always moves first. ## Common confusions - **`--force` is not a shortcut.** It only skips the skippable findings; the two-minor check stays fatal for released versions. - **Skipping patches is fine; skipping minors is not.** v1.36.1 to the newest v1.36 patch is a single step. - **A new cluster is not an upgrade.** Building a fresh cluster at v1.37 and moving workloads to it sidesteps the rule, because nothing is upgraded in place - at the cost of a migration. - **Downgrades have the same limit.** kubeadm's policy also allows at most one minor downward, and a downgrade is not a routine rollback tool. - **Falling behind compounds.** The project maintains only the three most recent minors, so a cluster that is several minors behind has to do several full hops, each with its own validation, before it is back on a supported release.

  • Does each node's kubelet have to be upgraded before the next control-plane hop?
    Not necessarily. The skew policy lets a kubelet be up to three minor versions older than `kube-apiserver`, so a v1.35 kubelet still works with a v1.37 control plane. kubeadm only complains when the target would leave kubelets more than three minors behind. In practice teams usually upgrade kubelets on every hop anyway, so the gap never grows.
  • Can you skip patch releases, for example v1.36.1 straight to the newest v1.36 patch?
    Yes. Patch releases within one minor carry fixes, not staged API changes, so moving directly to the latest patch is the recommended path. The one-at-a-time rule applies to minor versions only.

It is like climbing a staircase that only lets you step onto the next stair: you can take any stair quickly, but you cannot jump two, because each stair is built to rest on the one below it.

saying these in an interview costs you the question

  • Passing --force lets kubeadm jump two minor versions safely
  • Any kubeadm binary can upgrade a cluster to any release
  • You must install every patch release in order within a minor
  • Kubelets must be upgraded before the control plane
  • Skipping a minor is fine if no workloads use beta APIs