TL;DR
# Check current version
k3s --version
# Upgrade server node to latest stable (run on server first)
curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=stable sh -
# Upgrade to a specific version (upgrade One Minor Version at a Time)
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.32.5+k3s1 sh -
# Then upgrade each worker node (upgrade One Minor Version at a Time)
curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=stable K3S_URL=https://<server-ip>:6443 K3S_TOKEN=<token> sh -
# Verify
kubectl get nodes
Your Current Situation
You're running:
k3s version v1.28.4+k3s2 (6ba6c1b6)
go version go1.20.11
v1.28 reached end-of-life in late 2024. The current stable lines as of April 2026 are v1.32 and v1.33. That means you're roughly 4 minor versions behind, which is important — you cannot jump straight from v1.28 to v1.33 in one shot.
The Golden Rule: One Minor Version at a Time
When attempting to upgrade to a new version of K3s, the Kubernetes version skew policy applies. Ensure that your plan does not skip intermediate minor versions when upgrading.
This means your upgrade path from v1.28 must go:
v1.28 → v1.29 → v1.30 → v1.31 → v1.32 → v1.33
You cannot skip from v1.28 directly to v1.33. Each hop must be done separately, with the cluster verified healthy between each step.
Also: when upgrading, upgrade server nodes first one at a time, then any agent nodes. Never upgrade workers before the server.
Important: Traefik Version Change at v1.32
K3s versions v1.31 and earlier will install Traefik v2, while K3s versions v1.32 and later will install Traefik v3. If you're using Traefik as your ingress controller (which is the K3s default), the jump from v1.31 to v1.32 will upgrade Traefik from v2 to v3. Review the Traefik v3 migration guide before doing that hop if you have custom Traefik configuration or IngressRoute resources.
Important: etcd Warning for v1.34+
If you plan to go all the way to v1.34 or v1.35, there is a critical etcd requirement. The K3s project announced that there is no safe upgrade path from etcd 3.5 to 3.6 (included in v1.34+) unless you are running etcd v3.5.26 first. The January 2025 releases of K3s v1.32 include etcd v3.5.26, so upgrading to at least v1.32 before jumping to v1.34+ is mandatory to avoid cluster data issues.
Method 1: Manual Upgrade via Install Script (Recommended)
You can upgrade K3s by using the installation script, or by manually installing the binary of the desired version. The install script is the easiest approach.
Step 1 — Upgrade the server node, one minor version at a time
# SSH into your server node
ssh root@<server-ip>
# Hop 1: v1.28 → v1.29
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.29.13+k3s1 sh -
# Verify server is healthy before proceeding
kubectl get nodes
k3s --version
# Hop 2: v1.29 → v1.30
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.30.13+k3s1 sh -
kubectl get nodes
# Hop 3: v1.30 → v1.31
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.31.9+k3s1 sh -
kubectl get nodes
# Hop 4: v1.31 → v1.32 (Traefik v2 → v3 happens here!)
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.32.5+k3s1 sh -
kubectl get nodes
# Hop 5: v1.32 → v1.33 (optional, if you want latest stable)
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.33.1+k3s1 sh -
kubectl get nodes
Step 2 — Upgrade each worker node
After each server hop is confirmed healthy, upgrade the workers for that version before proceeding to the next hop:
# SSH into each worker node
ssh root@<worker-ip>
# Run the same version as the server just upgraded to
curl -sfL https://get.k3s.io | \
INSTALL_K3S_VERSION=v1.29.13+k3s1 \
K3S_URL=https://<server-ip>:6443 \
K3S_TOKEN=<your-token> \
sh -
# Verify worker rejoined
kubectl get nodes
Your token is in /var/lib/rancher/k3s/server/node-token on the server node:
cat /var/lib/rancher/k3s/server/node-token
Step 3 — Verify after each hop
# All nodes should show same version and Ready status
kubectl get nodes -o wide
# Check nothing is broken
kubectl get pods -A | grep -v Running | grep -v Completed
Method 2: Upgrade via Binary (Manual)
If you prefer more control, or the install script fails:
# Download the specific version binary
wget https://github.com/k3s-io/k3s/releases/download/v1.29.13%2Bk3s1/k3s
# Replace the binary
chmod +x k3s
sudo mv k3s /usr/local/bin/k3s
# Restart the service
sudo systemctl restart k3s # on server
sudo systemctl restart k3s-agent # on workers
# Verify
k3s --version
Draining Nodes Before Upgrading (For Production)
Containers for pods continue running even when K3s is stopped. If your workload is sensitive to brief API server outages, you should manually drain and cordon the node before restarting K3s, and uncordon it afterwards.
For a production cluster where you can't afford any disruption:
# Before upgrading a node, drain it from the server
kubectl drain <node-name> \
--ignore-daemonsets \
--delete-emptydir-data \
--force
# Run the upgrade on that node
# ...
# After the node is back up, uncordon it
kubectl uncordon <node-name>
After the Full Upgrade
Once all nodes are on the new version, do a full health check:
# All nodes Ready and on same version
kubectl get nodes -o wide
# No pods stuck in bad state
kubectl get pods -A | grep -v Running | grep -v Completed
# Check system pods specifically
kubectl get pods -n kube-system
# Verify cert status (especially useful since you're now in cert rotation territory)
sudo k3s certificate check
Summary
| Your version | Target | Hops required |
|---|---|---|
| v1.28.4 | v1.29 | 1 |
| v1.28.4 | v1.32 | 4 (go through 29, 30, 31, 32) |
| v1.28.4 | v1.33 | 5 (go through 29, 30, 31, 32, 33) |
Take it one minor version at a time, always server first then workers, verify healthy between each hop, and mind the Traefik v2→v3 change when crossing v1.32.
Top comments (0)