Solaris provides an effective and simple method of creating virtual Solaris hosts- Solaris Zones. This article provides the procedures to create and run Solaris Zones under a Solaris 10 environment. It is meant to supplement and provide clarity to the documents provided by Sun Microsystems.

It does not cover all topics within Solaris Zones.  Further information can be obtained by reading the following documents.

As processing power and energy costs have increased over the last several years, so too has the need for maximum hardware utilization in datacenters. The high-end computing industry “killer app” in this regard is virtualization, which allows for the creation of distributed network services and hardware resource delegation within a single machine. Virtualization drastically reduces the investment in additional hardware needed to provide these services, a reduction which is multiplied when considering the potential savings on data center footprint and power requirements of a single system hosting multiple virtual servers compared with those of multiple physical servers.
Sun Microsystems’ primary offering in server virtualization is known as Solaris Zones. Solaris Zones allows the creation of multiple running instances of Solaris within the host instance, where each zone is restricted to a predetermined set of hardware resources, known as resource pools. For example, Sun’s T1 processor found in its midrange servers has up to 8 cores and each core is capable of 4 threads of execution.  Solaris views this as 32 virtual processors and each Solaris zone can be limited to a specific number or range of these virtual processors. Given a range, Solaris will automatically and dynamically increase or decrease the number of processors available to each zone depending on need. Multiple zones on the same system can be created this way, each providing a different service normally hosted on a separate physical server. IDC reports that the number of servers being virtualized is expected to triple in the next three years. When combined with the low cost, low power consumption, and advanced parallel processing capabilities of the Sun Microsystems servers using the coolthreads processors, Solaris Zones virtualization software is at the forefront of this growing virtualization market by helping a datacenter improve hardware utilization, reduced costs, and maximum ROI.

Test Platform
Sun Microsystems T5140 server with two T2+ processors, 8GB RAM.
(Each processor has 6 processor cores and there are 8 cores per thread.  The system views this as 96 virtual processors.)
Running Solaris 10 05/08

# /usr/sbin/psrinfo -pv
The physical processor has 48 virtual processors (0-31 40-55)
UltraSPARC-T2+ (cpuid 0 clock 1167 MHz)
The physical processor has 48 virtual processors (64-111)
UltraSPARC-T2+ (cpuid 64 clock 1167 MHz)

# /usr/sbin/psrinfo | wc -l
96

Procedure

Step 1: Enable Dynamic Resource Pools

Dynamic resource pools allow your zones to adjust the amount of CPU and memory resources as need requires.  In order to enable this functionality you have to enable two solaris services, the resource pool service and the dynamic resource pools service.
(svc:/system/pools:default and svc:/system/pools/dynamic:default.)
The resource pools service allows for the creation and use of resource pools.
The dynamic resource pools service, which is dependent on the resource pools service, allows for the dynamic adjustment of resources within each resource pool in response to changing workloads on the system.

To enable these two services run the following commands.
# svcadm enable svc:/system/pools:default
# svcadm enable svc:/system/pools/dynamic:default

Step 2: Creating Solaris Zones

Terminology

Global Zone vs. Non-Global Zones:
In Solaris 10 terminology there is always at least one zone, the global zone.  When a clean install of Solaris is done on a server, this is considered the global zone.
Non-Global zones are any other zones that are created underneath the global zone.

Sparse Root Zone vs. Whole Root Zone:
When a Solaris Zone is created a set of packages will be copied to the directory that will act as the root file system for that non-global zone.  Some directories of the global zone can be shared to non-global zones.  For instance, the /usr directory holds many binaries and libraries that are used by system users and administrators and remains pretty static.  For most non-global zones there is no need to have a unique copy of the /usr directory as this will use an additional 3-4GB of disk space.  So, the /usr directory of the global zone will be mounted as a read-only file system to the /usr directory of the non-global zone.
By default Solaris creates sparse root zones.  The following directories are mounted in the non-global zone from the global zone.

  • /usr
  • /lib
  • /sbin
  • /platform

Note: In Solaris 10 /lib is not a symbolic link to /usr/lib.

When certain applications are installed in a non-global zone it is necessary for that zone to have it’s own copy of these directories.  Also, if you want to be able to patch each zone individually, you should install whole root zones. A whole root zone will have it’s own version of all Solaris directories so the administrator of that zone will be able install software packages and patches that will add or modify content within these directories.

A sparse-root zone requires a minimum of 700MB.
A whole-root zone requires a minimum of 5GB.

In the following examples ZONE1 will be a sparse root zone and ZONE2 will be a whole root zone.

ZONE1

Configuration of ZONE1:
In this example ZONE1 will be created and will be limited 4-8 CPU’s and capped at 4G of physical memory.  The /export/zones/ZONE1 directory will be used as the root for this non-global zone.  A non-global zone will require a minimum of 700MB of disk space in the file system that the zone is created in.
An IP address for ZONE1 will need to be set in the /etc/hosts file of the global zone.
The nxge0 interface needs to be plumbed and active on the global zone.  The non-global zone will create a virtual IP on this interface, for example nxge0:1.

# zonecfg -z ZONE1
Use ‘create’ to being configuring a zone
zonecfg:ZONE1> create
zonecfg:ZONE1> set zonepath=/export/zones/ZONE1
zonecfg:ZONE1> set autoboot=true
zonecfg:ZONE1> add net
zonecfg:ZONE1:net> set address=ZONE1
zonecfg:ZONE1:net> set physical=nxge0
zonecfg:ZONE1:net> end
zonecfg:ZONE1> add dedicated-cpu
zonecfg:ZONE1:dedicated-cpu> set ncpus=4-8
zonecfg:ZONE1:dedicated-cpu> end
zonecfg:ZONE1> add capped-memory
zonecfg:ZONE1:capped-memory> set physical=4g
zonecfg:ZONE1:capped-memory> set swap=512m
zonecfg:ZONE1:capped-memory> set locked=512m
zonecfg:ZONE1:capped-memory> end
zonecfg:ZONE1> verify
zonecfg:ZONE1> commit
zonecfg:ZONE1> exit

Explanation of configuration steps:

1) create
create a zones configuration file.  This steps creates the /etc/zones/ZONE1.xml file to hold the configuration for this zone.

2) set zonepath=/export/zones/ZONE1
set the location for where the zone will be installed

3)  set autoboot=true
Configure this zone to boot automatically when the global zone boots up.  Options are either true or false.

4) add net
Begin network configuration for the zone.

a) set address=ZONE1
Set the IP address for this zone to the IP address for ZONE1 as listed in /etc/hosts.
Alternately you could give the IP address.  (set address=192.168.1.100)

b) set physical=nxge0
Configure which physical interface to use for communication.  This will cause a virtual network adapter to be created on this physical NIC when this zone boots.

c) end
End the configuration for this network adapter.

5) add dedicated-cpu
Begin configuration of CPU allocation for the zone

a) set ncpus=4-8
The zone will have a minimum of 4 CPU’s and a maximum of 8 CPU’s depending upon the need of the zone.

b) end
End the dedicated CPU configuration settings for the zone

6) add capped-memory

a) set physical=4g
The zone will use a maximum of 4G of the system’s memory.

b) set swap=512m
The zone will use a maximum of 512G of the system’s swap space

c) set locked=512m
The zone will lock 512m of memory for use exclusively by this zone.

d) end
End the capped memory configuration for the zone.

7) verify
Verify the configuration does not have any errors and create a checksum in the /etc/zones/index file.

8) commit
Commit the configuration to the /etc/zones/ZONE1.xml

9) exit
Exit out of the zone configuration utility.

Take a look at the /etc/zones/ZONE1.xml file.

# cat /etc/zones/ZONE1.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE zone PUBLIC “-//Sun Microsystems Inc//DTD Zones//EN” “file:///usr/share/lib/xml/dtd/zonecfg.dtd.1″>
<!–
DO NOT EDIT THIS FILE.  Use zonecfg(1M) instead.
–>
<zone name=”ZONE1″ zonepath=”/export/zones/ZONE1″ autoboot=”true”>
<inherited-pkg-dir directory=”/lib”/>
<inherited-pkg-dir directory=”/platform”/>
<inherited-pkg-dir directory=”/sbin”/>
<inherited-pkg-dir directory=”/usr”/>
<network address=”ZONE1″ physical=”nxge0″/>
<pset ncpu_min=”4″ ncpu_max=”8″/>
<rctl name=”zone.max-swap”>
<rctl-value priv=”privileged” limit=”536870912″ action=”deny”/>
</rctl>
<rctl name=”zone.max-locked-memory”>
<rctl-value priv=”privileged” limit=”536870912″ action=”deny”/>
</rctl>
<mcap physcap=”4294967296″/>
</zone>

Notice the bold lines indicating the directories that will be shared from the global zone.  These directories will be read-only within the zone.  This means that packages and patches that update these directories, specifically /usr, can not be installed directly on the zone.

Note:  Do not edit the /etc/zones/*.xml files directly.  A checksum of the zone configuration is held in the /etc/zones/index file.  In order the keep the checksum updated with the zones configuration you must edit zones with the zonecfg command and use the verify statement to update the index.  If the checksum in the index file does not match the checksum of the zones XML file, the zone will not boot.

ZONE2

ZONE2 will be configured as a whole root zone.  Follow this set of commands to create a whole root zone.

# zonecfg -z ZONE2
Use ‘create’ to being configuring a zone
zonecfg:ZONE2> create
zonecfg:ZONE2> set zonepath=/export/zones/ZONE2
zonecfg:ZONE2> set autoboot=true
zonecfg:ZONE2> add net
zonecfg:ZONE2:net> set address=ZONE2
zonecfg:ZONE2:net> set physical=nxge0
zonecfg:ZONE2:net> end
zonecfg:ZONE2> add dedicated-cpu
zonecfg:ZONE2:dedicated-cpu> set ncpus=4-8
zonecfg:ZONE2:dedicated-cpu> end
zonecfg:ZONE2> add capped-memory
zonecfg:ZONE2:capped-memory> set physical=4g
zonecfg:ZONE2:capped-memory> set swap=512m
zonecfg:ZONE2:capped-memory> set locked=512m
zonecfg:ZONE2:capped-memory> end
zonecfg:ZONE2> remove inherit-pkg-dir dir=/usr
zonecfg:ZONE2> remove inherit-pkg-dir dir=/platform
zonecfg:ZONE2> remove inherit-pkg-dir dir=/lib
zonecfg:ZONE2> remove inherit-pkg-dir dir=/sbin
zonecfg:ZONE2> verify
zonecfg:ZONE2> commit
zonecfg:ZONE2> exit

In this example the remove inherit-pkg-dir statements are added so that the zone will create it’s own copy of these directories when you install the zone.

Step 3: Installing Solaris Zones

The following command will install the Solaris files into the zonepath.  This step will take approximately 15 minutes to complete.

# zoneadm -z ZONE1 install
Preparing to install zone <ZONE1>.
Creating list of files to copy from the global zone.
Copying <7168> files to the zone.
Initializing zone product registry.
Determining zone package initialization order.
Preparing to initialize <1164> packages on the zone.
Initializing package <41> of <1164>: percent complete: 3%

When the zone finishes installing it will be ready to boot.  To verify that the zone has been installed you can run the following command.

# zoneadm list -vi
ID NAME             STATUS     PATH                        BRAND    IP
0 global           running    /                                            native   shared
- ZONE1         installed  /export/zones/ZONE1            native   shared

Step 4: Booting and Logging Into Solaris Zones

To boot the zone execute the following command.

# zoneadm -z ZONE1 boot

To log into the zone through a virtual console sessions, execute the following command.

# zlogin -C ZONE1

Other Commands

To bring a zone down:
# zoneadm -z ZONE1 halt

To uninstall a zone:
# zoneadm -z ZONE1 uninstall

To delete a zone’s configuration:
# zonecfg -z ZONE1 delete