In this document we will explain how to migrate to a newer FreeBSD version both on hosts and on jails.
You can always refer to Chapter 24: Updating and Upgrading FreeBSD for more detailed information.
FreeBSD is known for being reliable and to be painlessly upgradeable, even with custom setups, like I do, with manual partitioning, ZFS on root, FreeBSD can handle this easily.
We should start by evaluating the current version we have installed, with:
uname -mrs
which in my case renders FreeBSD 12.2-RELEASE amd64
.
We should make sure you apply all existing pending updates for FreeBSD 12.x:
sudo freebsd-update fetch
sudo freebsd-update install
sudo pkg update
sudo pkg upgrade
Make sure to have a snapshot of the machine or VMWare snapshot for a VM.
Once all updates are installed, we can then proceed to do the upgrade
(in this case to 13.0-RELEASE
):
sudo freebsd-update -r 13.0-RELEASE upgrade
After that process is done, which may take a while, you will get prompted
To install the downloaded upgrades, run "/usr/sbin/freebsd-update install"
You should thus run:
sudo /usr/sbin/freebsd-update install
Then reboot the machine, then run again:
sudo /usr/sbin/freebsd-update install
Then you should perform a second reboot and you will have a system with the new OS but old packages.
Your /etc/resolv.conf
might be
overriden during the update. Make sure to check this.
The next logical step to follow, after the last reboot, is to upgrade all packages of the system, once again with:
sudo pkg update
sudo pkg upgrade
Once all software is up-to-date, run again:
sudo /usr/sbin/freebsd-update install
and another reboot is recommended.
Even though this is a low-risk process, for production systems that cannot allow any downtime it is recommended to simply create a new jail with the new release, and switch traffic to the new jail. This requires more work, but will be safer, and is a benefit of having a jailed environment.
Upon a successful update of your host's system, any of your existing jails will still be using the release where you created them. Ideally you should always keep your jails to the same major release as your host.
You can get an overview of your jails with:
sudo iocage list
You should pre-fetch the wanted release files, which will then be available for all upgrades and for any new jails you might want to create with said version.
sudo iocage fetch -r 13.0-RELEASE
If the machine you are working on contains many jails, you should likely open several SSH sessions and upgrade the jails in parallel, of course at the cost of CPU & RAM usage.
In order to upgrade a jail's FreeBSD version you should run:
sudo iocage upgrade <name of your jail> -r 13.0-RELEASE
then we must update all packages within the jail:
sudo iocage pkg <name of your jail> update
sudo iocage pkg <name of your jail> upgrade -y
it is recommendable to restart the jail after the procedure:
sudo iocage restart <name of your jail>
It is highly recommendable to cleanup your system after verifying everything is stable and in order. Several files, backups and rollbacks can then be deleted, often saving 8GB+ of space. There are several handy tricks to be able to clean a FreeBSD machine and shave some disk GB.
You can do some cleanup by removing the fetched pkg files, both on your host
sudo pkg clean
and on your jails:
sudo iocage pkg <your jail> clean -y
You can check the current allocated size for zpools by running:
zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
iocage 19.5G 13.5G 5.97G - - 66% 69% 1.00x ONLINE -
zroot 17.5G 3.72G 13.8G - - 23% 21% 1.00x ONLINE -
You can check which zfs file systems are currently taking more space with:
zfs list
NAME USED AVAIL REFER MOUNTPOINT
iocage 13.5G 5.38G 24K /iocage
iocage/iocage 13.5G 5.38G 29.5K /iocage/iocage
iocage/iocage/download 803M 5.38G 24K /iocage/iocage/download
iocage/iocage/download/12.2-RELEASE 402M 5.38G 402M /iocage/iocage/download/12.2-RELEASE
iocage/iocage/download/13.0-RELEASE 401M 5.38G 401M /iocage/iocage/download/13.0-RELEASE
iocage/iocage/images 24K 5.38G 24K /iocage/iocage/images
iocage/iocage/jails 10.5G 5.38G 24K /iocage/iocage/jails
iocage/iocage/jails/elk-d 4.19G 5.38G 25.5K /iocage/iocage/jails/elk-d
iocage/iocage/jails/elk-d/root 4.19G 5.38G 4.51G /iocage/iocage/jails/elk-d/root
iocage/iocage/jails/jaeger-d 4.00G 5.38G 25.5K /iocage/iocage/jails/jaeger-d
iocage/iocage/jails/jaeger-d/root 4.00G 5.38G 4.32G /iocage/iocage/jails/jaeger-d/root
iocage/iocage/jails/web-server-d 2.26G 5.38G 25.5K /iocage/iocage/jails/web-server-d
iocage/iocage/jails/web-server-d/root 2.26G 5.38G 2.57G /iocage/iocage/jails/web-server-d/root
iocage/iocage/log 28K 5.38G 28K /iocage/iocage/log
iocage/iocage/releases 2.26G 5.38G 24K /iocage/iocage/releases
iocage/iocage/releases/12.2-RELEASE 1.20G 5.38G 24K /iocage/iocage/releases/12.2-RELEASE
iocage/iocage/releases/12.2-RELEASE/root 1.20G 5.38G 1.20G /iocage/iocage/releases/12.2-RELEASE/root
iocage/iocage/releases/13.0-RELEASE 1.06G 5.38G 24K /iocage/iocage/releases/13.0-RELEASE
iocage/iocage/releases/13.0-RELEASE/root 1.06G 5.38G 1.06G /iocage/iocage/releases/13.0-RELEASE/root
iocage/iocage/templates 24K 5.38G 24K /iocage/iocage/templates
zroot 3.72G 13.2G 24K /zroot
zroot/ROOT 3.23G 13.2G 24K none
zroot/ROOT/default 3.23G 13.2G 3.23G /
zroot/tmp 26.5K 13.2G 26.5K /tmp
zroot/usr 497M 13.2G 24K /usr
zroot/usr/home 3.50M 13.2G 3.50M /usr/home
zroot/usr/obj 24K 13.2G 24K /usr/obj
zroot/usr/ports 72K 13.2G 24K /usr/ports
zroot/usr/ports/distfiles 24K 13.2G 24K /usr/ports/distfiles
zroot/usr/ports/packages 24K 13.2G 24K /usr/ports/packages
zroot/usr/src 493M 13.2G 493M /usr/src
zroot/var 259K 13.2G 24K /var
zroot/var/audit 24K 13.2G 24K /var/audit
zroot/var/crash 24K 13.2G 24K /var/crash
zroot/var/log 135K 13.2G 135K /var/log
zroot/var/mail 28K 13.2G 28K /var/mail
zroot/var/tmp 24K 13.2G 24K /var/tmp
By looking at the above output you can see we have both the 12.2-RELEASE and 13.0-RELEASE versions of FreeBSD saved in our machine. In our case, we have successfully upgraded to 13.0-RELEASE and thus can remove all files stored related to 12.2-RELEASE. We can do this by simply removing the zfs dataset containing the 12.2-RELEASE download:
sudo zfs destroy -r iocage/iocage/download/12.2-RELEASE
Be extremely wary when running this command and ask someone more experienced if you are doubting!
We also can then clean the freebsd-update remaining files by removing the rollback and creating a new empty folder:
sudo rm -rf /var/db/freebsd-update/files
sudo mkdir /var/db/freebsd-update/files
sudo chmod 755 /var/db/freebsd-update/files
This should also be done in the jails if you upgraded them:
sudo iocage exec <your jail> rm -rf /var/db/freebsd-update/files
sudo iocage exec <your jail> mkdir /var/db/freebsd-update/files
sudo iocage exec <your jail> chmod 755 /var/db/freebsd-update/files
When you update to a new major version you might end up keeping old datasets lying around. These can be seen like above in the output of zfs list.
Very likely at iocage/iocage/releases/12.2-RELEASE
and iocage/iocage/releases/12.2-RELEASE/root
.
We must first find the "cloned" datasets with:
sudo zfs list -t snapshot -o name,clones
which outputs something like:
NAME CLONES
iocage/iocage/releases/12.2-RELEASE/root@database iocage/iocage/jails/database/root
iocage/iocage/releases/12.2-RELEASE/root@cache-store iocage/iocage/jails/cache-store/root
and then we can promote the clones to be the primary datasets for that jail:
sudo zfs promote iocage/iocage/jails/database/root
sudo zfs promote iocage/iocage/jails/cache-store/root
The clones can be removed with:
sudo zfs destroy iocage/iocage/releases/12.2-RELEASE/root
sudo zfs destroy iocage/iocage/releases/12.2-RELEASE
After all the cleanup it is recommended to restart the machine and verify it all works as expected.