14.5.Â Updating Multiple Jails

Contributed by DanielGerzo.

Based upon an idea presented by SimonL. B. Nielsen.

And an article written by KenTom.

The management of multiple jails can become problematic
because every jail has to be rebuilt from scratch whenever it is
upgraded. This can be time consuming and tedious if a lot of
jails are created and manually updated.

This section demonstrates one method to resolve this issue
by safely sharing as much as is possible between jails using
read-only mount_nullfs(8) mounts, so that updating is
simpler. This makes it more attractive to put single services,
such as HTTP, DNS, and
SMTP, into individual jails. Additionally,
it provides a simple way to add, remove, and upgrade
jails.

Note:

Simpler solutions exist, such as
ezjail, which provides an easier
method of administering FreeBSD jails but is less versatile than
this setup. ezjail is covered in
more detail in SectionÂ 14.6, “Managing Jails with
ezjail”.

The goals of the setup described in this section are:

Create a simple and easy to understand jail structure
that does not require running a full installworld on each
and every jail.

Make it easy to add new jails or remove existing
ones.

Make it easy to update or upgrade existing jails.

Make it possible to run a customized FreeBSD branch.

Be paranoid about security, reducing as much as
possible the possibility of compromise.

Save space and inodes, as much as possible.

This design relies on a single, read-only master template
which is mounted into each jail and one read-write device per
jail. A device can be a separate physical disc, a partition, or
a vnode backed memory device. This example uses read-write
nullfs mounts.

The file system layout is as follows:

The jails are based under the
/home partition.

Each jail will be mounted under the
/home/j directory.

The template for each jail and the read-only partition
for all of the jails is
/home/j/mroot.

A blank directory will be created for each jail under
the /home/j directory.

Each jail will have a /s directory
that will be linked to the read-write portion of the
system.

Each jail will have its own read-write system that is
based upon /home/j/skel.

The read-write portion of each jail will be created in
/home/js.

14.5.1.Â Creating the Template

This section describes the steps needed to create the
master template.

It is recommended to first update the host FreeBSD system to
the latest -RELEASE branch using the instructions in SectionÂ 23.5, “Updating FreeBSD from Source”. Additionally, this template uses the
sysutils/cpdup package or port and
portsnap will be used to download
the FreeBSD Ports Collection.

First, create a directory structure for the read-only
file system which will contain the FreeBSD binaries for the
jails. Then, change directory to the FreeBSD source tree and
install the read-only file system to the jail
template:

Now, symlink the read-write file system to the
read-only file system. Ensure that the symlinks are
created in the correct s/ locations
as the creation of directories in the wrong locations will
cause the installation to fail.

As a last step, create a generic
/home/j/skel/etc/make.conf containing
this line:

WRKDIRPREFIX?= /s/portbuild

This makes it possible to compile FreeBSD ports inside
each jail. Remember that the ports directory is part of
the read-only system. The custom path for
WRKDIRPREFIX allows builds to be done
in the read-write portion of every jail.

14.5.2.Â Creating Jails

The jail template can now be used to setup and configure
the jails in /etc/rc.conf. This example
demonstrates the creation of 3 jails: NS,
MAIL and WWW.

Add the following lines to
/etc/fstab, so that the read-only
template for the jails and the read-write space will be
available in the respective jails:

The
jail_name_rootdir
variable is set to
/usr/home instead
of /home because
the physical path of /home on a default FreeBSD
installation is /usr/home. The
jail_name_rootdir
variable must not be set to a path
which includes a symbolic link, otherwise the jails will
refuse to start.

Create the required mount points for the read-only
file system of each jail:

At this point, it should be possible to log onto each
jail, add new users, or configure daemons. The
JID column indicates the jail
identification number of each running jail. Use the following
command to perform administrative tasks in the jail whose
JID is 3:

#jexec 3 tcsh

14.5.3.Â Upgrading

The design of this setup provides an easy way to upgrade
existing jails while minimizing their downtime. Also, it
provides a way to roll back to the older version should a
problem occur.

The first step is to upgrade the host system. Then,
create a new temporary read-only template in
/home/j/mroot2.

Move the old read-only file system and replace it with
the new one. This will serve as a backup and archive of
the old read-only file system should something go wrong.
The naming convention used here corresponds to when a new
read-only file system has been created. Move the original
FreeBSD Ports Collection over to the new file system to save
some space and inodes: