DevOps

Wednesday, 16 October 2013

Solaris Zones

Introduction to Solaris Zones Software

The Solaris Zones feature is based on the same basic concepts as FreeBSD. 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.
Two types of zones exist: global and non-global. A machine with the Solaris Zones feature enabled has one global zone and up to 8191 non-global zones. The maximum number of zones that a machine supports is dependent on the hardware resources available to the machine. Each zone has an ID assigned by the system when it's booted with the global zone, always listed as zone ID 0. Only the global zone contains a bootable Solaris kernel and is aware of all devices, file systems, and other zones. The global zone is also the only zone from which non-global zone configuration, installation, and management are possible.
Non-global zones contain a subset of the Solaris OS installed in the global zone and possibly additional packages not installed in the global zone. Each non-global zone has its own package database listing each software package installed relative to the zone and does not share package information with the global or other non-global zones. Non-global zones also contain localized configuration information and other zone-specific files and directories.

Configuring a Non-Global Zone

Non-global zones are created by the administrator of the global zone using the zonecfg and zoneadm commands. The zonecfg command allows the administrator to build a zone configuration specification from the template of the global zone. For complete information on the zonecfg and zoneadm commands, see their respective Man pageson BigAdmin. The syntax of the zonecfg 

command is:
zonecfg -z zonename
zonecfg -z zonename subcommand
zonecfg -z zonename -f command_file
zonecfg help
Subcommands to the zonecfg command are:
add <resource-type>
                (global scope)
add <property-name> <property-value>
                (resource scope)
cancel
commit
create [-F] [ -b | -t <template> ]
delete [-F]
end
exit [-F]
export [-f output-file]
help [commands] [syntax] [usage] [<command-name>]
info [<resource-type> [property-name=property-value]*]
remove <resource-type> { <property-name>=<property-value> }
                (global scope)
remove <property-name>=<property-value>
                (resource scope)
revert [-F]
select <resource-type> { <property-name>=<property-value> }
set <property-name>=<property-value>
verify
To set up a basic zone, run zonecfg in interactive mode and issue the create and set zonepath directives. The export directive prints out the current configuration information in a form suitable for saving to a file. Since no modifications have been made at this point, the export directive lists the default configuration:
zonecfg -z myzone
zonecfg:myzone> create
zonecfg:myzone> 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

Make any modifications to the default template at this point. This example configures the zone myzone to autoboot, associates the IP address 192.168.1.7 and netmask 255.255.255.0 (/24) with the physical interface hme0, mounts /opt/sfw as a read-only file system, and copies the corresponding packaging metadata into the zone. Using a writable loopback mount, this example exports the global zone directory /data into the zone under the name /usr/local.
zonecfg:myzone> set zonepath=/zones/myzone
zonecfg:myzone> set autoboot=true
zonecfg:myzone> add net
zonecfg:myzone:net> set address=192.168.1.7/24
zonecfg:myzone:net> set physical=hme0
zonecfg:myzone:net> end
zonecfg:myzone> add inherit-pkg-dir
zonecfg:myzone:inherit-pkg-dir> set dir=/opt/sfw
zonecfg:myzone:inherit-pkg-dir> end
zonecfg:myzone> add fs
zonecfg:myzone:fs> set dir=/usr/local
zonecfg:myzone:fs> set special=/data
zonecfg:myzone:fs> set type=lofs
zonecfg:myzone:fs> add options [nodevices]
zonecfg:myzone:fs> end
zonecfg:myzone> verify
zonecfg:myzone> export
create -b
set zonepath=/zones/myzone
set autoboot=true
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
add inherit-pkg-dir
set dir=/opt/sfw
end
add fs
set dir=/usr/local
set special=/data
set type=lofs
add options nodevices
end
add net
set address=192.168.1.7/24
set physical=hme0
end
zonecfg:myzone> commit
zonecfg:myzone> export -f /tmp/myzone-zone.cfg
zonecfg:myzone> exit


The zone is now configured and the template used to do so is saved to /tmp/myzone-zone.cfg. This file can later be used to configure the same zone, or slight modifications can be made (such as the IP address) so it can be used to configure a similar zone using zonecfg -z secondzone -f /tmp/myzone-zone.cfg. Now it's time to install the zone with the zoneadm command. The zoneadm command has the following syntax:
zoneadm -z zonename subcommand [options]
zoneadm [-z zonename] list [options]
zoneadm help
And the zoneadm command has the following subcommands:
boot
halt
help [subcommand]
install
list [-cipv]
ready
reboot
uninstall [-F]
verify

Installing and Booting a Non-Global Zone
To install the zone, simply issue the command:
zoneadm -z myzone install
Preparing to install zone <myzone>.
Creating list of files to copy from the global zone.
Initializing zone product registry.
Determining zone package initialization order.
Preparing to initialize <779> packages on the zone.
Initialized <779> packages on zone.
Successfully initialized zone <myzone>.

Now boot the zone to bring up the zone's runtime environment, and log into the zone's console with zlogin. To log out of the zone's console, press the key sequence ~. (tilde-dot).
zoneadm -z myzone boot
zlogin -C myzone


Since this is the initial boot for the zone after its installation, it has no internal naming configuration and will prompt for the necessary information via the console. The hostname of the zone defaults to the zone name. The chosen name should resolve to one of the zone's IPv4 addresses based on the zone's internal naming services (DNS, LDAP, files, NIS, NIS+, and others). The zone can use completely separate naming services from the global zone, and even where identical naming services are configured, they are run completely independently.
The zone uses sysidcfg to perform the configuration, so the screens should look like those encountered after a sys-unconfig or during an initial install of the OS. Most of the information required at this point can be preconfigured by creating the file sysidcfg in the zone's /etc directory prior to booting the zone for the first time. The zone can also be unconfigured with the sys-unconfig command. See the man pages on sysidtool(1M) and sysidcfg(4) for more information.
The state of each running zone can be seen from the global zone by executing:

zoneadm list -v
   ID NAME             STATUS         PATH
    0 global           running        /
    2 myzone           running        /zones/myzone
This verifies that the new zone is now booted and ready for use. If the zoneadm list -v command is run from within the non-global zone, it will only show the non-global zone. The zonename command can be run from within a zone to display the name of the currently running zone.

A newly booted zone is similar to a newly installed machine. There are no user accounts or configuration settings other than the system defaults, so the first step in preparing the new zone for production use is to create accounts, add additional software, and customize the zone's configuration. The administrator of the global zone can then log in as a normal user in the non-global zone by specifying the -l flag to zlogin:
zlogin -l user zonename


The zlogin command can also be run from the global zone in non-interactive mode to run commands inside a specified zone. To execute an ls -al / in myzone, one would do the following as the administrator from the global zone:
zlogin myzone ls -al /
total 126
drwxr-xr-x  19 root  other  512 Mar  8 12:45 .
drwxr-xr-x  19 root  other  512 Mar  8 12:45 ..
lrwxrwxrwx   1 root  root     9 Mar  8 12:03 bin -> ./usr/bin
drwxr-xr-x   2 root  other  512 Mar  8 12:02 data
drwxr-xr-x  10 root  other 1024 Mar  8 12:45 dev
drwxr-xr-x  51 root  sys   3584 Mar  8 13:36 etc
drwxr-xr-x   2 root  sys    512 Feb 12 11:42 export
dr-xr-xr-x   1 root  root     1 Mar  8 12:45 home
drwxr-xr-x   5 root  sys    512 Mar  8 12:03 kernel
drwxr-xr-x   4 root  bin   4608 Feb 12 12:17 lib
drwxr-xr-x   2 root  sys    512 Mar  8 12:04 mnt
dr-xr-xr-x   1 root  root     1 Mar  8 12:45 net
drwxr-xr-x   5 root  sys    512 Mar  8 12:03 opt
drwxr-xr-x  43 root  sys   1536 Feb 12 11:52 platform
dr-xr-xr-x  64 root  root 30400 Mar  8 16:27 proc
drwxr-xr-x   2 root  sys   1024 Feb 12 11:48 sbin
drwxrwxrwt   4 root  sys    314 Mar  8 16:19 tmp
drwxr-xr-x  38 root  other 1024 Jul 18  2003 usr
drwxr-xr-x  33 root  sys    512 Mar  8 12:45 var
The non-interactive mode of zlogin is especially useful in running scripts to administer non-global zones. The zlogin command also provides a failsafe mode (-S) to connect to a non-global zone in the event that a zone becomes damaged and will not accept logins.
To delete the zone myzone, shut it down, remove the root file system with zoneadm uninstall, and issue the zonecfg with the delete argument:
zlogin myzone shutdown -y -i0 -g0
zoneadm -z myzone uninstall -F
zonecfg -z myzone delete -F

Obtaining and Setting Non-Global Zone Information from the Global Zone
In addition to the use of zonecfg, zoneadm, zonename, and zlogin, a variety of standard system commands have been modified so that zone information can be viewed or modified from the global zone.

Process Controls

The ps command now has formatting options, -o zone and -o zoneid, that print out the zone name or zone ID of a process. One can then grep for the zone name or zone ID to get a listing of only those processes in the specified zone(s):
/bin/ps -efo user,zone,pid,ppid,c,stime,tty,time,comm |grep myzone
  root myzone 18386     1  0 12:45:24 ?      00:00 /usr/sbin/syslogd
  root myzone 18527     1  0 12:47:04 ?      00:00 /usr/lib/ssh/sshd
  root myzone 18630 18527  0 13:38:26 ?      00:03 /usr/lib/ssh/sshd
  root myzone 18300     1  0 12:45:22 ?      00:00 init
  root myzone 18512     1  0 12:45:33 ?      00:01 /usr/sfw/sbin/snmpd
  root myzone 18399     1  0 12:45:24 ?      00:00 /usr/sbin/cron
  root myzone 18638 18634  0 13:38:31 pts/2  00:00 -sh
  root myzone 18523 18300  0 12:47:03 ?      00:00 /usr/lib/saf/sac
  root myzone 18401     1  0 12:45:25 ?      00:00 /usr/lib/autofs/automountd
daemon myzone 18324     1  0 12:45:23 ?      00:00 /usr/lib/crypto/kcfd
  root myzone 18656 18638  0 13:44:26 pts/2  00:00 tcsh
daemon myzone 18349     1  0 12:45:23 ?      00:00 /usr/sbin/rpcbind
  root myzone 18400     1  0 12:45:24 ?      00:00 /usr/sbin/nscd
  root myzone 18402     1  0 12:45:25 ?      00:00 /usr/sbin/inetd
 smmsp myzone 18435     1  0 12:45:29 ?      00:00 /usr/lib/sendmail
  root myzone 18434     1  0 12:45:29 ?      00:00 /usr/lib/sendmail
  root myzone 18442     1  0 12:45:29 ?      00:00 /usr/lib/utmpd
  root myzone 18297     1  0 12:45:09 ?      00:00 zsched
  root myzone 18618 18300  0 13:37:58 zoneconsole \
                                             00:00 /usr/lib/saf/ttymon
  root myzone 18496     1  0 12:45:31 ?      00:00 /usr/dt/bin/dtlogin
  root myzone 18526 18523  0 12:47:03 ?      00:00 /usr/lib/saf/ttymon

A number of commands have been enhanced to filter the information they print by zone or to include in their input the zone that a process belongs to. The commands ipcs, pgrep, pkill, ptree, and prstat now include a -z flag to specify a zone. Additionally, prstat has a -Z flag to list all processes but also a summary by zone ID. This helps quickly identify which zone is using the most resources. The truss program has also been modified to know about Zone-specific calls but is not yet Zone-aware.
In the Solaris OS, coreadm can be used to set the core file name pattern. The pattern now includes %z for zone name. For example, if the core file name pattern were set to /var/core/core.%f.%p.%z in the global zone, the core for a program named foo with the PID of 123 running in the zone myzone would be: /var/core/core.foo.123.myzone. The zone administrator can also run coreadm inside a non-global zone to control settings for that specific zone.

File Systems
When run from the global zone, the -Z flag to df displays mounts in all zones. By default, df only displays mounts located within the current zone.
df -Z
/                  (/dev/dsk/c0t1d0s0 ):      1881482 blocks   247016 files
/devices           (/devices          ):            0 blocks        0 files
/usr               (/dev/dsk/c0t1d0s3 ):       859490 blocks   271499 files
/proc              (proc              ):            0 blocks     1837 files
/etc/mnttab        (mnttab            ):            0 blocks        0 files
/dev/fd            (fd                ):            0 blocks        0 files
/var               (/dev/dsk/c0t1d0s4 ):      1889810 blocks   239530 files
/var/run           (swap              ):      2111168 blocks    15280 files
/tmp               (swap              ):      2111168 blocks    15280 files
/zones             (/dev/dsk/c0t1d0s5 ):     60468666 blocks  3681959 files
/zones/myzone/root/dev(/zones/myzone/dev  ): 60468666 blocks  3681959 files
/zones/myzone/root/lib(/lib               ):  1881482 blocks   247016 files
/zones/myzone/root/opt/sfw(/opt/sfw       ): 60468666 blocks  3681959 files
/zones/myzone/root/platform(/platform     ):  1881482 blocks   247016 files
/zones/myzone/root/sbin(/sbin             ):  1881482 blocks   247016 files
/zones/myzone/root/usr(/usr               ):   859490 blocks   271499 files
/zones/myzone/root/usr/local(/data        ):  1881482 blocks   247016 files
/zones/myzone/root/proc(proc              ):        0 blocks     1837 files
/zones/myzone/root/etc/mnttab(mnttab      ):        0 blocks        0 files
/zones/myzone/root/dev/fd(fd              ):        0 blocks        0 files
/zones/myzone/root/var/run(swap           ):  2111168 blocks    15280 files
/zones/myzone/root/tmp(swap               ):  2111168 blocks    15280 files
Networking
The ifconfig utility has been modified in order to configure and view interfaces based on zone granularity as well, but interfaces can only be plumbed or unplumbed from the global zone. To place an IP interface inside a zone from the global zone:
ifconfig <interface> zone {<name> | <number>}
ifconfig hme0:3 plumb 192.168.1.8 netmask 255.255.255.0 zone myzone up
To print the list of IP interfaces limited to the global zone from the global zone, use ifconfig -aZ. Using ifconfig -a shows network interfaces for all zones.
ifconfig -a
lo0: flags=1000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4>
         mtu 8232 index 1
         inet 192.168.1.7 netmask ff000000
lo0:1: flags=1000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4>
         mtu 8232 index 1
         zone myzone
         inet 127.0.0.1 netmask ff000000
hme0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4>
         mtu 1500 index 2
         inet 192.168.1.4 netmask ffffff00 broadcast 192.168.1.255
         ether 8:0:20:9e:b5:40
hme0:1: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4>
         mtu 1500 index 2
         zone myzone
         inet 192.168.1.7 netmask ffffff00 broadcast 192.168.1.255

ifconfig -aZ
lo0: flags=1000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4>
         mtu 8232 index 1
         inet 192.168.1.7 netmask ff000000
hme0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4>
         mtu 1500 index 2
         inet 192.168.1.4 netmask ffffff00 broadcast 192.168.1.255
         ether 8:0:20:9e:b5:40
Accounting
When using extended accounting (exacct), each zone is configured separately. Records are written to both the global zone's accounting files as well as the individual zones' accounting files. Both task and process accounting records now have a new field named zonename. This identifies the zone to which the process or task belongs.


No comments:

Post a Comment