Solaris 10 Zones

Basic Instructions to Setup Zones

A demonstration on how to implement Solaris 10 Zones.

The following information outlines the basic steps.

Solaris 10 Zones

Zones provide a new isolation primitive for the Solaris OS, which is secure, flexible, scalable and lightweight: virtualized OS services which look like different Solaris instances. Together with the existing Solaris Resource management framework, Solaris Zones forms the basis of Solaris Containers.

The Solaris Zones feature is based on the same basic concepts as FreeBSD Jails. In both FreeBSD Jails and Solaris Zones, each virtual view of the runtime environment is completely segregated, and processes from one environment cannot send signals to or even see processes in another. Both Jails and Zones share only one instance of the operating system, though, so multiple runtime environments can coexist on a machine with only one CPU.

Getting Started

There are several things to consider when setting up zones. The main requirement is that you'll need a Solaris 10 machine. Depending on the number of zones you're planing on setting up, you'll need an appropriate amount of disk and memory. I recommend that you isolate your zones on a separate disk partition. Now's a good time to look at you machine's configuration

# uname -a
SunOS yourmachine 5.10 Generic_118822-25 sun4u sparc SUNW,Ultra-4

#  prtconf -v | grep Memory
Memory size: 1024 Megabytes
	

# df -lk
Filesystem            kbytes    used   avail capacity  Mounted on
/dev/dsk/c0t0d0s0     964269  687642  218771    76%    /
/devices                   0       0       0     0%    /devices
ctfs                       0       0       0     0%    /system/contract
proc                       0       0       0     0%    /proc
mnttab                     0       0       0     0%    /etc/mnttab
swap                  815992     384  815608     1%    /etc/svc/volatile
objfs                      0       0       0     0%    /system/object
fd                         0       0       0     0%    /dev/fd
swap                  817992    2392  815600     1%    /tmp
swap                  815656      56  815600     1%    /var/run
/dev/dsk/c0t0d0s3    7178855 5613875 1493192    79%    /zones

# isainfo -v
64-bit sparcv9 applications
        vis 
32-bit sparc applications
        vis v8plus div32 mul32 

# psrinfo -v
Status of virtual processor 0 as of: 02/20/2006 07:57:25
  on-line since 02/17/2006 11:07:01.
  The sparcv9 processor operates at 500 MHz,
        and has a sparcv9 floating point processor.

Create a Zone

O.K. enough of that.. Let's create a zone. In case you haven't figured it out we'll stick our zone under /zones. One thing to note is that the zone we're about to create will inherit /lib /platform /sbin and /lib from the global zone (the parent machine's operation system). Inherited directories are imported read-only. If you are going to install additional software packages that need to place files in one of these imported directories (e.g. /usr) you'll need either use "create -b" which will create hard copies of these directories (which is VERY large) or use the "set special" options.

This first section simply configures the zone

# zonecfg -z z1 
z1: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:z1> create
zonecfg:z1> set zonepath=/zones/z1
zonecfg:z1> set autoboot=true
zonecfg:z1> add net
zonecfg:z1:net> set address=xxx.xxx.xxx.xxx
zonecfg:z1:net> set physical=hme0
zonecfg:z1:net> end
zonecfg:z1> info
zonepath: /zones/z1
autoboot: true
pool: 
inherit-pkg-dir:
        dir: /lib
inherit-pkg-dir:
        dir: /platform
inherit-pkg-dir:
        dir: /sbin
inherit-pkg-dir:
        dir: /usr
net:
        address: xxx.xxx.xxx.xxx
        physical: hme0
zonecfg:z1> verify
zonecfg:z1> commit
zonecfg:z1> exit

Once the zone has been configured you're ready to install the zone.

# zoneadm -z z1 install
Preparing to install zone .
Creating list of files to copy from the global zone.
Copying <2402> files to the zone.
Initializing zone product registry.
Determining zone package initialization order.
Preparing to initialize <862> packages on the zone.
Initialized <862> packages on zone.                                
Zone  is initialized.
The file  contains a log of the zone installation.

Once the zone has been installed you're ready to boot up the zone.

# zoneadm -z z1 boot

After the zone has been booted go ahead and check the status of the zone using the zoneadm list -vc command.

# zoneadm list -vc
  ID NAME             STATUS         PATH                          
   0 global           running        /                             
   3 z1               running        /zones/z1    

# ping xxx.xxx.xxx.xxx1
xxx.xxx.xxx.xxx is alive

Logging In

Congratulation, you have done it. Now log into your new zone. Use the zlogin command. If you want to use a special character to exit from the zlogin session use the -C <character> option. By default you can disconnect using ~. or exit.
The first time you connect to a new zone you'll be prompted for TERM information. The ssh keys will then be automatically generated. I generally create my local users at this point so I don't need to log in with zlogin

# zlogin z1
[Connected to zone 'z1' console]                                   79/91

What type of terminal are you using?
 1) ANSI Standard CRT
 2) DEC VT52
 3) DEC VT100
 4) Heathkit 19
 5) Lear Siegler ADM31
 6) PC Console
 7) Sun Command Tool
 8) Sun Workstation
 9) Televideo 910
 10) Televideo 925
 11) Wyse Model 50
 12) X Terminal Emulator (xterms)
 13) CDE Terminal Emulator (dtterm)
 14) Other
Type the number of your choice and press Return: 3
Creating new rsa public/private host key pair
Creating new dsa public/private host key pair

Run the ifconfig command to see the interface aliasing

# ifconfig -a
lo0:1: flags=2001000849 mtu 8232 index 1
        inet 127.0.0.1 netmask ff000000 
hme0:1: flags=1000843 mtu 1500 index 2
        inet xxx.xxx.xxx.xxx netmask ffffff00 broadcast xxx.xxx.xxx.xxx 

Shutting Down and Removal

Had enough? Let's halt the system. It's probably better to login into the machine and shut it down using the shutdown command

# zoneadm -z z1 halt

Let's uninstall and delete the zone.

# zoneadm -z z1 uninstall
Are you sure you want to uninstall zone z1 (y/[n])? y

#  zonecfg -z z1 delete
Are you sure you want to delete zone z1 (y/[n])? y

NOTE -F option will not prompt

Create Special Filesystems

Want more? As I mentioned earlier the zone you previously created imports several OS directories read-only. If you need to be able to add packages to your zone which require these read-only mounts to can use a loopback mount. This example configures the zone z1 to autoboot, associates the IP address xxx.xxx.xxx.xxx and netmask 255.255.255.0 (/24) with the physical interface hme0, mounts /usr/share, /usr/sbin, /usr/bin and /usr/local as a read-only file systems, and copies the corresponding packaging metadata into the zone. Using a writable loopback mount, this example exports the global zone directory /export/z1/share, export/z1/sbin, /export/z1/bin and /export/z1/local into the zone under the name /usr/share, /usr/sbin, /usr/bin and /usr/local.

# cd /export
# mkdir z1
# cd z1
# mkdir share
# mkdir bin
# mkdir sbin
# mkdir local

chmod -R 775 z1

# zonecfg -z z1
z1: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:z1> create
zonecfg:z1> export
create -b
set autoboot=false
add inherit-pkg-dir
set dir=/lib
end
add inherit-pkg-dir
set dir=/platform
end
add inherit-pkg-dir
set dir=/sbin
end
add inherit-pkg-dir
set dir=/usr
end
zonecfg:z1> set zonepath=/zones/z1
zonecfg:z1> set autoboot=true
zonecfg:z1> add net
zonecfg:z1:net> set address=xxx.xxx.xxx.xxx
zonecfg:z1:net> set physical=hme0
zonecfg:z1:net> end
zonecfg:z1> add fs
zonecfg:z1:fs> set dir=/usr/share
zonecfg:z1:fs> set special=/export/z1/share
zonecfg:z1:fs> set type=lofs
zonecfg:z1:fs> set options=[rw,nodevices]
zonecfg:z1:fs> end
zonecfg:z1> add fs
zonecfg:z1:fs>  set dir=/usr/sbin
zonecfg:z1:fs>  set special=/export/z1/sbin
zonecfg:z1:fs>  set type=lofs
zonecfg:z1:fs> set options=[rw,nodevices]
zonecfg:z1:fs> end
zonecfg:z1> add fs
zonecfg:z1:fs> set dir=/usr/bin
zonecfg:z1:fs> set special=/export/z1/bin
zonecfg:z1:fs> set type=lofs
zonecfg:z1:fs>  set options=[rw,nodevices]
zonecfg:z1:fs> end
zonecfg:z1> add fs
zonecfg:z1:fs>  set dir=/usr/local
zonecfg:z1:fs> set special=/export/z1/local
zonecfg:z1:fs>  set type=lofs
zonecfg:z1:fs>  set options=[rw,nodevices]
zonecfg:z1:fs> end

zonecfg:z1> info
zonepath: /zones/z1
autoboot: true
pool: 
fs:
        dir: /usr/share
        special: /export/z1/share
        raw not specified
        type: lofs
        options: [rw,nodevices]
fs:
        dir: /usr/sbin
        special: /export/z1/sbin
        raw not specified
        type: lofs
        options: [rw,nodevices]
fs:
        dir: /usr/bin
        special: /export/z1/bin
        raw not specified
        type: lofs
        options: [rw,nodevices]
fs:
        dir: /usr/local
        special: /export/z1/local
        raw not specified
        type: lofs
        options: [rw,nodevices]
net:
        address: xxx.xxx.xxx.xxx
        physical: hme0


/dev/dsk/c0t0d0s3    4033806   55929 3937539     2%     /zones
/lib                 12101980 3293367 8687594    28%    /zones/z1/root/lib
/platform            12101980 3293367 8687594    28%    /zones/z1/root/platform
/sbin                12101980 3293367 8687594    28%    /zones/z1/root/sbin
/usr                 12101980 3293367 8687594    28%    /zones/z1/root/usr
/export/z1/share     12101980 3293367 8687594    28%    /zones/z1/root/usr/share
/export/z1/sbin      12101980 3293367 8687594    28%    /zones/z1/root/usr/sbin
/export/z1/bin       12101980 3293367 8687594    28%    /zones/z1/root/usr/bin
/export/z1/local     12101980 3293367 8687594    28%    /zones/z1/root/usr/local
/export/z1/lib       12101980 3293367 8687594    28%    /zones/z1/root/usr/lib

Using Zones With Sendmail Switch 3.2

I have not performed extensive testing using Sendmail Switch 3.2 in conjunction with Solaris 10 Zones. However I have used zones to enable me to install several Sendmail Switch MTA's for the purpose of simulating numerous remote Switch test clients.
By default, the zonecfg "create" command produces a zone that inherits /usr, /platform, /sbin and /lib as read-only mounts from the global zone (parent machine's filesystem). The Switch installation leads the user to install the Switch binaries under /usr/local/sendmail. You will not have the permissions to write to /usr/local when incorporating the read-only /usr. There are various things you could do to workaround this issue namely using the loopback mounts as described in a previous section. You could choose and alternative location for the Switch installation however you will still run into problems when the installer attempt to create links to other read-only filesystems (like /sbin). Each of these linked directories need to be special mounted in loopback mode. It gets ugly.
I have found that the only sure-fire way , without complications, is to create a full zone using the zonecfg "create -b" option. Doing this consumes a considerable amount of diskspace. It is recommended that you minimized the size of the global zone so that the cloned zones will be smaller. Here is a jumpstart profile of the Solaris 10 packages I personally used. Following this model enables you to install Switch without problems.

If you are interested in scripts here is the zones.sh based on one that Sun made available. This script is used to create a number of zones using sequential ip address and zone names suffixes.

Use clean_zones.sh to remove the zones you've made.

updated: 06Oct06