Solaris 10 zones: part one – a working example

Many of you have already heard about Solaris 10 zones – it’s a virtualization technology which allows you to create isolated and secure environments for running applications. For end-users these environments look just like separate abstract machines with Solaris 10 installed on them. Inside each zone, all the processes don’t see anything happening in all the other zones on a system. Isolation is done on such a level that processes of one zone can’t see or affect processes of any other zone.

All of this is done on a software level, and by default every Solaris 10 machine has a global zone – only from this zone you can view processes of all the rest zones on your system. You probably didn’t even notice, but upon the completion of your Solaris 10 install, you’re immediately put into the global zone. It’s very easy to see this zone:

solaris# zoneadm list -vc
ID NAME             STATUS         PATH
0 global           running        /

To create a non-global zone, just plan some hard drive space for it, and work away! You’re going to need a zonecfg command. You must specify a zone name as a command line parameter:

solaris# zonecfg -z zone3

If the zone specified doesn’t exist, you’ll see a message about it, and zonecfg will put you into it’s command interface, where you can manage or create zones. Type the following (line by line):

solaris# zonecfg -z zone3
zone3: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:zone3> create
zonecfg:zone3> set zonepath=/sr/zones/3
zonecfg:zone3> set autoboot=false
zonecfg:zone3> add net
zonecfg:zone3:net> set address=192.168.0.7
zonecfg:zone3:net> set physical=bge0
zonecfg:zone3:net> end
zonecfg:zone3> verify
zonecfg:zone3> exit

This set of commands will create you a simple zone. There aren’t that many parameters initially, as you can see:

  • zonepath is the full path to the directory where the specified zone’s files will reside
  • autoboot is a flag used to determine whether a non-global zone should be automatically booted up every time your actual system (with your global zone) boots.

Further on, we’re assigning one network interface to our zone, and give it an IP address. You should specify the name of the real network interface present in your global zone. For the zone you’re creating, zonecfg will have a virtual interface based off the real one you specify.

Now it’s time to verify your config – this command makes sure all the necessary parameters have got their values set. After this, we’re done.

Now, if you look at the list of your zones again, you’re going to see a newly created zone as well:

solaris# zoneadm list -vc
ID NAME             STATUS         PATH
0 global           running        /
- zone3            configured     /sr/zones/3

Right now our zone is in a “configured” state – it can’t be used until we install OS onto it and it gets its unique ID. Obviously, you won’t be able to boot your zone unless it has installed OS.

Here’s a list of the states a non-global zone can be in:

  • configured – our zone is configured, but it’s yet to have its initial boot
  • incomplete – zoneadm command sets a zone’s state to this value while installing and uninstalling a zone. When the operation is completed, zone’s status is changed.
  • installed – zone is fully configured, OS packages have been installed. It’s a ready-to-use zone, all you have to do is to boot it. The zone has no virtual platform associated yet.
  • ready – the zone is ready. It already has a virtual platform established, the kernel has created a zsched process, all the network interfaces are plumbed, devices are configured and file systems are mounted. No processes have been started yet, but since the zone is ready it already has a unique ID assigned to it. We normally don’t see a zone in this state, and it always moves one to the next one – running.
  • running – the zone is up and running. You can connect to the zone. It’s a fully working environment now.
  • shutting down and down are short-term states which are shown when the zone is being halted. Upon completion of halt, the zone gets back into installed state.

Now, it’s time to continue configuring our zone. We should install it. It is done with the following command:

solaris# zoneadm -z zone3 install

After this you can watch the process of packages installation for your zone, and when all the packages are installed, you’ll get the location of the OS installation log file. That’s it! Our zone is ready, and you can boot it:

solaris# zoneadm -z zone3 boot

Wonderful. But we still can’t log in… Why? Because we’ve yet to configure the OS inside our zone – just like we would configure any box we’ve just installed with Solaris. As you’ve noticed, the order of OS installation is slightly different – in real life you have to configure the box first, and then you get to watch all the packages installing on it, with zones it’s the other way around – first copy all the stuff, then configure the OS.

What we need now is connect to the zone’s console and answer all the standard Configuration Assistant’s questions, one of them is the root password. After this, your zone will want to reboot, and you’ll be able to log in as root on your console. If you want to allow remote root logins, you’ll obviously need to add theCONSOLE=/dev/console line to /etc/default/login.

To reach a zone’s console, you should use zlogin command, -C means “console”:

solaris# zlogin -C zone3

You can disconnect from the console using the standard combination: “~.” (tilda dot)

One more thing. Since non-global zones will share the physical network interface with your global zone – you’ve got to make sure your system (your global zone) can see your non-global zones networks.

For instance, here’s the ifconfig -a from my laptop:

bge0:1: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
zone zone2
inet 192.168.0.6 netmask ffffff00 broadcast 192.168.0.255
bge0:2: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
inet 192.168.0.2 netmask ffffff00 broadcast 192.168.0.255
bge0:3: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
zone zone1
inet 192.168.0.5 netmask ffffff00 broadcast 192.168.0.255

As you can see, interfaces assigned to zones are marked with the “zone” parameter. I had to create a virtual interface (bge0:2) from the same subnet as the IPs of my zones. This way, I can ping interfaces assigned to each of the zones configured.

One more thing I wanted to mention: software packages, installed in a zone. Most curious of you have probably looked inside the installation log file, and noticed, that most of the standard Solaris 10 packages have been installed in our zone. At the same time, the directory with our zone’s files takes up roughly 70mb…

Such an incostistancy is explained by one of the key features of the zones virtualization: non-global zones can easily share files with the global zone. Thus, you can specify for each zone, that some files (packages), when required by the installer, should not be actually copied and installed, but just borrowed from the global zone – every time you’ll want to access some of these files in your non-global zone, they’ll be taken from the ones in your actual system – from your global zone.

Obviously, all the files inherited in such a way by non-global zone, will be read-only.This technique allows you save lots of space, and by default all the files from /lib, /platform, /usr and /sbin directories are shared with the global zone. It is important to undestand that this happens only to the standard packages. So, if you’ve added some files of yours in the abovenamed directories, they will obviously NOT be shared with non-global zones.

Well, I guess it’s enough for the part one of my notes on Solaris zones – with any luck you should now have a working zone which you can access remotely – log in, manage services, do whatever you want.

I’ll add more stuff whenever I have a minute to spare….