Runbook: Rolling kernel upgrade - the production procedure
1 · Prerequisites
Confirm every item is in place before any state change.
2 · Pre-checks
Read-only diagnostic commands. If any of these don't match expected output, stop and investigate further.
- · Verify the new kernel package is available in the repository
- · Verify the cluster is healthy (all nodes online, and no node already in standby)
- · Verify GRUB has the old kernel as the fallback option: grubby --info=ALL lists an entry for the currently running kernel
- · Confirm GRUB_DEFAULT=saved in /etc/default/grub - grub2-reboot and grub2-set-default have no effect otherwise
- · Verify out-of-band access (BMC, console)
3 · Procedure
Execute each step in order. Verify the expected output of a step before moving to the next.
- 1Drain node1 (canary) with pcs node standby
- 2Install the new kernel package
- 3Reboot the node
- 4Validate: kernel version, services, network, storage
- 5Return node1 to service: pcs node unstandby node1, then confirm resources can be placed with pcs status nodes
- 6Hold for 24 hours
- 7If validation fails, roll back via GRUB
- 8Proceed to node2 and node3 in the same way (drain, upgrade, reboot, validate, unstandby, hold)
- 9Document the change
4 · Verification
Confirm the procedure actually fixed the problem.
- ✓All nodes running the new kernel
- ✓No node is left in standby: pcs status nodes shows an empty Standby list
- ✓All services healthy
- ✓No regressions observed in 24h
- ✓GRUB fallback still works (tested in staging)
- ✓grubby --default-kernel and grub2-editenv list agree with the kernel the node is running - the node will boot the same kernel next time
5 · Rollback
If verification fails, undo the procedure in reverse order.
- ↶Set the persistent GRUB default to the old kernel with grubby --set-default (grub2-reboot is one-shot and does not survive the following boot)
- ↶Reboot the node
- ↶Verify the old kernel boots and that grubby --default-kernel still points at it
- ↶Remove or version-lock the bad kernel package so it cannot be reselected
- ↶If the new kernel must be removed, uninstall the package
- ↶Return the node to service with pcs node unstandby <node> before leaving the maintenance window, whether the upgrade succeeded or was rolled back
6 · Escalation
When the runbook isn't enough, contact:
- · If the new kernel does not boot, escalate to the platform team
- · If a regression is observed in production, escalate immediately
- · If the rollback fails, escalate to support
This runbook covers a rolling kernel upgrade on a cluster node by node. The procedure is the production discipline for kernel maintenance.
When to use this runbook
Use this runbook when:
- A security update requires a kernel upgrade.
- A new kernel feature is needed.
- A driver or hardware change requires a newer kernel.
- The new kernel has been tested in staging.
Inputs
Gather before starting:
- The target kernel version.
- The cluster name and node names.
- Out-of-band access (BMC, console).
- A maintenance window (typically 24+ hours per node).
- Communication channels.
Procedure
Step 1: Capture baseline
# Current kernel
uname -r > /tmp/kernel-before.txt
# Cluster status
sudo pcs status > /tmp/cluster-before.txt
# Service health
curl -sf http://<vip>/health > /tmp/health-before.txtStep 2: Configure GRUB for fallback
# Note the current default kernel
sudo grubby --default-kernel
sudo grub2-editenv list | grep saved_entry
# List every bootable kernel entry
sudo grubby --info=ALL | grep -E '^(index|kernel|title)='
# Explicit gate: the currently RUNNING kernel must still have an entry
running=$(uname -r)
sudo grubby --info=ALL | grep -q "vmlinuz-${running}" \
&& echo "FALLBACK OK: ${running} is still bootable" \
|| { echo "ABORT: no fallback entry for ${running}"; exit 1; }The old kernel is the safety net. Confirm it is still in
the menu before proceeding. This is a gate, not a note: if
the ABORT branch fires, stop the change. dnf prunes old
kernels once installonly_limit is reached, so a node that
has been patched several times may have no fallback left.
Step 3: Drain node1 (canary)
sudo pcs node standby node1 --wait=300
sudo pcs status nodesVerify resources have migrated. Node1 must appear under
Standby, and every resource must be running on node2 or
node3.
Standby is a node attribute in the CIB. It survives the
reboot. Node1 will come back as Online (standby) and
will host nothing until you clear it in Step 7. That is
the point of the drain, and it is also the trap: nothing
clears standby for you.
Step 4: Install the new kernel on node1
sudo dnf install kernelStep 5: Reboot node1
sudo rebootWait for the host to come back. SSH in and verify.
Step 6: Validate node1
uname -r
# New kernel
sudo pcs status nodes
# Node1 rejoined the cluster, still listed under Standby
# Cluster-level health, served by node2 and node3
curl -sf http://<vip>/health
# Latency
time curl -sf http://<vip>/
# Logs
sudo journalctl -k --since "5 minutes ago" | grep -i errorNode1 is back in the membership but still drained, so these checks prove the new kernel boots and the cluster stack starts. They do not yet prove node1 can carry the workload. That is Step 7.
If validation fails, roll back:
# 1. Identify the known-good kernel entry
sudo grubby --info=ALL | grep -E '^(index|kernel|title)='
# 2. Make the OLD kernel the PERSISTENT default (survives every future boot)
sudo grubby --set-default /boot/vmlinuz-<old-version>
sudo grubby --default-kernel # verify it took
# 3. Reboot
sudo reboot
# 4. After boot, confirm running == intended
uname -r
sudo grubby --default-kernel
# 5. Prevent recurrence: the bad kernel must not be reselectable
sudo dnf remove kernel-core-<bad-version>
# or, if it must stay installed:
sudo dnf versionlock add kernel-<good-version>Verify the rollback. Leave node1 in standby while it is rolling back, then clear standby in Step 7 once the old kernel has booted and validated. A rolled-back node still has to go back into service.
Step 7: Return node1 to service
sudo pcs node unstandby node1 --wait=300
sudo pcs status nodes
# node1 must be listed under Online, and under no Standby line
sudo pcs status
# Resources placed on node1The node is only upgraded when it is carrying resources
again. Until unstandby runs, node1 is a spare that costs
capacity and gives nothing back, and the cluster is running
on the remaining nodes with no headroom.
Do not proceed to node2 until node1 is out of standby. If you drain node2 while node1 is still drained, a three-node cluster is down to one node, and the third drain takes the service down completely.
Step 8: Hold for 24 hours
After node1 is back in service, hold for 24 hours. Monitor:
- Error rates.
- Performance.
- Health check status.
The hold only counts while node1 is carrying live traffic. A drained node under no load proves nothing.
If any regression, roll back immediately.
Step 9: Update node2 and node3
Repeat the full procedure for node2 and node3, one at a
time, with 24-hour holds. The full procedure is: drain,
install, reboot, validate, unstandby, hold. Each node
returns to service before the next is drained.
Step 10: Final validation
After all nodes updated:
# All nodes online, no node left in standby
sudo pcs status nodes
# All resources running and spread across the nodes
sudo pcs resource status
# Synthetic monitoring
curl -sf http://<vip>/healthThe Standby line in pcs status nodes must be empty. If
a node name is still on it, that node is online, patched,
and idle, and the cluster has less capacity than the change
record claims.
Step 11: Document
In the change log:
- Time of upgrade.
- Old and new kernel versions.
- Nodes updated.
- Validation results.
- Confirmation that no node was left in standby.
- Confirmation that each node’s persistent default kernel
(
grubby --default-kernel) matches the kernel it is running. - Rollback tested.
Common patterns
| Symptom | Likely cause | Resolution |
|---|---|---|
| New kernel does not boot | Driver or initramfs issue | Roll back; investigate |
| Rolled-back node returns to the bad kernel weeks later | Rollback used one-shot grub2-reboot only | grubby --set-default /boot/vmlinuz-<good>; remove or version-lock the bad package |
grub2-reboot appears to do nothing | GRUB_DEFAULT=saved not set in /etc/default/grub | Set it, run grub2-mkconfig -o the active config, retest in staging |
| Network interface renamed | Predictable naming change | Update network config; rename or disable |
| Service fails post-reboot | Module not loaded | Load module; rebuild initramfs |
| Performance regression | Driver bug | Roll back; file upstream bug |
| Node online but hosts nothing | Left in standby after the reboot | pcs node unstandby <node>; recheck pcs status nodes |
| Resources will not start anywhere | Every node drained | pcs node unstandby --all; then re-drain one node at a time |
Knowledge check
Knowledge check · 7 questions
Q1. What is the first step in a kernel upgrade?
Q2. A kernel upgrade does not require a reboot.
Q3. Which of the following are valid for kernel upgrade? Select all that apply.
Q4. Node1 has rebooted onto the new kernel and pcs status shows it as Online (standby). What must happen before node2 is drained?
Q5. A cluster can be fully down while pcs status reports every node as Online.
Q6. You rolled a node back with grub2-reboot, it booted the old kernel, validation passed and you closed the incident. Three weeks later the same regression reappears on that node after an unrelated power event. What happened?
Q7. On RHEL 8 and 9 a check that scrapes /boot/grub2/grub.cfg prints nothing even when a fallback kernel entry is present and bootable.
Passing score: 75%. Answers are checked in this browser.