CKS — Kubernetes Upgrade Frequency

8 minute read

Upgrade Frequency as a Security Concern

Running an outdated Kubernetes version is a security vulnerability — not just a maintenance issue. Every unpatched release carries known CVEs with public exploits. The CKS exam tests your understanding of why upgrade cadence matters and how the version support policy works.


CVE Exposure Window

The longer you stay on an old version, the wider your CVE exposure window — the time between a vulnerability being publicly disclosed and your cluster being patched.

CVE Disclosed    Patch Released    You Upgrade
     │                │                │
     ▼                ▼                ▼
─────┤────────────────┤────────────────┤──────────
     │◄──────────────────────────────►│
     │     CVE Exposure Window         │
     │     (cluster is vulnerable)     │

Real-World Kubernetes CVEs

CVE Severity Affected Versions Impact
CVE-2021-25741 High < 1.22.2, < 1.21.5 Symlink vulnerability allows host filesystem access
CVE-2022-3162 Medium < 1.25.4, < 1.24.8 Unauthorized read of custom resources
CVE-2023-5528 High < 1.28.4, < 1.27.8 Windows node privilege escalation
CVE-2024-9486 Critical Image Builder < 0.1.38 Default credentials in VM images
CVE-2020-8554 Medium All versions Man-in-the-middle via ExternalIP services

Every month without upgrading adds to your exposure to known and newly discovered vulnerabilities.


Kubernetes Version Support Policy

The Kubernetes project maintains three minor releases at any given time — the current release and the two immediately prior releases (the N-2 policy).

Support Window

Time ───────────────────────────────────────────────►

Release:  1.28        1.29        1.30        1.31
          │           │           │           │
 Supported └───────────┴───────────┴───────────┘
              When 1.31 is current, only
              1.29, 1.30, 1.31 receive patches

 Unsupported:  1.28 and older — NO security patches

Version Support Table

Release Support Status Security Patches Notes
N (latest) Full support Yes Recommended for new clusters
N-1 Full support Yes Safe for production
N-2 Full support Yes Minimum recommended version
N-3 and older End of Life No Must upgrade immediately

CKS Exam Tip: If asked “how often should you upgrade Kubernetes?”, the answer is: at least once per year to stay within the N-2 support window. Each minor release cycle is approximately 4 months (3 releases per year).

Patch Release Cadence

Within a supported minor release, patch releases (e.g., 1.29.1, 1.29.2) are issued approximately monthly or as needed for critical CVEs.

# Check the latest patch releases
curl -s https://dl.k8s.io/release/stable.txt
# e.g., v1.30.3

curl -s https://dl.k8s.io/release/stable-1.29.txt
# e.g., v1.29.7

Tracking Security Advisories

Official Channels

Channel URL / Info Type
kubernetes-announce mailing list groups.google.com/g/kubernetes-announce Email notifications for releases and CVEs
GitHub Security Advisories github.com/kubernetes/kubernetes/security/advisories Detailed CVE reports
Kubernetes Blog kubernetes.io/blog Release announcements
Release Notes github.com/kubernetes/kubernetes/blob/master/CHANGELOG Per-version changes
kubernetes/sig-release GitHub repo Release schedule and timelines

Subscribing to Security Notifications

# Subscribe to kubernetes-announce mailing list:
# https://groups.google.com/g/kubernetes-announce

# Watch the GitHub repo for security advisories:
# github.com/kubernetes/kubernetes → Watch → Custom → Security alerts

# Check current version against known CVEs:
kubectl version --short
# Compare against: https://kubernetes.io/docs/reference/issues-security/official-cve-feed/

Checking Your Cluster Version

# Server and client versions
kubectl version

# Just the server version
kubectl version -o json | jq '.serverVersion.gitVersion'

# Node versions (kubelet may differ from API server)
kubectl get nodes -o wide
# Check the VERSION column

# Compare control plane component versions
kubectl get pods -n kube-system -o json | jq -r '
  .items[] |
  select(.metadata.labels.tier == "control-plane") |
  "\(.metadata.labels.component): \(.spec.containers[0].image)"
'

Version Skew Policy

Not all components need to be at the exact same version. Kubernetes has a defined version skew policy that allows controlled upgrades.

Supported Version Skew

Component Relative to API Server Example (API Server = 1.30)
kube-controller-manager Same minor or N-1 1.30 or 1.29
kube-scheduler Same minor or N-1 1.30 or 1.29
kubelet Same minor, N-1, or N-2 1.30, 1.29, or 1.28
kube-proxy Same minor as kubelet Must match kubelet version
kubectl N+1, N, or N-1 1.31, 1.30, or 1.29

Upgrade Order

The version skew policy dictates the upgrade order:

1. API Server (control plane)        ← Upgrade FIRST
2. kube-controller-manager           ← After API server
3. kube-scheduler                    ← After API server
4. kubelet (worker nodes)            ← After control plane
5. kube-proxy                        ← With kubelet

Important: You cannot skip minor versions. To go from 1.28 to 1.30, you must upgrade 1.28 → 1.29 → 1.30.


Upgrade Strategy for Security Compliance

The Security-Driven Upgrade Process

┌─────────────────────────────────────────┐
│ 1. Monitor: Check for new CVEs weekly   │
│    - kubernetes-announce mailing list   │
│    - GitHub security advisories         │
├─────────────────────────────────────────┤
│ 2. Assess: Evaluate CVE impact          │
│    - Does it affect your configuration? │
│    - What's the CVSS score?             │
│    - Is there a known exploit?          │
├─────────────────────────────────────────┤
│ 3. Plan: Schedule upgrade window        │
│    - Critical CVE: immediate            │
│    - High: within 1 week               │
│    - Medium: next maintenance window    │
├─────────────────────────────────────────┤
│ 4. Test: Validate in staging first      │
│    - Run conformance tests              │
│    - Check application compatibility    │
├─────────────────────────────────────────┤
│ 5. Execute: Rolling upgrade             │
│    - Control plane first, workers next  │
│    - One node at a time                 │
└─────────────────────────────────────────┘
Upgrade Type Frequency Trigger
Patch version (e.g., 1.30.1 → 1.30.2) Monthly or on CVE release Security patches, bug fixes
Minor version (e.g., 1.29 → 1.30) Every 4 months Stay within N-2 window
Emergency patch Immediately Critical CVE with known exploit

kubeadm Upgrade Process (Security Context)

The CKS exam uses kubeadm-based clusters. Understanding the upgrade process is essential.

Pre-Upgrade Checklist

# 1. Check current version
kubectl get nodes
kubeadm version

# 2. Check available versions
apt list -a kubeadm 2>/dev/null | head -20   # Debian/Ubuntu
# or
yum list --showduplicates kubeadm | tail -20  # RHEL/CentOS

# 3. Read the release notes for breaking changes
# https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.30.md

# 4. Backup etcd
ETCDCTL_API=3 etcdctl snapshot save /tmp/etcd-backup.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

Control Plane Upgrade

# 1. Update kubeadm
apt-get update && apt-get install -y kubeadm=1.30.0-1.1
# or yum install -y kubeadm-1.30.0

# 2. Verify the upgrade plan
kubeadm upgrade plan

# 3. Apply the upgrade (first control plane node)
kubeadm upgrade apply v1.30.0

# 4. Upgrade kubelet and kubectl
apt-get install -y kubelet=1.30.0-1.1 kubectl=1.30.0-1.1
systemctl daemon-reload && systemctl restart kubelet

Worker Node Upgrade

# 1. Drain the node (from a control plane node)
kubectl drain <worker-node> --ignore-daemonsets --delete-emptydir-data

# 2. On the worker node: upgrade kubeadm, then kubelet config
apt-get update && apt-get install -y kubeadm=1.30.0-1.1
kubeadm upgrade node

# 3. Upgrade kubelet and kubectl
apt-get install -y kubelet=1.30.0-1.1 kubectl=1.30.0-1.1
systemctl daemon-reload && systemctl restart kubelet

# 4. Uncordon the node (from a control plane node)
kubectl uncordon <worker-node>

Post-Upgrade Verification

# Verify all nodes are at the new version
kubectl get nodes -o wide

# Check component health
kubectl get componentstatuses 2>/dev/null  # Deprecated but may still work
kubectl get --raw /healthz
kubectl get --raw /readyz

# Verify all system Pods are running
kubectl get pods -n kube-system

# Run a quick smoke test
kubectl run test --image=nginx:1.25 --restart=Never
kubectl get pod test
kubectl delete pod test

Security Implications of Outdated Versions

Risk Description
Known CVEs Public exploits exist for unpatched vulnerabilities
No security patches EOL versions receive no fixes, even for critical CVEs
Missing security features Newer versions add security improvements (e.g., PodSecurity, bound tokens)
Compliance failure Security frameworks (CIS, SOC2) require running supported versions
Difficult emergency patching Multi-version jumps increase upgrade complexity and risk
Ecosystem drift CNI plugins, CSI drivers, and operators may drop support for old versions

Practice Questions

Q1. Your cluster is running Kubernetes 1.27. The latest stable release is 1.31. Is your cluster within the supported version window?

Show Answer

No. With 1.31 as the latest release, the supported versions are:

  • 1.31 (N)
  • 1.30 (N-1)
  • 1.29 (N-2)

Version 1.27 is N-4, which is End of Life and receives no security patches. You need to upgrade through 1.28 → 1.29 → 1.30 → 1.31 (you cannot skip minor versions).


Q2. A critical CVE (CVSS 9.8) is announced affecting your cluster’s version. Patches are available. What should your response be?

Show Answer

For a CVSS 9.8 (Critical) CVE:

  1. Assess immediately — Determine if your cluster configuration is affected
  2. Apply workarounds — If a mitigation is available (e.g., disable a feature), apply it immediately
  3. Upgrade to patched version — Schedule an emergency maintenance window
  4. Backup etcd before upgrading
  5. Upgrade control plane first, then worker nodes
  6. Verify the cluster is healthy after the upgrade
  7. Document the incident and response for compliance

Do NOT wait for the next scheduled maintenance window for critical CVEs.


Q3. What is the correct upgrade order for Kubernetes components, and why?

Show Answer

The upgrade order is:

  1. kube-apiserver — First, because all other components communicate through it
  2. kube-controller-manager — Can run at N-1 relative to API server
  3. kube-scheduler — Same as controller-manager
  4. kubelet (on each node) — Can run at N-2 relative to API server
  5. kube-proxy — Must match kubelet version

The API server is upgraded first because the version skew policy allows other components to be older than the API server (but not newer). Upgrading the API server first ensures all other components remain within the supported skew.


Q4. How do you check the Kubernetes version on all nodes and identify any version skew?

Show Answer
# Check API server version
kubectl version -o json | jq '.serverVersion.gitVersion'

# Check all node (kubelet) versions
kubectl get nodes -o custom-columns=\
NAME:.metadata.name,\
VERSION:.status.nodeInfo.kubeletVersion,\
OS:.status.nodeInfo.osImage

# Check control plane component versions
kubectl get pods -n kube-system -o custom-columns=\
NAME:.metadata.name,\
IMAGE:.spec.containers[0].image \
| grep -E 'apiserver|controller|scheduler|etcd'

# Quick version skew check
echo "=== API Server ===" && \
kubectl version -o json | jq -r '.serverVersion.gitVersion' && \
echo "=== Nodes ===" && \
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}: {.status.nodeInfo.kubeletVersion}{"\n"}{end}'

All kubelets should be within N-2 of the API server version.


Q5. You need to upgrade a worker node from Kubernetes 1.29 to 1.30. Write the complete step-by-step commands.

Show Answer
# --- From a control plane node ---

# 1. Drain the worker node
kubectl drain worker-1 --ignore-daemonsets --delete-emptydir-data

# --- SSH to the worker node ---

# 2. Update kubeadm
apt-get update
apt-get install -y kubeadm=1.30.0-1.1

# 3. Upgrade the node configuration
kubeadm upgrade node

# 4. Upgrade kubelet and kubectl
apt-get install -y kubelet=1.30.0-1.1 kubectl=1.30.0-1.1

# 5. Restart kubelet
systemctl daemon-reload
systemctl restart kubelet

# --- Back on the control plane node ---

# 6. Uncordon the node
kubectl uncordon worker-1

# 7. Verify
kubectl get node worker-1
# Should show v1.30.0 and Ready status

Previous Up Next
ServiceAccount Security CKS Home API Server Audit

Updated: