I am using unattended-upgrades across multiple servers. I would like package updates to be rolled out gradually, either randomly or to a subset of test/staging machines first. Is there a way to do that for APT on Ubuntu?
An obvious option is to set some machines to update on Monday and the others to update on Wednesday, but that only gives me only weekly updates…
The goal of course is to avoid a Crowdstrike-like situation on my Ubuntu machines.
edit: For example. An updated openssh-server comes out. One fifth of the machines updates that day, another fifth updates the next day, and the rest updates 3 days later.
Small number of machines?
Disable unattended-upgrades and use crontab to schedule this on the days of the week you want.
Eg, Monday each week at 4 am - every combination of dates and days is possible with crontab. 2nd Tuesdays in a month? No problem.
0 4 * * MON apt-get update && apt-get upgrade && reboot
(You can also be more subtle by calling a script that does the above, and also does things like check whether a reboot is needed first)
Dozens, hundreds or thousands of machines? Use a scheduling automation system like Uyuni. That way you can put machines into System Groups and set patching schedule like that. And you can also define groups of machines, either ad-hoc or with System Groups, to do emergency patching like that day’s openssh critical vuln by sending a remote command like the above to a batch at a time.
All of that is pretty normal SME/Enterprise sysadminning, so there’s some good tools. I like Uyuni, but others have their preference.
However - Crowdstrike on Linux operates much like CS on Windows - they will push out updates, and you have little or no control over when or what. They aren’t unique in this - pretty much every AV needs to be able to push updates to clients when new malware is detected. But! In the example of Crowdstrike breaking EL 9.4 a few months ago when it took exception to a new kernel and refused to boot, then yes, scheduled group patching would have minimised the damage. It did so for us, but we only have CS installed on a handful of Linux machines.
You could go the Ansible route. (No unattended upgrades)
Cron with the -y option on apt commands.
A cron job that runs when you want it to instead of the unattended updates metapackage.
My suggestion is to use system management tools like Foreman. It has a “content views” mechanism that can do more or less what you want. There’s a bunch of other tools like that along the lines of Uyuni. Of course, those tools have a lot of features, so it might be overkill for your case, but a lot of those features will probably end up useful anyway if you have that many hosts.
With the way Debian/Ubuntu APT repos are set up, if you take a copy of /dists/$DISTRO_VERSION
as downloaded from a mirror at any given moment and serve it to a particular server, that’s going to end up with apt update && apt upgrade
installing those identical versions, provided that the actual package files in /pool
are still available. You can set up caching proxies for that.
I remember my DIY hodgepodge a decade ago ultimately just being a daily cronjob that pulls in the current distro (let’s say bookworm
) and their associated -updates
and -security
repos from an upstream rsync-capable mirror, then after checking a killswitch and making sure things aren’t currently on fire, it does rsync -rva tier2 tier3; rsync -rva tier1 tier2; rsync -rva upstream/bookworm tier1
. Machines are configured to pull and update from tier1 (first 20%)/tier2 (second 20%)/tier3 (rest) appropriately on a regular basis. The files in /pool
were served by apt-cacher-ng, but I don’t know if that’s still the cool option nowadays (you will need some kind of local caching for those as old files may disappear without notice).