Skip to main content
RunBook Academy

LinuxLXV · Rolling Kernel UpgradesCapacity

Cluster capacity during a kernel campaign - the reboot budget

Advanced⏱ ~14 minsystemd-analyzepcscorosync-quorumtool

What you'll learn

  • Measure the real out-of-service time for a kernel reboot, not just the kernel boot time
  • Compute campaign duration from node count, hold period and batch size
  • Explain why a node that is up is not yet a node that is carrying its share
  • Decide between a longer campaign, a larger batch and live patching against a CVE deadline

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-11

Not yet marked complete on this device.

linux-maintenance-capacity establishes the general rule: a maintenance window consumes the same headroom as a node failure, so a cluster doing planned work is a cluster running with its redundancy already spent.

Kernel upgrades are the case where that rule bites hardest, and for a reason that has nothing to do with the kernel. It is the only change in this course that combines a long per-node outage with a long mandatory hold — and multiplying those by the node count turns “apply a security patch” into a schedule measured in weeks, during every hour of which the cluster is one node short.

Nobody measures the right number

Ask how long a reboot takes and you will be told sixty seconds, because that is what a virtual machine does. The number that matters is not the reboot. It is node-out time: from the moment the node stops carrying work to the moment it is carrying its full share again.

node-out time =
    drain                       seconds to minutes
  + shutdown                    stopping services, unmounting, flushing
  + firmware POST               the one nobody counts
  + bootloader + kernel + initrd
  + userspace start             systemd units to their targets
  + application readiness       pool warm-up, cache fill, JIT
  + return + verification
  + observation hold            the big one

Firmware POST is the term that surprises people who have only operated virtual machines. A dense server with a large memory population, several HBAs and a RAID controller that inventories its drives on every boot can spend five to ten minutes before the bootloader is even reached. Memory training after a DIMM change can add several more. None of it is visible to any tool running on the host, because the host is not running.

Read-only / Safesystemd-analyze
$ systemd-analyze
Startup finished in 8.412s (firmware) + 2.104s (loader) + 891ms (kernel) + 1.464s (initrd) + 24.367s (userspace) = 37.238s
graphical.target reached after 24.366s in userspace.

Illustrative output

The honest way to get the number is to measure it on the canary node and write it in the plan:

# On the control node, immediately before the reboot
date -u +%s > /tmp/reboot-start

# ... reboot the node, wait for it to return to full service ...

# When the node is genuinely back
echo "node-out seconds: $(( $(date -u +%s) - $(cat /tmp/reboot-start) ))"

Then check where the time went:

systemd-analyze                  # firmware, loader, kernel, initrd, userspace
systemd-analyze blame | head     # which units dominated userspace
systemd-analyze critical-chain   # the dependency path that set the total

Campaign arithmetic

Now multiply. For N nodes, batch size B, node-out time T and hold H between batches:

campaign duration  ~=  ceil(N / B) x (T + H)
exposure           =   B nodes down, continuously, for that whole duration

Put the recommended kernel numbers in:

N = 40, B = 1, T = 20 min, H = 24 h
  ceil(40/1) x (0.33 + 24) h  =  40 x 24.33 h  =  973 h  =  ~41 days

Forty days to apply a kernel patch, with the tier running at N-1 for the entire period. That is not a criticism of the 24-hour hold — the hold exists because kernel regressions are frequently load-dependent and take a full daily cycle to appear. It is an argument that the schedule has to be a deliberate decision rather than an emergent property of a policy nobody did the arithmetic on.

The three levers against a deadline

A kernel CVE with a remediation deadline turns the campaign length into a hard constraint. There are exactly three things you can change, and each has a cost.

Shorten the hold. Cheap, and defensible after the canary has proven the kernel. The cost is that a load-dependent regression appearing on node 12 now has eleven other nodes already carrying it. Bound this by keeping the canary hold intact and only shortening the subsequent gates.

Increase the batch. Bounded, hard, by the two ceilings from linux-batch-sizing-and-rollback: B <= N - quorum and the capacity test at peak load. A deadline does not move either ceiling. Exceeding the quorum ceiling converts the campaign into a guaranteed outage, which is a worse outcome than missing the deadline.

Decouple the reboot from the fix. Live patching applies the security fix now and moves the reboot to the normal maintenance schedule. linux-live-kernel-patching-concepts covers what it does and does not cover — it handles a subset of kernel fixes and no driver changes — but where it applies, it is the only lever that satisfies the deadline without spending capacity.

The lever that does not exist is “do it faster with the same safety”. The observation period is where the safety lives.

What the fleet looks like mid-campaign

For most of the campaign the fleet is running two kernel versions. That is normal, expected, and supported: the kernel maintains a stable userspace ABI, so a mixed-kernel fleet behind a load balancer is unremarkable and a mixed-kernel Corosync or Pacemaker cluster is explicitly supported during upgrades.

Two things are worth checking rather than assuming.

Out-of-tree modules must exist for both kernels. ZFS, DRBD, vendor HBA and NIC drivers are built per kernel version by DKMS. The pre-reboot gate in linux-kernel-package-install catches a build failure on the node being patched; what it does not catch is a module version that behaves differently across the two kernels in the fleet — relevant for anything that talks between nodes, DRBD in particular.

The campaign has to be tracked. A campaign that runs for days across shift changes needs a record of which hosts are done, which is the subject of the next lesson.

Knowledge check

Knowledge check · 4 questions

  1. Q1. Which figure should a kernel campaign plan use for how long a node is unavailable?

  2. Q2. A node that has rebooted, reports systemctl is-system-running as running, and returns 200 from its health endpoint is contributing its full share of capacity.

  3. Q3. A kernel CVE has a deadline your 40-day serial campaign will miss. Which are legitimate levers? Select all that apply.

  4. Q4. A 40-node tier runs a serial kernel campaign with a 24-hour hold after every node. What is the most important consequence beyond the elapsed time?

Passing score: 75%. Answers are checked in this browser.