Pages

Tuesday, February 28, 2006

Solaris Zones: Resource Controls - CPU

An overview of Solaris Zones is available in blog entry: Zone creation for dummies. It is possible to limit the resource utilization in each zone, with Solaris containers. Detailed information about the kind of resources that can be controlled, can be found in the Resource Controls chapter of Solaris Containers-Resource Management and Solaris Zones guide. The primary focus of this blog entry is to show how to restrict one of the zones to use a maximum of 3 CPUs, on a 4 CPU Sun server.

Let's assume that we have a server configured to run 3 zones (1 global + 2 local), as shown below:
 % zoneadm list -cv
  ID NAME STATUS PATH
  0 global running /
  19 v1280appserv running /zones/z1
  22 v1280webserv running /zones/z2

The assumption is that the application server running in v1280appserv zone is going to consume majority of CPU cycles. So to give a fair chance to run web server, and other applications on this server, let's try to restrict the non-global zone, v1280appserv, to use a maximum of 3 processors only, leaving one processor for the web server. This was shown in the following figure:


Steps for CPU resource control

1. Enable pools facility

Make sure the resource pool daemon, poold, is running.
 % ps -eaf | grep poold
  root 20019 18948 0 15:03:58 pts/3 0:00 grep poold

 % pooladm
 pooladm: couldn't open pools state file: Facility is not active

Use -e option of pooladm to enable the pools facility
 % pooladm -e
 % pgrep poold
 18951

Without any options, pooladm prints out the currently running pools configuration
 % pooladm
 system sdcv1280s001
  string system.comment
  int system.version 1
  boolean system.bind-default true
  int system.poold.pid 18951

  pool pool_default
  int pool.sys_id 0
  boolean pool.active true
  boolean pool.default true
  int pool.importance 1
  string pool.comment
  pset pset_default

  pset pset_default
  int pset.sys_id -1
  boolean pset.default true
  uint pset.min 1
  uint pset.max 65536
  string pset.units population
  uint pset.load 17
  uint pset.size 4
  string pset.comment

  cpu
  int cpu.sys_id 1
  string cpu.comment
  string cpu.status on-line

  cpu
  int cpu.sys_id 0
  string cpu.comment
  string cpu.status on-line

  cpu
  int cpu.sys_id 3
  string cpu.comment
  string cpu.status on-line

  cpu
  int cpu.sys_id 2
  string cpu.comment
  string cpu.status on-line

2. Configure & load pool into memory

Since the plan is to restrict v1280appserv zone to 3 processors, create an input file as shown below. This file will be used to configure the required resource pool using poolcfg.
 % cat zonepoolcfg
 create pset appserv-pset ( uint pset.min = 3; uint pset.max = 3 )
 create pool appserv-pool
 associate pool appserv-pool ( pset appserv-pset )

create pset appserv-pset ( uint pset.min = 3; uint pset.max = 3 ) creates a processor set with 3 processors
create pool appserv-pool creates a new pool called appserv-pool
associate pool appserv-pool ( pset appserv-pset ) associates the processor set appserv-pset with pool appserv-pool

Update the configuration using the zonepoolcfg input file.
 % poolcfg -f zonepoolcfg
 poolcfg: cannot load configuration from /etc/pooladm.conf: No such file or directory

Note that /etc/pooladm.conf file must exist before updating it. Use -s option of pooladm to save active configuration from memory in to /etc/pooladm.conf
 % pooladm -s
 % ls -l /etc/pooladm.conf
 -rw-rw-r-- 1 root root 1429 Feb 28 13:43 /etc/pooladm.conf

Now since the /etc/pooladm.conf exists, update it with the new pool configuration that we just created. This can be done with -f option of poolcfg -- it takes the input file as an argument.
 % poolcfg -f zonepoolcfg

Alternatively you can run the following commands instead of an input file, to update the configuration:
 % poolcfg -c 'create pset appserv-pset  ( uint pset.min = 3; uint pset.max = 3 )'
 % poolcfg -c 'create pool appserv-pool'
 % poolcfg -c 'associate pool appserv-pool ( pset appserv-pset )'

Next step is to instantiate (ie., activate) the configuration from /etc/pooladm.conf in to memory -- use -c option of pooladm to do this. It takes a file name as an argument; but if no file name is specified, it will read the configuration from /etc/pooladm.conf
 % pooladm -c
 % psrset
 user processor set 1: processors 0 1 2

Observe that one processor set is created with 3 processors in that set.

Check the current pool configuration one more time, with pooladm.
 % pooladm
 system sdcv1280s001
  string system.comment
  int system.version 1
  boolean system.bind-default true
  int system.poold.pid 18951

  pool appserv-pool
  int pool.sys_id 1
  boolean pool.active true
  boolean pool.default false
  int pool.importance 1
  string pool.comment
  pset appserv-pset

  ...
  ...

  pset appserv-pset
  int pset.sys_id 1
  boolean pset.default false
  uint pset.min 3
  uint pset.max 3
  string pset.units population
  uint pset.load 0
  uint pset.size 3
  string pset.comment

  cpu
  int cpu.sys_id 1
  string cpu.comment
  string cpu.status on-line

  cpu
  int cpu.sys_id 0
  string cpu.comment
  string cpu.status on-line

  cpu
  int cpu.sys_id 2
  string cpu.comment
  string cpu.status on-line

  ...
  ...

3. Configure the zone(s)

Since the v1280appserv zone is already created, we just need to connect the zone to the pool that we just created. Use zonecfg to update the zone configuration.
 % zonecfg -z v1280appserv
 zonecfg:v1280appserv> set pool=appserv-pool
 zonecfg:v1280appserv> verify
 zonecfg:v1280appserv> exit

If the zone is not created yet, follow the instructions of Zone creation for dummies, and specify the pool, when the zone is configured.

4. Reboot the zone

Simply reboot the zone, v1280appserv, so it binds to the newly created pool, when it comes back.
 % zlogin v1280appserv init 6
 % zoneadm list -cv
  ID NAME STATUS PATH
  0 global running /
  19 v1280appserv shutting_down /zones/z1
  22 v1280webserv running /zones/z2

 % zoneadm list -cv
  ID NAME STATUS PATH
  ...
  23 v1280appserv ready /zones/z1

 % zoneadm list -cv
  ID NAME STATUS PATH
  ...
  23 v1280appserv running /zones/z1

5. Connect & verify the resource utilization
 v1280appserv zone:

 v1280appserv:/% psrset
 user processor set 1: processors 0 1 2

 v1280appserv:/% psrinfo
 0 on-line since 01/19/2006 13:44:11
 1 on-line since 01/19/2006 13:44:12
 2 on-line since 01/19/2006 13:44:12

 v1280appserv:/%vmstat 2
  kthr memory page disk faults cpu
  r b w swap free re mf pi po fr de sr s0 s1 s3 -- in sy cs us sy id
  0 0 0 16964480 6000376 3 6 8 5 4 0 0 1 0 0 0 342 293 240 4 1 96
  0 0 0 15999272 5119352 0 25 4 0 0 0 0 0 2 0 0 875 2948 968 62 2 36
  0 0 0 15994448 5114792 23 105 0 0 0 0 0 13 2 0 0 620 1666 433 51 1 48
  0 0 0 15982504 5102680 33 182 0 0 0 0 0 0 6 0 0 702 2246 767 49 2 50
  0 0 0 15976104 5096336 0 14 0 0 0 0 0 0 0 0 0 575 1376 461 32 1 67
  0 0 0 15969896 5090152 0 8 0 0 0 0 0 0 0 0 0 472 1067 569 18 1 82
  0 0 0 15963296 5083672 0 38 0 0 0 0 0 0 0 0 0 685 2440 731 38 2 60

 v1280webserv zone:

 v1280webserv:/% psrset
 v1280webserv:/% psrinfo
 3 on-line since 01/19/2006 13:44:12

 v1280webserv:/%vmstat 2
  kthr memory page disk faults cpu
  r b w swap free re mf pi po fr de sr s0 s1 s3 -- in sy cs us sy id
  0 0 0 16964480 6000376 1 2 4 0 0 0 0 1 0 0 0 22 110 102 4 1 95
  0 0 0 16032976 5152368 0 21 8 0 0 0 0 0 1 0 0 99 1013 1239 13 4 83
  0 0 0 16024560 5143968 0 1 0 0 0 0 0 0 2 0 0 69 915 816 12 3 85
  0 0 0 16022272 5141744 0 1 0 0 0 0 0 0 2 0 0 41 738 715 7 2 90
  0 0 0 16011216 5130992 0 7 0 0 0 0 0 0 3 0 0 92 936 976 11 4 85
  0 0 0 16004560 5124480 0 4 0 0 0 0 0 0 3 0 0 44 768 726 6 2 92
  0 0 0 15999272 5119352 0 1 0 0 0 0 0 0 2 0 0 132 1196 1387 19 4 76

 Global Zone:

  PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
  19844 giri 1007M 908M cpu2 59 0 0:04:49 16% siebmtshmw/154
  19859 giri 1007M 908M sleep 59 0 0:04:48 16% siebmtshmw/141
  19870 giri 999M 900M cpu0 59 0 0:04:38 16% siebmtshmw/145
  19906 giri 291M 127M run 29 10 0:01:27 4.3% webservd/417
  19907 giri 249M 85M run 59 0 0:00:22 1.2% webservd/158
  19976 giri 103M 63M sleep 32 0 0:00:01 1.1% siebmtshmw/7

 ZONEID NPROC SIZE RSS MEMORY TIME CPU ZONE
  23 54 4382M 3626M 45% 0:15:59 50% v1280appserv
  22 40 771M 320M 4.0% 0:05:40 5.5% v1280webserv
  0 37 355M 80M 1.0% 1:02:45 0.2% global

It is that simple.

Troubleshooting:

If you encounter the following error, double check your configuration.
        pooladm: configuration at '/etc/pooladm.conf' cannot be instantiated on current system
It is very likely that you configured some resource that is either not available or beyond its limits, on the system.

For more examples, see:
  1. [URL updated 05/28/08] Brendan Gregg's Zones documentation
  2. Sun's HOW-TO Guide: Solaris Containers: Consolidating Servers and Applications

Technorati tags
| | |

1 comment:

  1. The zones docuemnt you refer to doesn't exist anymore

    ReplyDelete