Streamlining Zone Creation Thanks to ZFS Integration
Posted on September 28, 2006
Zone’s a wonderful and handy tools for developers and admins alike, but creating them can be a time consuming activity especially when you need to create more than one. Scripting can help but your not shortening the time, just automating the process. But around Nevada B43 ZFS and Zones were integrated, building on each others strengths. Now we can clone zones, which reduces the amount of wasted disk space when creating multiple zones that are initially identical. When you create a zone in a ZFS pool a new filesystem is automatically created instead of just a simple directory. And just in case your existing zones are on UFS and you want to migrate them to ZFS, you can use the handy move capabilities of zoneadm to move everything seemlessly for you.
Lets take a look at the process.
First lets create our initial zone, which I’m calling “puppet1”.
$ zonecfg -z puppet1 'create; set autoboot=true; set zonepath=/ultrastor/puppet1; add net; set address=10.0.0.21; set physical=nge0; end; verify; commit; exit' $ zonecfg -z puppet1 info zonename: puppet1 zonepath: /ultrastor/puppet1 autoboot: true bootargs: pool: limitpriv: inherit-pkg-dir: dir: /lib inherit-pkg-dir: dir: /platform inherit-pkg-dir: dir: /sbin inherit-pkg-dir: dir: /usr net: address: 10.0.0.21 physical: nge0
Note in the above that by default /usr, /sbin, /lib, and /platform are loopback mounted rather than copied, which is the default behavior. If you wanted a “blank” configuration with no defaults set you could have specified create -b to zonecfg.
zonecfg only creates the metadata required for my zone to function, the zone itself hasn’t actually been created. So now I’ll go ahead and “install” the zone.
$ time zoneadm -z puppet1 install A ZFS file system has been created for this zone. Preparing to install zone. Creating list of files to copy from the global zone. Copying <35389> files to the zone. Initializing zone product registry. Determining zone package initialization order. Preparing to initialize <1073> packages on the zone. Initialized <1073> packages on zone. Zone is initialized. Installation of these packages generated warnings: The file contains a log of the zone installation. real 24m28.964s user 1m0.522s sys 1m50.353s
So that install took 25 minutes! Part of the hold up was due to my not inheriting /opt, and you see that in the output as the 35,000 files to copies. But because I want to write into /opt, it had to be done.
I personally can’t stand going through the sysid when you boot a zone for the first time (the curses interface that asks you all the questions), so I’ll insert a sysidcfg file before I boot the zone for the first time.
$ cat sysidcfg system_locale=C timezone=US/Pacific terminal=xterms security_policy=NONE root_password=HsANA7Dt/0sXX timeserver=localhost name_service=NONE network_interface=primary {hostname=puppet1 netmask=255.255.255.0 protocol_ipv6=no default_route=10.0.0.250} name_service=NONE nfs4_domain=dynamic $ cp sysidcfg /ultrastor/puppet1/root/etc/ $ zoneadm -z puppet1 boot
Against, this first boot is going to take a while as it initializes everything. While its booting you should watch the console by using zlogin -C puppet1 in another window.
So I’ve now spent the better part of an hour getting this zone setup and configured. At this point I can do any last little tweeks I want within the zone.
Now comes the real magic. I liked that first zone, but I need 4 more. Rather than repeat the process, I can simply clone them off! This first requires that I create the zone configuration for them.
$ zonecfg -z puppet2 'create; set autoboot=true; set zonepath=/ultrastor/puppet2; add net; set address=10.0.0.22; set physical=nge0; end; verify; commit; exit' $ zonecfg -z puppet3 'create; set autoboot=true; set zonepath=/ultrastor/puppet3; add net; set address=10.0.0.23; set physical=nge0; end; verify; commit; exit' $ zonecfg -z puppet4 'create; set autoboot=true; set zonepath=/ultrastor/puppet4; add net; set address=10.0.0.24; set physical=nge0; end; verify; commit; exit'
Now I can clone the first zone, puppet1, to bypass the normal “install” phase of the other zones.
$ zoneadm list -vc ID NAME STATUS PATH 0 global running / 19 puppet1 running /ultrastor/puppet1 - puppet2 configured /ultrastor/puppet2 - puppet3 configured /ultrastor/puppet3 - puppet4 configured /ultrastor/puppet4 $ zlogin puppet1 halt $ time zoneadm -z puppet2 clone puppet1 Cloning snapshot ultrastor/puppet1@SUNWzone1 Instead of copying, a ZFS clone has been created for this zone. real 0m53.895s user 0m0.289s sys 0m0.218s $ zoneadm -z puppet3 clone puppet1 Cloning snapshot ultrastor/puppet1@SUNWzone2 Instead of copying, a ZFS clone has been created for this zone. $ zoneadm -z puppet4 clone puppet1 Cloning snapshot ultrastor/puppet1@SUNWzone3 Instead of copying, a ZFS clone has been created for this zone.
You’ll notice that it created a new ZFS snapshot each time I cloned, I could have actually specified “-s SUNWzone1” after the first clone to continue using that single snapshot.
Now we look again at our zone list to see that we’ve changed state for those 3 new zones from “configured” to “installed”:
$ zoneadm list -vc ID NAME STATUS PATH 0 global running / - puppet1 installed /ultrastor/puppet1 - puppet2 installed /ultrastor/puppet2 - puppet3 installed /ultrastor/puppet3 - puppet4 installed /ultrastor/puppet4
Perfect. To avoid any additional configuration I’ll take that sysidcfg I created earlier, change the hostname, and then copy it in. Once thats done, start ’em up.
$ cp sysidcfg /ultrastor/puppet2/root/etc/ $ cp sysidcfg /ultrastor/puppet3/root/etc/ $ cp sysidcfg /ultrastor/puppet4/root/etc/ $ vi /ultrastor/puppet2/root/etc/sysidcfg $ vi /ultrastor/puppet3/root/etc/sysidcfg $ vi /ultrastor/puppet4/root/etc/sysidcfg $ zoneadm -z puppet1 boot $ zoneadm -z puppet2 boot $ zoneadm -z puppet3 boot $ zoneadm -z puppet4 boot
And we’re done! Cloning lets us really leverage that initial time we spent getting our zone right and relieves us of having to repeat it over and over. While creating that first zone might take 30 minutes or more, more can be created in minutes with ease. By using sysidcfg files as well we even further reduce the intervention on our part.
$ zoneadm list -vc | grep puppet 23 puppet1 running /ultrastor/puppet1 27 puppet2 running /ultrastor/puppet2 28 puppet3 running /ultrastor/puppet3 29 puppet4 running /ultrastor/puppet4
Just wrap some of this up in a script and things get even simpler. If you thought you were burning through your class C address space before, just watch your network admin cridge now!