[Solaris] Quick Solaris Zones Using ZFS
Or using a clone to phone in a zone
May 10, 2007

This is just a cheap trick en route to building an arbitrary set of zones in the least possible time. The end result of this walk-through creates new zones in a few keystrokes. Along the way, however, I also create a cheater device pool using space from an existing UFS partition. That's fun too.

Let's do that for starters. You can create a device pool for ZFS by using a form of reserved file space. These objects are zero-filled allocations of disk space set with a sticky bit. They're often used to supplement or replace the paging capacity of a system, like so:

# mkfile 256m /pagespace
# ls -l /pagespace
-rw------T   1 root     root     268435456 May 10 17:08 /pagespace
# swap -a /pagespace
# swap -l
swapfile             dev  swaplo blocks   free
/dev/dsk/c0t0d0s1   136,9      16 1052624 1052624
/pagespace            -       16 524272 524272

Now the /pagespace file is available for paging along with the dedicated device that was previously installed. It is worth noting however, that because mkfile(1M) zero-fills the space, the time required to make a file scales with its on-disk size:

# ptime mkfile 256m /pagespace1

real        4.687
user        0.044
sys         1.193
# ptime mkfile 1024m /pagespace2

real       20.714
user        0.182
sys         5.626

ZFS, as it turns out, can use these file objects to make a pool. That is, we can emulate disk space for play. What's more, ZFS doesn't require reserved space like the swap system does. Using mkfile -n, we can simply declare the files:

# ptime mkfile -n 2048m /cant_be_page_file_though

real        0.045
user        0.001
sys         0.003
# ls -l /cant_be_page_file_though
-rw------T   1 root     root     2147483648 May 10 17:20 /cant_be_page_file_though

# swap -a /cant_be_page_file_though
"/cant_be_page_file_though" may contain holes - can't swap on it.

We're only doing this to save time. All who decide to grow such a file beyond physical disk capacity did not learn this trick from me. So long as we're playing nice, however, we can create vdevs very quickly, make a zpool, and pay only for disk space that's actually consumed. This cheat might be handy for creating a demo or test on a system that has little disk room to spare:

# for i in 1 2 3 4 5 6 7 8
> do
> mkfile -n 1024m /vdevs/diskZ${i}
> done

# zpool create zfzones /vdevs/diskZ?
# zpool list
NAME                    SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
zfzones                7.94G   60.5K   7.94G     0%  ONLINE     -

I'm committed to minimal consumption at all points, so let's also turn on compression:

# zfs set compression=on zfzones

Any file system I create from zfzones will inherit this attribute, feeding my other need to factor out extra steps:

# zfs get compression zfzones
NAME             PROPERTY       VALUE                      SOURCE
zfzones          compression    on                         local

# zfs create zfzones/zone1
# zfs get compression zfzones/zone1
NAME             PROPERTY       VALUE                      SOURCE
zfzones/zone1    compression    on                         inherited from zfzones

Now the fun part: building zones from this pool:

# zonecfg -z goldzone
goldzone: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:goldzone> create
zonecfg:goldzone> set autoboot=false
zonecfg:goldzone> set zonepath=/zfzones/zone1
zonecfg:goldzone> info
zonepath: /zfzones/zone1
autoboot: false
pool:
inherit-pkg-dir:
        dir: /lib
inherit-pkg-dir:
        dir: /platform
inherit-pkg-dir:
        dir: /sbin
inherit-pkg-dir:
        dir: /usr
zonecfg:goldzone> verify;commit;exit
# zoneadm -z goldzone install
...

At this point, we could boot the zone and walk through the interactive sysidcfg program. Or, we could put a proper sysidcfg file in the /etc directory of the local zone, and then boot. Before doing either, however, I'll take a snapshot of the zone. Then I'll clone it to zfzones/zone2:

# zfs snapshot zfzones/zone1@presysid
# zfs list
NAME                   USED  AVAIL  REFER  MOUNTPOINT
zfzones               33.4M  7.78G  33.3M  /zfzones
zfzones/zone1         24.5K  7.78G  24.5K  /zfzones/zone1
zfzones/zone1@presysid      0      -  24.5K  -

# zfs clone zfzones/zone1@preid zfzones/zone2
# zfs list
NAME                   USED  AVAIL  REFER  MOUNTPOINT
zfzones               33.4M  7.78G  33.3M  /zfzones
zfzones/zone1         24.5K  7.78G  24.5K  /zfzones/zone1
zfzones/zone1@preid      0      -  24.5K  -
zfzones/zone2             0  7.78G  24.5K  /zfzones/zone2

Now it's a matter of copying the zone configuration file /etc/zones/goldzone.xml to, say, silver.xml, and edit the value for zonepath in it. Finally, we can copy the entry for goldzone in /etc/zones/index, and modify the zone's name and path as appropriate. Then delete the last field. Now there are two zones in the same state. If you prepare a sysidcfg file for each zone and place them before booting, creation of subsequent zones takes very little time.

Naturally you can bring a zone up to any point you like, snapshot it, clone it, create the needed zone metadata. The impact on disk space at the outset is zero:

# zpool list zfzones
NAME                    SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
zfzones                7.94G   33.4M   7.90G     0%  ONLINE     -
# zfs clone zfzones/zone1@preid zfzones/zone3
# zfs clone zfzones/zone1@preid zfzones/zone4
# zfs clone zfzones/zone1@preid zfzones/zone5
# zfs clone zfzones/zone1@preid zfzones/zone6
# zfs clone zfzones/zone1@preid zfzones/zone7
# zfs clone zfzones/zone1@preid zfzones/zone8

# zpool list zfzones
NAME                    SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT
zfzones                7.94G   33.5M   7.90G     0%  ONLINE     -

# zfs list
NAME                   USED  AVAIL  REFER  MOUNTPOINT
zfzones               33.5M  7.78G  33.3M  /zfzones
zfzones/zone1         24.5K  7.78G  24.5K  /zfzones/zone1
zfzones/zone1@preid      0      -  24.5K  -
zfzones/zone2             0  7.78G  24.5K  /zfzones/zone2
zfzones/zone3             0  7.78G  24.5K  /zfzones/zone3
zfzones/zone4             0  7.78G  24.5K  /zfzones/zone4
zfzones/zone5             0  7.78G  24.5K  /zfzones/zone5
zfzones/zone6             0  7.78G  24.5K  /zfzones/zone6
zfzones/zone7             0  7.78G  24.5K  /zfzones/zone7
zfzones/zone8             0  7.78G  24.5K  /zfzones/zone8

Not bad for starters. Add in scripting, and the savings in both elapsed time and disk space is considerable.




Add a comment

Title
Body
HTML : b, i, blockquote, br, p, pre, a href="", ul, ol, li
Math Quiz 6 + 7 = (Helps stop blog spam)
Name
E-mail address
Website
Remember me Yes  No 

E-mail addresses are not publicly displayed, so please only leave your e-mail address if you would like to be notified when new comments are added to this blog entry (you can opt-out later).

TrackBack to http://radio.javaranch.com/michael/addTrackBack.action?entry=1178864926824