Virtualization is something I've been interested in for some time, dabbling with VMWare on Windows, and eagerly awaiting Xen+BSD and AMD's Pacifica-enabled chips. FreeBSD's jail feature gives many of the same benefits but with relatively little overhead, as long as you're interested in working with the same version of FreeBSD in your "virtual" system as your "host" is running. Jails are a great way to isolate software - for security reasons, to run different versions of the same package, or just to allow yourself a sandbox to mess with that you can easily wipe out and recreate in a few seconds.
The man page for jail describes how to setup a jail by hand, which seems a bit involved. Luckily I stumbled across ezjail, which makes creating jails a breeze. Once it's setup, you can create and "boot" a fully functioning jail with just three commands. ezjail arranges things so most of the FreeBSD userland is shared between the jails, and the files unique to each jail take up as little as 2mb.
The initial setup is basically:
- install the port in
/usr/local/etc/ezjail.confto set where you want your jails created. (In my case I used
- make sure your
/usr/srctree is complete
That last command can take a lot of time (maybe hours), since it does
If you've already built your world,
-i parameter for skipping that step and just doing the
Once that's all done, in your jail directory there is a
basejail which contains
about 130+mb of files that will be shared between jails,
newjail which is a
skeleton containing about 2mb of files that gets copied to any new jails you create, and
flavours which is basically another set of skeleton directories that get copied
newjail skeleton when your jail is created.
At this point, you can create and boot a jail with:
ifconfig lo0 alias 127.66.0.1 netmask 255.255.255.255or similar to give one of your network interfaces an IP the jail can use.
ezjail create myjail 127.66.0.1creates a new directory (
/data/jails/myjailin my case) that's a copy of
newjailand sets a few other things up.
/usr/local/etc/rc.d/ezjail.sh start myjail
At this point the jail is up and running. You can "log into" it by first finding
out the integer id of the jail with
jls, and then running
jexec <jail-id> /bin/sh
There are a few things that are missing in this barebones install, mainly no
/etc/resolv.conf so domain name lookups don't work, no
/etc/localtime so time in the jail shows as UTC.
You can fix these problems and add your own customizations easily by using a flavour
(don't mess with the
newjail template directory).
You can stop and wipe out your jail with
/usr/local/etc/rc.d/ezjail.sh stop myjail ezjail-admin delete -w myjail
Then, to make a new flavour and make a jail using that flavour, something like
cd /data/jails/flavours cp -pr default myflavour cd myflavour/etc cp -p /etc/resolv.conf . cp -p /etc/localtime . ezjail-admin create -f myflavour myjail 127.66.0.1 /usr/local/etc/rc.d/ezjail.sh start myjail
At this point, you've created a new jail with your customizations, and would use
again to find the jail-id, and
jexec to start a shell inside the running jail.
A flavour may also contain packages you wish to install upon jail creation, and commands to
execute when the jail is created. Check out the
file in your flavour directory. I've used it to install common useful things like
gettext which take
a long time to build that you don't want to repeat for every jail.