Tuesday 18 February 2014

Oracle Solaris 11 in the Cloud



Lab Introduction
Within cloud environments, multiple considerations and functionality are key to building a successful cloud. These can be grouped into five main areas:
  • Rapid deployment
  • Flexibility
  • Availability
  • Security
  • Monitoring
To demonstrate how Oracle Solaris can provide the best cloud environment, this lab will describe how to set up a multilayer application environment. The lab will effectively create a cloud in a box, along the way touching on each of the main areas.
The final environment will consist of a WordPress blog contained within an Oracle Solaris Zone. The application environment will be supported by a web server and a database.
During this lab, you will learn how Oracle Solaris 11 places cloud at its core, integrating the cloud with key Oracle Solaris 11 features.
Prerequisites
You should have the following:
  • A basic familiarity with Oracle Solaris administration operations
  • A basic understanding of virtual environments
The Environment
You will be working on an Oracle Solaris 11 instance contained within an Oracle VM VirtualBox environment. You can treat the Oracle Solaris 11 instance as a bare-metal installation as far as the lab is concerned.
  • User: ouser
  • Password: Oracle123
  • Root password: solaris11
Lab Outline
Table 1. Description of Exercises
Exercise
Name
Topics Covered
1
Configuring the System and Setting Up the Network
  • Look at the network setup.
  • Look at the storage setup.
2
Configuring the Storage Layer
  • Create ZFS file systems to store our Oracle Solaris Zones.
  • Create ZFS file systems to store our data.
3
Configuring the Web Layer
  • Configure the network, including creating a virtual switch and VNIC.
  • Create and install an Oracle Solaris Zone.
  • Configure a network from within the zone.
  • Add the AMP packages to the zone.
  • Enable the Apache service.
4
Configuring the Database Layer
  • Clone the web zone to create a database zone.
  • Configure a network from within the zone.
  • Configure and run the MySQL instance.
5
Configuring the Application Layer
Configure and install the WordPress blog application.
6
Monitoring Zones
Monitor system activity using ps, prstat, and zonestat.
7
Performing Resource Management
  • Add resource management to a zone.
  • Test resource management by putting a load on a zone.
8
Ensuring Availability
  • Use the svcs command to monitor services.
  • Observe services auto-restarting.
9
Securing the Environment
Create and test an immutable zone.

Lab Goals
At the end of the lab, you will have created two zones: one from a standard installation and one via cloning. You will have configured the network and added applications to those zones giving you your own blog, which has a three-tier environment consisting of application, middleware, and database.
At the end of the lab, your configuration should look something like Figure 1.

Figure 1. Layout of your finished environment.
Note: When this lab refers to the "global zone," it is referring to the default zone for the system, which is also used for system-wide administrative control.
Now that we understand what we are trying to do, in the exercises, we will go through the steps, including command-line examples, for exactly how to achieve our goals.
While going through this lab, refer to Figure 2 for a quick reminder of the settings we will use.

Figure 2. Cheat sheet of settings.
Exercise 1: Configuring the System and Setting Up the Network
In this portion of the lab, we will look at the settings on the system so you can see the differences as you progress though the lab.
First, let's look at how the system is currently configured.
Log in to your system:
user: ouser
password: Oracle123

Q: Why did we log in as ouser and not root?
A: Because in Oracle Solaris 11, root is now what we call a "role" and is no longer a user.

Open up a terminal window. For the rest of the lab, it will be useful to be root, so let's do that now:
ouser@solaris:~$ su -
Password: solaris11
Oracle Corporation      SunOS 5.11      11.1    September 2012
root@solaris:~#

Let's start by checking how the ZFS file system is set up:
root@solaris:~# zfs list
NAME                      USED  AVAIL  REFER  MOUNTPOINT
rpool                    15.3G  13.0G  4.90M  /rpool
rpool/ROOT               4.17G  13.0G    31K  legacy
rpool/ROOT/solaris       4.17G  13.0G  3.79G  /
rpool/ROOT/solaris/var    284M  13.0G   220M  /var
rpool/VARSHARE             54K  13.0G    54K  /var/share
rpool/dump               1.03G  13.1G  1.00G  -
rpool/export             5.19M  13.0G    32K  /export
rpool/export/home        5.16M  13.0G    32K  /export/home
rpool/export/home/ouser  5.13M  13.0G  5.13M  /export/home/ouser
rpool/repository         9.02G  13.0G  9.02G  /repository
rpool/swap               1.03G  13.1G  1.00G  -

Make a note of what file systems are present; you will need this information later.
Next, let's look at the network. There are some new commands in Oracle Solaris 11 that you will become very familiar with: ipadm and dladm.
ipadm let's you look at the IP stack, as shown in Listing 1. Let's see what interfaces and IP addresses we have:
root@solaris:~# ipadm show-if
IFNAME     CLASS    STATE    ACTIVE OVER
lo0        loopback ok       yes    --
net0       ip       ok       yes    --
root@solaris:~# ipadm show-addr
ADDROBJ           TYPE     STATE        ADDR
lo0/v4            static   ok           127.0.0.1/8
net0/v4           static   ok           192.168.1.222/24
lo0/v6            static   ok           ::1/128
Listing 1
Note in Listing 1 that we have a loopback interface (lo0) and a network interface (net0); both these interfaces have been assigned an IPv4 address. We can also see that net0 has been assigned its IPv4 address statically.
Now let's look at the data link layer using the dladm command, as shown in Listing 2:
root@solaris:~# dladm show-link
LINK                CLASS     MTU    STATE    OVER
net1                phys      1500   unknown  --
net0                phys      1500   up       --
root@solaris:~# dladm show-vnic
root@solaris:~# dladm show-etherstub
Listing 2
Note in Listing 2 that we can see we have two physical network interfaces and we have no VNICs or Etherstubs (don't worry you will learn what these are later).
Q: Why did net1 not show up in the ipadm command in Listing 1?
A: Because it has not been assigned an IP address.

Ok, now we are ready to set up the storage layer.
Exercise 2: Configuring the Storage Layer
For a full discussion on all the steps involved in creating and managing ZFS, please check out the Oracle Solaris 11.1 Administration: ZFS File Systems guide.
Before We Start
Check the status of the ZFS file system:
root@solaris:~# zfs list | grep zones
root@solaris:~# zfs list | grep mydata

Note: There are no ZFS data sets associated with any zones nor is there a ZFS data set for mydata.
Configure the Zone ZFS Data Set
We want a ZFS data set to put all our zone root directories in; it will be created in our root pool and mounted at /zones. Let's do that now:
root@solaris:~# zfs create -o mountpoint=/zones rpool/zones

Now, let's look at what that gives us:
root@solaris:~# zfs list rpool/zones
NAME         USED  AVAIL  REFER  MOUNTPOINT
rpool/zones   31K  13.0G    31K  /zones
root@solaris:~# ls /zones

Note that we don't actually have to do this step. The zone creation will actually do that for you; however, we do it here just so you see how easy it is to create a data set and give it a mount point of your choosing.
Configure the Database ZFS Data Set
We also want to create a separate file system to store MySQL data files. Later this will be assigned to the database zone. This enables the database zone administrator to manage this data set separately, for example, to change its compression and deduplication parameters, create snapshots, and so on.
root@solaris:~# zfs create rpool/mydata
root@solaris:~# zfs list rpool/mydata
NAME          USED  AVAIL  REFER  MOUNTPOINT
rpool/mydata   31K  13.0G    31K  /rpool/mydata

Exercise 3: Configuring the Web Layer
We will start by creating our web layer, which will involve setting up a network, creating and installing a zone, and adding an application into our zone. Let's start by configuring the network.
Configuring the Network
The Oracle Solaris instance you are using is configured with two internal networks. We can see them and what IP addresses they have by using the dladm and ipadm commands :
root@solaris:~# dladm show-link
LINK                CLASS     MTU    STATE    OVER
net1                phys      1500   unknown  --
net0                phys      1500   up       --

root@solaris:~# ipadm show-addr
ADDROBJ           TYPE     STATE        ADDR
lo0/v4            static   ok           127.0.0.1/8
net0/v4           static   ok           192.168.1.222/24
lo0/v6            static   ok           ::1/128

We are going to create an internal network to allow webzone and dbzone to communicate with each other. To do this, we will use an etherstub. We will connect to the etherstub using VNICs that we will dedicate to each of our zones (once we create them).
Q: What is an etherstub?
A: Etherstubs are pseudo Ethernet NICs that are managed by the system administrator. You can create VNICs over etherstubs instead of over physical links. VNICs over an etherstub become independent of the physical NICs in the system. With etherstubs, you can construct a private virtual network that is isolated both from the other virtual networks in the system and from the external network. The simple way to think of an etherstub is as an internal network switch.

First let's create the etherstub:
root@solaris:~# dladm create-etherstub vswitch0
root@solaris:~# dladm show-etherstub
LINK
vswitch0

Now we will create our first VNIC, and we will associate it with vswitch0:
root@solaris:~# dladm create-vnic -l vswitch0 webint0
root@solaris:~# dladm show-vnic
LINK                OVER         SPEED  MACADDRESS        MACADDRTYPE       VID
webint0             vswitch0     40000  2:8:20:de:f4:40   random            0

Configuring webzone
webzone will need to be configured and installed, and then a network needs to be set up and an application needs to be added to it.
Let's start by entering the configuration information for the zone we are about to create. By default, all that you need to supply to a zone to create it is its name and its zonepath (the place where the zone root will live; remember, we created the rpool/zones ZFS data set to hold this information). However, in this case we will take the opportunity to also add in the webint0 VNIC.
root@solaris:~# zonecfg -z webzone
Use 'create' to begin configuring a new zone.
zonecfg:webzone> create
create: Using system default template 'SYSdefault'
zonecfg:webzone> set zonepath=/zones/webzone
zonecfg:webzone> add net
zonecfg:webzone:net> set physical=webint0
zonecfg:webzone:net> end
zonecfg:webzone> verify
zonecfg:webzone> commit
zonecfg:webzone> exit

Q: What are the verify and commit commands?
A: These commands in zonecfg verify that the information is correct and then commit that configuration. It is good practice to use these commands when editing zone configuration information.

Installing webzone
Now, webzone is configured, but it is not installed yet. We could install it right now, but if we did, after the first boot we would have to log in to it and create a system profile that includes host name, time zone, root password, and so on. Another way of achieving this—and have our zone be ready to use right after the first boot—is to create its profile before installation. This way also enables the automation of future zone creation.
root@solaris:~# sysconfig create-profile -o /root/webzone-profile.xml

In the dialog box that appears, enter the following parameters:
Computer Name: webzone
Network connection:
None (we will configure networking later from within the zone)
Time Zone: Select your time zone (hint: when selecting the country, press its first letter, for example, U for United States)
Root password:
solaris11
User real name:
Zone User
User id:
zuser
User password:
oracle1
For everything else, accept the defaults, and then press F2 or ESC-2 to continue.
Now let's install the zone (this will take a few minutes to complete):
root@solaris:~# zoneadm -z webzone install -c /root/webzone-profile.xml
Progress being logged to /var/log/zones/zoneadm.20130812T145306Z.webzone.install
       Image: Preparing at /zones/webzone/root.

 AI Manifest: /tmp/manifest.xml.ZnaOeg
  SC Profile: /root/webzone-profile.xml
    Zonename: webzone
Installation: Starting ...

              Creating IPS image
Startup linked: 1/1 done
              Installing packages from:
                  solaris
                      origin:  http://192.168.1.222/
DOWNLOAD                                PKGS         FILES    XFER (MB)   SPEED
Completed                            183/183   33556/33556  222.2/222.2  328k/s

PHASE                                          ITEMS
Installing new actions                   46825/46825
Updating package state database                 Done
Updating image state                            Done
Creating fast lookup database                   Done
Installation: Succeeded

        Note: Man pages can be obtained by installing pkg:/system/manual

 done.

        Done: Installation completed in 1096.528 seconds.


  Next Steps: Boot the zone, then log into the zone console (zlogin -C)

              to complete the configuration process.

Log saved in non-global zone as /zones/webzone/root/var/log/zones/zoneadm.20130812T145306Z.webzone.install

Once installation is done, we can boot webzone and log in to its console:
root@solaris:~# zoneadm -z webzone boot; zlogin -C webzone
[Connected to zone 'webzone' console]
Loading smf(5) service descriptions: 116/116
Hostname: webzone

webzone console login: zuser
Password: oracle1
Oracle Corporation      SunOS 5.11      11.1    September 2012

Now let's exit the console using "~.":
zuser@webzone:~$ exit
logout
webzone console login: ~.
[Connection to zone 'webzone' console closed]

Setting Up a Network for webzone
Now we need to set up the webzone network, and log back in again using zlogin (see Listing 3). Note how we don't use the -C option and, hence, we don't connect to the console. Also note how we connect straight in with the root role. We'll do a quick check of the initial network setup using the ipadm and dladm commands, which you should be familiar with by now:
root@solaris:~# zlogin webzone
[Connected to zone 'webzone' pts/3]
Oracle Corporation      SunOS 5.11      11.1    September 2012
root@webzone:~# ipadm
NAME              CLASS/TYPE STATE        UNDER      ADDR
lo0               loopback   ok           --         --
   lo0/v4         static     ok           --         127.0.0.1/8
   lo0/v6         static     ok           --         ::1/128
root@webzone:~# dladm
LINK                CLASS     MTU    STATE    OVER
webint0             vnic      9000   unknown  ?
net0                vnic      1500   up       ?
Listing3
We don't have any IP addresses configured, but we have two data links available. Why two? We have configured only one interface using zonecfg. The second network interface, net0, is configured for us automatically. Even if we didn't configure any network using zonecfg, we would still have an automatic data link net0.
Now let's configure our IP interfaces for this zone. We need one interface to communicate with the outside world, and we are going to use net0 for that. We will assign a static IP address (though note that you could use DHCP here if you wanted to).
root@webzone:~# ipadm create-ip net0
root@webzone:~# ipadm
NAME              CLASS/TYPE STATE        UNDER      ADDR
lo0               loopback   ok           --         --
   lo0/v4         static     ok           --         127.0.0.1/8
   lo0/v6         static     ok           --         ::1/128
net0              ip         down         --         --

Now net0 appears in our IP stack, but it still has no IP address. Let's assign one now:
root@webzone:~# ipadm create-addr -T static -a 192.168.1.225/24 net0
net0/v4
root@webzone:~# ipadm
NAME              CLASS/TYPE STATE        UNDER      ADDR
lo0               loopback   ok           --         --
   lo0/v4         static     ok           --         127.0.0.1/8
   lo0/v6         static     ok           --         ::1/128
net0              ip         ok           --         --
   net0/v4        static     ok           --         192.168.1.225/24

Now let's try to ping the global zone on our newly created network:
root@webzone:~# ping 192.168.1.222
ping: sendto Network is unreachable

We are not able to ping the global zone, so let's check our routing table to make sure that is correct:
root@webzone:~# netstat -nr

Routing Table: IPv4
  Destination           Gateway           Flags  Ref     Use     Interface
-------------------- -------------------- ----- ----- ---------- ---------
127.0.0.1            127.0.0.1            UH        2          0 lo0      
192.168.1.0          192.168.1.225        U         3          1 net0     

Routing Table: IPv6
  Destination/Mask            Gateway                   Flags Ref   Use    If  
--------------------------- --------------------------- ----- --- ------- -----
::1                         ::1                         UH      2       0 lo0  

The routing is also configured correctly.
This issue is actually being caused because of the "secure by default" nature of Oracle Solaris, which enables strict firewalls for manually created network interfaces. Note that if we had assigned a static network when we did the system configuration step previously, we would not have seen this issue.
Let's investigate the settings and then disable the firewall service. Note that outside the lab, you would implement some rules to follow your security policies.
root@webzone:~# ipfstat -io
block out log all
pass out quick on lo0 all
pass out quick proto udp from any to any port = bootps
block in log all
pass in quick on lo0 all
pass in quick proto udp from any to any port = bootpc
root@webzone:~# svcadm disable svc:/network/ipfilter
root@webzone:~# ping 192.168.1.222
192.168.1.222 is alive

Let's finish up the network setup for webzone by configuring the network for our internal communications between webzone and dbzone, as shown in Listing 4:
root@webzone:~# ipadm create-ip webint0
root@webzone:~# ipadm create-addr -a local=10.0.3.10/24 webint0/v4
root@webzone:~# ipadm
NAME              CLASS/TYPE STATE        UNDER      ADDR
lo0               loopback   ok           --         --
   lo0/v4         static     ok           --         127.0.0.1/8
   lo0/v6         static     ok           --         ::1/128
net0              ip         ok           --         --
   net0/v4        static     ok           --         192.168.1.225/24
webint0           ip         ok           --         --
   webint0/v4     static     ok           --         10.0.3.10/24
Listing4
In Listing 4, note how we used a different format of the ipadm command this time (using local instead of static).
We also need to add host names to /etc/hosts for the WordPress installation.
root@webzone:~# echo '10.0.3.10 webzone' >> /etc/hosts
root@webzone:~# echo '10.0.3.11 dbzone' >> /etc/hosts
root@webzone:~# cat /etc/hosts
#
# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# Internet host table
#
::1 webzone localhost
127.0.0.1 webzone localhost loghost
10.0.3.10 webzone
10.0.3.11 dbzone

Adding Packages to webzone
The final step in the webzone installation is to add packages. We could install separate sets of packages into webzone and dbzone, but for simplicity sake we will install the full set of AMP (Apache, MySQL, PHP) packages into webzone and then clone webzone to create dbzone. We will use the pkg command. Note how all the package dependencies are worked out for us so we get everything we need using one simple command.
root@webzone:~# pkg install amp
           Packages to install: 45
           Mediators to change:  1
       Create boot environment: No
Create backup boot environment: No
            Services to change:  2

DOWNLOAD                                PKGS         FILES    XFER (MB)   SPEED
Completed                              45/45     4351/4351    93.7/93.7  845k/s

PHASE                                          ITEMS
Installing new actions                     5844/5844
Updating package state database                 Done
Updating image state                            Done
Creating fast lookup database                   Done

Let's check the contents of what we installed:
root@webzone:~# pkg list *apache*
NAME (PUBLISHER)                                  VERSION                    IFO
web/server/apache-22                              2.2.22-0.175.1.0.0.24.0    i--
web/server/apache-22/module/apache-dtrace         0.3.1-0.175.1.0.0.24.0     i--
web/server/apache-22/module/apache-fcgid          2.3.6-0.175.1.0.0.24.0     i--
web/server/apache-22/module/apache-php5           5.2.17-0.175.1.0.0.18      i-r
web/server/apache-22/module/apache-php52          5.2.17-0.175.1.0.0.24.0    i--

root@webzone:~# pkg list *php*
NAME (PUBLISHER)                                  VERSION                    IFO
web/php-52                                        5.2.17-0.175.1.0.0.24.0    i--
web/php-52/extension/php-apc                      3.0.19-0.175.1.0.0.24.0    i--
web/php-52/extension/php-idn                      0.2.0-0.175.1.0.0.24.0     i--
web/php-52/extension/php-memcache                 2.2.5-0.175.1.0.0.24.0     i--
web/php-52/extension/php-mysql                    5.2.17-0.175.1.0.0.24.0    i--
web/php-52/extension/php-pear                     5.2.17-0.175.1.0.0.24.0    i--
web/php-52/extension/php-suhosin                  0.9.29-0.175.1.0.0.24.0    i--
web/php-52/extension/php-tcpwrap                  1.1.3-0.175.1.0.0.24.0     i--
web/php-52/extension/php-xdebug                   2.0.5-0.175.1.0.0.24.0     i--
web/php-common                                    11.1-0.175.1.0.0.24.0      i--
web/server/apache-22/module/apache-php5           5.2.17-0.175.1.0.0.18      i-r
web/server/apache-22/module/apache-php52          5.2.17-0.175.1.0.0.24.0    i--

root@webzone:~# pkg list *mysql*
NAME (PUBLISHER)                                  VERSION                    IFO
database/mysql-51                                 5.1.37-0.175.1.0.0.24.0    i--
database/mysql-51/library                         5.1.37-0.175.1.0.0.24.0    i--
database/mysql-common                             0.5.11-0.175.1.0.0.24.0    i--
library/apr-util-13/dbd-mysql                     1.3.9-0.175.1.0.0.24.0     i--
web/php-52/extension/php-mysql                    5.2.17-0.175.1.0.0.24.0    i--

All that is left to do is to start the web server service and check that it is running:
root@webzone:~# svcadm enable apache22
root@webzone:~# svcs apache22
STATE          STIME    FMRI
online          9:12:18 svc:/network/http:apache22

In your Oracle Solaris desktop, open the Firefox browser and enter the webzone IP address (192.168.1.225) into the address line. The resultant page should read "It works!"
Now that webzone is created and configured, we need to clone it to create dbzone. To do this, we must first halt webzone:
root@webzone:~# exit
logout

[Connection to zone 'webzone' pts/3 closed]
root@solaris:~# zoneadm -z webzone shutdown

root@solaris:~#

Exercise 4: Configuring the Database Layer
The next step is to create a database server zone. Instead of installing it, we will clone our existing zone, which saves time and disk space. As before, we need to set up the network, do the configuration and profile creation, and replace the installation with the cloning operation.
Configuring the dbzone VNIC
We want the database zone to be connected only internally to webzone, so we'll create a virtual NIC that is connected to the virtual switch we created before.
root@solaris:~# dladm create-vnic -l vswitch0 dbint0
root@solaris:~# dladm
LINK                CLASS     MTU    STATE    OVER
net1                phys      1500   unknown  --
net0                phys      1500   up       --
vswitch0            etherstub 9000   unknown  --
webint0             vnic      9000   up       vswitch0
dbint0              vnic      9000   up       vswitch0

Configuring dbzone
Because this zone will be running the database part of our application, we will call it dbzone. In this configuration, we will set the path where the zone will be located (/zones/dbzone) and its network interface (dbint0), and also we will assign the data set we created at the very beginning of the lab (rpool/mydata) to use inside the zone.
root@solaris:~#  zonecfg -z dbzone
Use 'create' to begin configuring a new zone.
zonecfg:dbzone> create
create: Using system default template 'SYSdefault'
zonecfg:dbzone> set zonepath=/zones/dbzone
zonecfg:dbzone> add net
zonecfg:dbzone:net>set physical=dbint0
zonecfg:dbzone:net> end
zonecfg:dbzone> add dataset
zonecfg:dbzone:dataset> set name=rpool/mydata
zonecfg:dbzone:dataset> end
zonecfg:dbzone> verify
zonecfg:dbzone> commit
zonecfg:dbzone> exit

Next let's create the zone profile for dbzone.
root@solaris:~# sysconfig create-profile -o /root/dbzone-profile.xml

In the dialog box that appears, enter the following parameters:
Computer Name: dbzone
Network connection:
None (we will configure networking later from within the zone)
Time Zone: Select your time zone (hint: when selecting the country, press its first letter, for example, U for United States)
Root password:
solaris11
User real name:
Zone User
User id:
zuser
User password:
oracle1
For everything else, accept the defaults by pressing F2 or ESC-2 to continue.
Installing dbzone Using Cloning
Instead of installing the zone from our newly created profile, this time we will clone webzone to create dbzone.
root@solaris:~# zoneadm -z dbzone clone -c /root/dbzone-profile.xml webzone
Progress being logged to /var/log/zones/zoneadm.20130812T195010Z.dbzone.clone
Log saved in non-global zone as /zones/dbzone/root/var/log/zones/zoneadm.20130812T195010Z.dbzone.clone
root@solaris:~# zoneadm list -cv
  ID NAME             STATUS     PATH                           BRAND    IP   
   0 global           running    /                              solaris  shared
   - webzone          installed  /zones/webzone                 solaris  excl 
   - dbzone           installed  /zones/dbzone                  solaris  excl 

This time, the installation was much quicker, and we also ended up with a copy of our original zone. This technique is extremely useful in a cloud environment to allow us to rapidly provision new instances.
Also important is how efficiently space is used by our virtualization technology. Let's take a look at the disk usage now:
root@solaris:~# zfs list rpool/zones rpool/zones/webzone rpool/zones/dbzone
NAME                 USED  AVAIL  REFER  MOUNTPOINT
rpool/zones          619M  12.0G    33K  /zones
rpool/zones/dbzone   391K  12.0G    34K  /zones/dbzone
rpool/zones/webzone  619M  12.0G    33K  /zones/webzone
Listing 5
Listing 5 shows that the total space used is 619 MB, but when you total up the two zones you get 1010 MB—how can that be? It is because we are using ZFS, which means that we get a copy-on-write file system—only the differences between dbzone and webzone will need to be stored on disk.
Setting Up dbzone
Let's check out dbzone and do some final configuration. First let's start up both our zones:
root@solaris:~# zoneadm -z webzone boot
root@solaris:~# zoneadm -z dbzone boot
root@solaris:~# zoneadm list -cv
  ID NAME             STATUS     PATH                           BRAND    IP   
   0 global           running    /                              solaris  shared
   3 webzone          running    /zones/webzone                 solaris  excl 
   4 dbzone           running    /zones/dbzone                  solaris  excl 

We can see that both zones are running. Now log in to dbzone and see whether we have a full copy of webzone by checking the AMP packages and checking whether the Apache web server is running:
root@solaris:~# zlogin dbzone
[Connected to zone 'dbzone' pts/2]
Oracle Corporation      SunOS 5.11      11.1    September 2012
root@dbzone:~# pkg list *apache*
NAME (PUBLISHER)                                  VERSION                    IFO
web/server/apache-22                              2.2.22-0.175.1.0.0.24.0    i--
web/server/apache-22/module/apache-dtrace         0.3.1-0.175.1.0.0.24.0     i--
web/server/apache-22/module/apache-fcgid          2.3.6-0.175.1.0.0.24.0     i--
web/server/apache-22/module/apache-php5           5.2.17-0.175.1.0.0.18      i-r
web/server/apache-22/module/apache-php52          5.2.17-0.175.1.0.0.24.0    i--

root@dbzone:~# pkg list *php*
NAME (PUBLISHER)                                  VERSION                    IFO
web/php-52                                        5.2.17-0.175.1.0.0.24.0    i--
web/php-52/extension/php-apc                      3.0.19-0.175.1.0.0.24.0    i--
web/php-52/extension/php-idn                      0.2.0-0.175.1.0.0.24.0     i--
web/php-52/extension/php-memcache                 2.2.5-0.175.1.0.0.24.0     i--
web/php-52/extension/php-mysql                    5.2.17-0.175.1.0.0.24.0    i--
web/php-52/extension/php-pear                     5.2.17-0.175.1.0.0.24.0    i--
web/php-52/extension/php-suhosin                  0.9.29-0.175.1.0.0.24.0    i--
web/php-52/extension/php-tcpwrap                  1.1.3-0.175.1.0.0.24.0     i--
web/php-52/extension/php-xdebug                   2.0.5-0.175.1.0.0.24.0     i--
web/php-common                                    11.1-0.175.1.0.0.24.0      i--
web/server/apache-22/module/apache-php5           5.2.17-0.175.1.0.0.18      i-r
web/server/apache-22/module/apache-php52          5.2.17-0.175.1.0.0.24.0    i--

root@dbzone:~# pkg list *mysql*
NAME (PUBLISHER)                                  VERSION                    IFO
database/mysql-51                                 5.1.37-0.175.1.0.0.24.0    i--
database/mysql-51/library                         5.1.37-0.175.1.0.0.24.0    i--
database/mysql-common                             0.5.11-0.175.1.0.0.24.0    i--
library/apr-util-13/dbd-mysql                     1.3.9-0.175.1.0.0.24.0     i--
web/php-52/extension/php-mysql                    5.2.17-0.175.1.0.0.24.0    i--

root@dbzone:~# svcs apache22
STATE          STIME    FMRI
online          4:25:11 svc:/network/http:apache22

All the packages are there and the Apache web server is up and running, just like our webzone. We actually don't need Apache here in dbzone, so let's stop it.
root@webzone:~# svcadm disable apache22
root@dbzone:~# svcs apache22
STATE          STIME    FMRI
offline         6:39:24 svc:/network/http:apache22

We also need to finish configuring our network. Note that we do not need to disable the firewall this time because we did that in webzone already.
root@dbzone:~# ipadm
NAME              CLASS/TYPE STATE        UNDER      ADDR
lo0               loopback   ok           --         --
   lo0/v4         static     ok           --         127.0.0.1/8
   lo0/v6         static     ok           --         ::1/128
root@dbzone:~# dladm
LINK                CLASS     MTU    STATE    OVER
dbint0              vnic      9000   up       ?
net0                vnic      1500   up       ?
root@dbzone:~# ipadm create-ip dbint0
root@dbzone:~# ipadm create-addr -a local=10.0.3.11/24 dbint0/v4
root@dbzone:~# ping 10.0.3.10
10.0.3.10 is alive
root@dbzone:~# ping webzone
webzone is alive
root@dbzone:~# ipadm
NAME              CLASS/TYPE STATE        UNDER      ADDR
dbint0            ip         ok           --         --
   dbint0/v4      static     ok           --         10.0.3.11/24
lo0               loopback   ok           --         --
   lo0/v4         static     ok           --         127.0.0.1/8
   lo0/v6         static     ok           --         ::1/128

Q: How were we able to ping webzone by host name, since we haven't set up /etc/hosts in this zone?
A: Because /etc/hosts was already set up in webzone, it was cloned across with the rest of the webzone contents.

The last task is to configure and start our database. You may remember that we set up a ZFS data set for the database information. We need to configure MySQL to use that.
First, check that the mydata ZFS data set was correctly delegated to this zone:
root@dbzone:~# zfs list
NAME                       USED  AVAIL  REFER  MOUNTPOINT
mydata                      31K  11.9G    31K  /mydata
rpool                     64.0M  11.9G    31K  /rpool
rpool/ROOT                63.9M  11.9G    31K  legacy
rpool/ROOT/solaris-0      63.9M  11.9G   618M  /
rpool/ROOT/solaris-0/var   261K  11.9G  28.7M  /var
rpool/VARSHARE              19K  11.9G    39K  /var/share
rpool/export              74.5K  11.9G    32K  /export
rpool/export/home         53.5K  11.9G    32K  /export/home
rpool/export/home/zuser   32.5K  11.9G  32.5K  /export/home/zuser

Now, set up the correct ownership for the /mydata directory and configure MySQL to use it:
root@dbzone:~# chown -R mysql:mysql /mydata
root@dbzone:~# chmod -R 700 /mydata
root@dbzone:~# svccfg -s mysql:version_51 setprop mysql/data=/mydata
root@dbzone:~# svcadm refresh mysql:version_51
root@dbzone:~# svccfg -s mysql:version_51 listprop mysql/data
mysql/data astring     /mydata

Finally, let's start MySQL and check that it is working. You can check whether it has started up using the svcs command because MySQL might take a little time to start:
root@dbzone:~# svcadm enable mysql
root@dbzone:~# svcs mysql
STATE          STIME    FMRI
online          4:26:21 svc:/application/database/mysql:version_51

root@dbzone:~# mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.37 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Exercise 5: Configuring the WordPress Application
The last part of our stack is to configure and run our application, in our case WordPress.
While we are still in the database zone and logged into the MySQL instance, let's create the database we need for WordPress:
mysql> create database wp01;
Query OK, 1 row affected (0.01 sec)

Let's add access privileges for the user wordpress from host webzone with password oracle1:
mysql> grant all privileges on wp01.* to 'wordpress'@'webzone' identified by 'oracle1';
Query OK, 0 rows affected (0.01 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.02 sec)

mysql> quit;
Bye

That is all the tasks for the database zone, so quit out to the global zone:
root@dbzone:~# exit
logout

[Connection to zone 'dbzone' pts/2 closed]
root@solaris:~#

Now, let's copy the WordPress binaries into place in webzone. We will use the network connection we created when we configured webzone:
root@solaris:~# scp /root/files/wordpress-3.6.zip zuser@192.168.1.225:
The authenticity of host '192.168.1.225 (192.168.1.225)' can't be established.
RSA key fingerprint is 68:20:37:5f:fe:d8:92:e0:b4:6f:2d:53:a0:3e:c6:74.
Are you sure you want to continue connecting (yes/no)? yes
Password: oracle1
wordpress-3.6.zip    100% |**********************************************************************************
***************************|  4371 KB    00:00   
root@solaris:~#

Next, let's log in to webzone and extract the WordPress application. Remember to copy or move the archive from the zuser location.
root@solaris:~# zlogin webzone
[Connected to zone 'webzone' pts/2]
Oracle Corporation      SunOS 5.11      11.1    September 2012
root@webzone:~# pwd
/root
root@webzone:~# mv /home/zuser/wordpress-3.6.zip .
root@webzone:~# unzip wordpress-3.6.zip
Archive:  wordpress-3.6.zip
   creating: wordpress/
  inflating: wordpress/wp-settings.php 
  inflating: wordpress/wp-cron.php  

(output omitted)

inflating: wordpress/wp-includes/Text/Diff.php 
  inflating: wordpress/wp-includes/update.php 
  inflating: wordpress/wp-includes/comment.php 
  inflating: wordpress/wp-config-sample.php 
root@webzone:~#

Now, we need to configure WordPress to use our MySQL database. First, copy the configuration file, and then make the changes shown below:
root@webzone:~# cd wordpress
root@webzone:~/wordpress# cp wp-config-sample.php wp-config.php
root@webzone:~/wordpress# vi wp-config.php

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wp01');

/** MySQL database username */
define('DB_USER', 'wordpress');

/** MySQL database password */
define('DB_PASSWORD', 'oracle1');

/** MySQL hostname */
define('DB_HOST', 'dbzone');

We now need to copy the WordPress distribution to the web server document root.
root@webzone:~/wordpress# mkdir /var/apache2/2.2/htdocs/blog
root@webzone:~/wordpress# cp -r * /var/apache2/2.2/htdocs/blog
root@webzone:~/wordpress# ls /var/apache2/2.2/htdocs/blog/
index.php   wp-activate.php    wp-comments-post.php wp-cron.php       wp-load.php  wp-settings.php xmlrpc.php
license.txt wp-admin           wp-config.php        wp-includes       wp-login.php wp-signup.php
readme.html wp-blog-header.php wp-content           wp-links-opml.php wp-mail.php  wp-trackback.php

We are now ready to install WordPress using your browser. Start a browser from the desktop in your global zone, and enter the URL http://192.168.1.225/blog/wp-admin/install.php. The rest is easy. Enter the name of the blog ("Oracle Solaris 11 Blog"), your administrator's login name (admin, by default) and the password (solaris1, for example), and an e-mail address, as shown in Figure 3.


Figure 3. The WordPress installation screen.

Figure 4. WordPress successful installation screen.
Now, log in to your new blog using the credentials you selected.


Figure 5. WordPress login screen.
Once you are at the dashboard, access your blogging window by clicking "Oracle Solaris 11 Blog" at the top of the browser window.


Figure 6. WordPress dashboard.


Figure 7. WordPress blog screen.
Exercise 6: Monitoring Zones
Monitoring what resources your zones and—hence, your cloud—are using is important for debugging issues and also for capacity planning, and even for charging. Oracle Solaris 11 adds features that make this even simpler. We will look at them now.
Zone Extensions to Existing Commands
Some Oracle Solaris 11 commands now have a -Z parameter to help you when you examine a system. Let's try a couple now. Note that the following examples are run from the global zone, and some of the output has been truncated to be more readable.
With the ps command, it is now possible to see which zone a process belongs to:
root@solaris:~# ps -efZ
ZONE      UID   PID  PPID   C    STIME TTY         TIME CMD
  global     root     0     0   0   Aug 11 ?           0:04 sched
  global     root     5     0   0   Aug 11 ?           1:02 zpool-rpool
  global     root     6     0   0   Aug 11 ?           0:13 kmem_task
  global     root     1     0   0   Aug 11 ?           0:01 /usr/sbin/init
  dbzone     root 12762     1   0 06:39:26 ?           0:00 /usr/lib/pfexecd
 webzone     root 11549     1   0 06:38:20 ?           0:00 /usr/lib/utmpd
 webzone   daemon 11217     1   0 06:38:11 ?           0:00 /lib/crypto/kcfd

With the prstat command, there is a summary for zone-related information:
root@solaris:~# prstat -Z
ZONEID    NPROC  SWAP   RSS MEMORY      TIME  CPU ZONE                       
     0      120 3103M  703M    34%   0:26:36 1.4% global                     
     4       29  306M  108M   5.3%   0:01:57 0.2% dbzone                     
     3       38 1182M  336M    17%   0:01:02 0.2% webzone                    

The zonestat Command
There is a new command called zonestat, which is extremely useful for examining zone and network information, as shown in Listing 6:
root@solaris:~# zonestat 5 2
Collecting data for first interval...
Interval: 1, Duration: 0:00:05
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  0.17 17.4% 1432M 69.9% 1899M 61.8%   212 0.00%
           [system]  0.01 1.67%  449M 21.9% 1019M 33.1%     -     -
             global  0.14 14.2%  747M 36.5%  572M 18.6%   212 0.00%
             dbzone  0.00 0.47%  100M 4.88%   99M 3.22%     0 0.00%
            webzone  0.00 0.99%  135M 6.61%  207M 6.77%     0 0.00%

Interval: 2, Duration: 0:00:10
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  0.17 17.8% 1432M 69.9% 1899M 61.8%   936 0.00%
           [system]  0.02 2.44%  449M 21.9% 1019M 33.1%     -     -
             global  0.13 13.3%  748M 36.5%  572M 18.6%   936 0.00%
             dbzone  0.01 1.01%  100M 4.88%   99M 3.22%     0 0.00%
            webzone  0.00 0.96%  135M 6.61%  208M 6.77%     0 0.00%
Listing 6
You can also use zonestat from within a zone, as shown in Listing 7. Can you spot what the differences are between Listing 6 and Listing 7?
root@solaris:~# zlogin webzone
[Connected to zone 'webzone' pts/2]
Oracle Corporation     SunOS 5.11     11.1    September 2012
root@webzone:~# zonestat 5 2
Collecting data for first interval...
Interval: 1, Duration: 0:00:05
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  0.16 16.6% 1435M 70.1% 1901M 61.9%   212 0.00%
           [system]  0.15 15.8% 1297M 63.3% 1692M 55.1%     -     -
            webzone  0.00 0.75%  138M 6.74%  209M 6.81%     0 0.00%

Interval: 2, Duration: 0:00:10
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  0.17 17.1% 1435M 70.1% 1901M 61.9%   628 0.00%
           [system]  0.16 16.1% 1297M 63.3% 1692M 55.1%     -     -
            webzone  0.01 1.02%  138M 6.74%  209M 6.81%     0 0.00%

root@webzone:~# exit
logout

[Connection to zone 'webzone' pts/2 closed]
Listing 7
Look at the zonestat man page and experiment with the different output types.
Exercise 7: Performing Resource Management
Resource management is very important in the cloud. You might want to control misbehaving applications or bill on a per-CPU basis. Among other features, Oracle Solaris Zones and the Oracle Solaris network stack also allow you to control resources. While you can control many different things, in this lab, we will look at controlling processing power via Oracle Solaris Zones.
Loading a Zone Without Resource Management
Let's look first at Oracle Solaris Zones without any resource management in place. This can be beneficial for cases where loads are "bursty" and resources need to be instantly available or shared across multiple instances. However, in the cloud case, it is much more likely that resources need to be assigned. We will look at the output here simply for comparison.
We start by looking at the system in its current state. We will use the vmstat and zonestat commands to look at the processor load, as shown in Listing 8.
root@solaris:~# vmstat 5 5
 kthr      memory            page            disk          faults      cpu
 r b w   swap  free  re  mf pi po fr de sr s0 s1 s2 --   in   sy   cs us sy id
 0 0 0 1497124 759028 57 233 0  0  0  0  9 13  0  0  0  465 1795  817  2  4 94
 0 0 0 1085060 430068 7  11  0  0  0  0  0  0  0  0  0  463  408  376  1  2 97
 0 0 0 1085060 430068 0   0  0  0  0  0  0  0  0  0  0  457  443  373  0  2 98
 0 0 0 1085060 430068 0   0  0  0  0  0  0  0  0  0  0  455  392  370  1  1 98
 0 0 0 1085060 430068 0   0  0  0  0  0  0  0  0  0  0  456  412  368  0  2 98

root@solaris:~# zonestat 5 2
Collecting data for first interval...
Interval: 1, Duration: 0:00:05
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  0.12 12.2%  848M 41.4% 1232M 40.1%   212 0.00%
           [system]  0.01 1.09%  307M 15.0%  812M 26.4%     -     -
             global  0.10 10.1%  347M 16.9%  196M 6.38%   212 0.00%
             dbzone  0.00 0.56% 90.9M 4.44% 87.0M 2.83%     0 0.00%
            webzone  0.00 0.48%  102M 4.98%  136M 4.44%     0 0.00%

Interval: 2, Duration: 0:00:10
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  0.14 14.8%  848M 41.4% 1233M 40.1%   936 0.00%
           [system]  0.01 1.03%  307M 15.0%  813M 26.4%     -     -
             global  0.13 13.0%  347M 16.9%  196M 6.38%   936 0.00%
             dbzone  0.00 0.37% 90.9M 4.44% 87.0M 2.83%     0 0.00%
            webzone  0.00 0.40%  102M 4.98%  136M 4.44%     0 0.00%
Listing 8
In Listing 8, we can see from vmstat that the system is pretty idle, and zonestat shows us that both dbzone and webzone are using very few CPU resources.
Let's run a simple CPU-intensive script in webzone. We'll run three instances to put the system under some measurable load:
root@solaris:~# zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'" &
[1] 2376
root@solaris:~# zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'" &
[2] 4352
root@solaris:~# zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'" &
[3] 5820

Let's look at the effect on the system:
root@solaris:~# vmstat 5 5
kthr      memory            page            disk          faults      cpu
 r b w   swap  free  re  mf pi po fr de sr s0 s1 s2 --   in   sy   cs us sy id
 0 0 0 1458340 728048 57 257 0  0  0  0  9 12  0  0  0  465 1697  781  2  4 94
 5 0 0 1073088 420496 2991 25178 0 0 0 0 0  0  0  0  0  508 12344 572 42 58  0
 4 0 0 1072960 420404 3001 25325 0 0 0 0 0  0  0  0  0  488 12404 573 42 58  0
 4 0 0 1072920 420484 3003 25323 0 0 0 0 0  0  0  0  0  496 12488 609 42 58  0
 4 0 0 1072896 420400 2962 24986 0 0 0 0 0  0  0  0  0  508 12341 610 42 58  0

System time hits a high of 58. Also let's look at what zonestat is telling us:
root@solaris:~# zonestat 5 2
Collecting data for first interval...
Interval: 1, Duration: 0:00:05
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  0.99 99.9%  854M 41.7% 1241M 40.4%   212 0.00%
           [system]  0.07 7.82%  308M 15.0%  813M 26.4%     -     -
            webzone  0.80 80.5%  106M 5.18%  139M 4.54%     0 0.00%
             global  0.11 11.2%  349M 17.0%  200M 6.53%   212 0.00%
             dbzone  0.00 0.34% 90.9M 4.44% 87.0M 2.83%     0 0.00%

Interval: 2, Duration: 0:00:10
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  1.00  100%  855M 41.7% 1242M 40.4%   936 0.00%
           [system]  0.05 5.46%  308M 15.0%  814M 26.5%     -     -
            webzone  0.83 83.0%  106M 5.18%  139M 4.55%     0 0.00%
             global  0.11 11.0%  349M 17.0%  201M 6.54%   936 0.00%
             dbzone  0.00 0.38% 90.9M 4.44% 87.0M 2.83%     0 0.00%
Listing 9
In Listing 9, we can clearly see that webzone is using 83 percent of the available CPU resources.
Let's kill off the scripts before we add some resource control.
root@solaris:~# fg 1
zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'"
^C
root@solaris:~# fg 2
zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'"
^C
root@solaris:~# fg 3
zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'"
^C

Adding CPU Resource Control
Now let's limit webzone to half a CPU:
root@solaris:~# zonecfg -z webzone
zonecfg:webzone> add capped-cpu
zonecfg:webzone:capped-cpu> set ncpus=0.5
zonecfg:webzone:capped-cpu> end
zonecfg:webzone> verify
zonecfg:webzone> commit
zonecfg:webzone> exit

Resource limitations are applied only after a zone reboot, so let's reboot now:
root@solaris:~# zoneadm -z webzone reboot
root@solaris:~# zoneadm list -iv
  ID NAME             STATUS     PATH                           BRAND    IP   
   0 global           running    /                              solaris  shared
   2 dbzone           running    /zones/dbzone                  solaris  excl 
   3 webzone          running    /zones/webzone                 solaris  excl 

Now, let's run the same tests again, as shown in Listing 10, and look at the output:
root@solaris:~# zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'" &
[1] 4305
root@solaris:~# zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'" &
[2] 4545
root@solaris:~# zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'" &
[3] 4747

root@solaris:~# vmstat 5 5
 kthr      memory            page            disk          faults      cpu
 r b w   swap  free  re  mf pi po fr de sr s0 s1 s2 --   in   sy   cs us sy id
 0 0 0 1419676 695904 171 1164 0 0 0  0  8 12  0  0  0  468 2298  838  3  6 90
 0 0 0 1013684 350316 1289 11358 0 0 0 0 0  0  0  0  0  482 5726  508 23 33 44
 0 0 0 1013684 350236 1248 11121 0 0 0 0 0  0  0  0  0  484 5577  510 23 32 45
 0 0 0 1013684 350224 1264 11361 0 0 0 0 0  0  0  0  0  475 5732  508 23 32 45
 1 0 0 1013692 350256 1292 11464 0 0 0 0 0  0  0  0  0  486 5769  505 23 32 45

root@solaris:~# zonestat 5 2
Collecting data for first interval...
Interval: 1, Duration: 0:00:05
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  0.64 64.9%  919M 44.9% 1296M 42.2%   212 0.00%
           [system]  0.05 5.83%  375M 18.3%  871M 28.3%     -     -
            webzone  0.47 47.9%  103M 5.05%  136M 4.46%     0 0.00%
             global  0.10 10.7%  349M 17.0%  201M 6.54%   212 0.00%
             dbzone  0.00 0.39% 90.9M 4.44% 87.0M 2.83%     0 0.00%

Interval: 2, Duration: 0:00:10
SUMMARY                   Cpus/Online: 1/1   PhysMem: 2047M  VirtMem: 3071M
                    ---CPU----  --PhysMem-- --VirtMem-- --PhysNet--
               ZONE  USED %PART  USED %USED  USED %USED PBYTE %PUSE
            [total]  0.65 65.9%  920M 44.9% 1296M 42.2%   936 0.00%
           [system]  0.03 3.26%  375M 18.3%  871M 28.3%     -     -
            webzone  0.48 48.3%  103M 5.06%  136M 4.45%     0 0.00%
             global  0.13 13.9%  349M 17.0%  201M 6.55%   936 0.00%
             dbzone  0.00 0.42% 90.9M 4.44% 87.0M 2.83%     0 0.00%
Listing 10
In Listing 10, you can see how the resource controls have limited the CPU usage of webzone. To complete this part of the lab, let's stop the scripts and remove the CPU resource limit from webzone (don't forget to reboot webzone at the end to apply the resource changes):
root@solaris:~# fg 1
zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'"
^C
root@solaris:~# fg 2
zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'"
^C
root@solaris:~# fg 3
zlogin webzone "bash -c 'while true ; do date > /dev/null ; done'"
^C

root@solaris:~# zonecfg -z webzone
zonecfg:webzone-1> remove capped-cpu
zonecfg:webzone-1> verify
zonecfg:webzone-1> commit
zonecfg:webzone-1> exit
root@solaris:~# zoneadm -z webzone reboot

There are lots of other resource control settings you can apply to a zone. Have a look at the man page or documentation to see what other options there are.
Exercise 8: Ensuring Availability
Oracle Solaris offers many ways to make your applications available. You can simply rely on the reliability, availability, and serviceability (RAS) features built into the hardware or you might want to go all the way and implement a highly available environment with Oracle Solaris Cluster. Oracle Solaris offers availability at all levels. Here, we will take a very quick look at the Service Management Framework of Oracle Solaris.
For a quick demonstration, let's look at the processes associated with our Apache web server, as shown in Listing 11:
root@webzone:~# svcs -p apache22
STATE          STIME    FMRI
online          5:05:46 svc:/network/http:apache22
                5:05:46    20538 httpd
                5:05:47    20539 httpd
                5:05:48    20540 httpd
                5:05:48    20541 httpd
                5:05:48    20542 httpd
                5:05:48    20543 httpd
                5:05:48    20544 httpd
Listing 11
Now, let's simulate a failure in the service by killing the httpd processes, as shown in Listing 12, and see what happens to them:
root@webzone:~# pkill httpd
root@webzone:~# svcs -p apache22
STATE          STIME    FMRI
online          5:28:01 svc:/network/http:apache22
                5:28:01    20585 httpd
                5:28:01    20586 httpd
                5:28:02    20587 httpd
                5:28:02    20588 httpd
                5:28:02    20589 httpd
                5:28:02    20590 httpd
                5:28:02    20591 httpd
Listing 12
The Apache httpd processes are still there. If you look closely at Listing 12, you will see that the process IDs have changed from Listing 11, and the service was automatically restarted after it was stopped. This is a standard part of the Service Management Framework and provides a small insight into how Oracle Solaris maintains your cloud service availability.
Exercise 9: Securing the Environment
Security is always important, but in a cloud space with shared environments and an "open" network, it is even more important to protect your environment.
Oracle Solaris includes the ability to secure your environment at many different layers. You might want to use ZFS encryption for your data or use data link protection to harden your network. Here, we will look at Oracle Solaris' unique ability to create read-only environments called immutable zones.
Turning webzone into an Immutable Zone
Let's start by turning our webzone into an immutable zone or read-only environment. This is very simple to do via a configuration change. To apply the change, we need to reboot the zone:
root@solaris:~# zonecfg -z webzone
zonecfg:webzone> set file-mac-profile=fixed-configuration
zonecfg:webzone> verify
zonecfg:webzone> commit
zonecfg:webzone> exit
root@solaris:~# zoneadm -z webzone reboot

That's all we need to do. We now have a read-only environment.
Trying to Do Some Damage
Let's see what we can do from inside our read-only environment:
root@solaris:~# zlogin webzone
[Connected to zone 'webzone' pts/2]
Oracle Corporation     SunOS 5.11     11.1    September 2012
root@webzone:~# touch /etc/a_file
touch: cannot create /etc/a_file: Read-only file system
root@webzone:~# touch /var/tmp/a_file
root@webzone:~# touch /tmp/a_file
root@webzone:~# pkg install emacs

pkg install: Could not complete the operation on /var/pkg/lock: read-only filesystem.
root@webzone:~# rm /usr/bin/vi

rm: /usr/bin/vi not removed: Read-only file system
root@webzone:~# useradd larry
/usr/lib/passmgmt: Password file(s) busy.  Try again later
/usr/lib/passmgmt: Password file(s) busy.  Try again later
/usr/lib/passmgmt: Password file(s) busy.  Try again later
UX: useradd: ERROR: Cannot update system - login cannot be created.
root@webzone:~# svcadm disable apache22
root@webzone:~# svcs apache22
STATE          STIME    FMRI
disabled        8:56:10 svc:/network/http:apache22
root@webzone:~# exit
logout

[Connection to zone 'webzone' pts/2 closed]

But what do we need to do if we need to make some changes to webzone? Well, you can boot the zone in read/write mode, but note that you can do this only from the global zone. A similar thing happens when you do updates from the global zone that affect the zone.
root@solaris:~# zoneadm -z webzone reboot -w
root@solaris:~# zlogin -C webzone
[Connected to zone 'webzone' console]

Hostname: webzone
webzone console login: zuser
Password: oracle1
Last login: Tue Aug 13 09:39:27 from 192.168.1.222
Oracle Corporation      SunOS 5.11      11.1    September 2012
zuser@webzone:~$ su -
Password: solaris11
Aug 14 12:02:57 webzone su: 'su root' succeeded for zuser on /dev/console
Oracle Corporation      SunOS 5.11      11.1    September 2012
root@webzone:~# touch /etc/a_file
root@webzone:~# rm /etc/a_file
root@webzone:~# exit
logout
zuser@webzone:~$ exit
logout

webzone console login: ~.
[Connection to zone 'webzone' console closed]

Finally, let's return the zone back to its normal mode:
root@solaris:~# zonecfg -z webzone
zonecfg:webzone> clear file-mac-profile
zonecfg:webzone> verify
zonecfg:webzone> commit
zonecfg:webzone> exit
root@solaris:~# zoneadm -z webzone reboot

Conclusion
That's it; you're all done. Having completed the lab, you've learned how Oracle Solaris is the best foundation for your cloud infrastructure. You've seen how easy it is to rapidly deploy applications, configure flexible networks, and control resources, and you've seen how Oracle Solaris works to keep your services running. You've also seen how to implement a read-only virtual environment. If you got this far and have some time to spare, why not look at the following section and see how far you can get.