Solarisゾーンで仮想化(ゾーン環境のリソース制御)

ゾーン環境は、デフォルト設定だとCPUなどをリソースの許す限り使用する。
そのため高負荷時には、他ゾーンのパフォーマンス低下等の悪影響を引き起こす可能性がある。
ということで、リソース制御について。


1. ゾーン環境でのリソース管理について
ゾーン環境で制限可能なリソースは以下の2つ。

  • zone.cpu-shares(CPU割り当て時間)

   CPU時間と配分値(配分値を「global:zone1:zone2=1:2:2」にした場合)
    global: 1/(1+2+2)*100=20%
    zone1: 2/(1+2+2)*100=40%
    zone2: 2/(1+2+2)*100=40%
    ※他ゾーンがCPUを使用していない場合は、割り当て値を超えて使用する。
    ※デフォルトの配分値は、「1」。

  • zone.max-lwps(プロセス最大数)

   lwpは、「Light Weight Process」のこと。おおざっぱに言うと、1LWP=1スレッド。

2. Solaris10のスケジューラについて
Solaris10には複数のスケジューラが用意されており、システムのデフォルトは、Time Sharing(TS)になっている。
スケジュール一覧は、dispadminコマンドで確認できる。

# dispadmin -l
CONFIGURED CLASSES
==================

SYS (System Class)
TS (Time Sharing)
FX (Fixed Priority)
IA (Interactive)
RT (Real Time)
FSS (Fair Share)

CPUの配分を管理者が制御するには、スケジューラをFair Share(FSS)に変更する。

# dispadmin -d FSS

/etc/dispadmin.confでFSSが設定されたことを確認する。

# cat /etc/dispadmin.conf
DEFAULT_SCHEDULER=FSS

OS再起動後、ps -efcコマンドでCLSの値がほとんどFSSになっていることを確認する。

# ps -efc
UID PID PPID CLS PRI STIME TTY TIME CMD
root 94 1 FSS 59 11:50:43 ? 0:00 /usr/sfw/sbin/snmpd
root 7 1 FSS 29 11:50:30 ? 0:03 /lib/svc/bin/svc.startd
root 9 1 FSS 29 11:50:30 ? 0:11 /lib/svc/bin/svc.configd
root 243 1 FSS 18 11:50:52 ? 0:00 /usr/sbin/cron

3. ゾーンへのリソース割り当て
各ゾーンとも、「zone.cpu-shares=2」、「zone.max-lwps=300」に設定する。

# zonecfg -z solaris_zone_01
zonecfg:solaris_zone_01> add rctl
zonecfg:solaris_zone_01:rctl> set name=zone.max-lwps
zonecfg:solaris_zone_01:rctl> add value
zonecfg:solaris_zone_01:rctl> add value (priv=privileged,limit=100,action=deny)
zonecfg:solaris_zone_01:rctl> end
zonecfg:solaris_zone_01> add rctl
zonecfg:solaris_zone_01:rctl> set name=zone.cpu-shares
zonecfg:solaris_zone_01:rctl> add value
zonecfg:solaris_zone_01:rctl> add value (priv=privileged,limit=2,action=none)
zonecfg:solaris_zone_01:rctl> end
zonecfg:solaris_zone_01> verify
zonecfg:solaris_zone_01> commit
zonecfg:solaris_zone_01> exit

ゾーン再起動後、設定値を確認する。

# prctl -n zone.max-lwps -i zone solaris_zone_01
zone: 3: solaris_zone_01
NAME  PRIVILEGE    VALUE  FLAG ACTION             RECIPIENT
zone.max-lwps
     privileged    300     -   deny                -
     system     2.15G   max  deny                -
# prctl -n zone.cpu-shares -i zone solaris_zone_01
zone: 3: solaris_zone_01
NAME  PRIVILEGE    VALUE  FLAG ACTION             RECIPIENT
zone.cpu-shares
     privileged     2     -   none                -
     system     65.5K   max  none                -

4. 確認
それぞれの設定について、以下のperlスクリプトを各ゾーンで実行する。

(fork.pl)

#!/usr/bin/perl


use strict;


my $i;
my $pid;


for ($i=0; $i<300; $i++) {
    $pid = fork;
    if ($pid) {

    }
    elsif (defined($pid)) {
        print "child process $i finish!!\n";
        sleep 1;
        exit(0);
    }
    else {
        die "fork failed: $i\n";
    }
}

while (wait() != -1) {

}
print "finished!!\n";

(loop.pl)

#!/usr/bin/perl


use strict;


while (1) {

}

zone.max-lwpsに制限をかけたノングローバルゾーンで、fork.plを実行。
途中でプロセスが300以上になるため、スクリプトが終了する。

$ ./fork.pl
child process 133 finish!!
fork failed: 135
child process 134 finish!!

グローバルゾーン・各ノングローバルゾーンで、loop.plを実行。
prstatコマンドでゾーン毎のCPU使用率を確認。おおよそ「1:2:2」になっていることが確認できる。

# prstat -Z
ZONEID  NPROC  SIZE  RSS  MEMORY   TIME  CPU  ZONE
  4    42    360M  193M  19%   0:01:07  39% solaris_zone_02
  3    42    357M  186M  19%   0:01:13  37%  solaris_zone_01
  0    56    818M  220M  22%   0:00:59  19%  global

5. まとめ
今回実施したリソース制御を設定することで、他ゾーンへ悪影響を与えずに複数のサーバを運用できることができる。
また、動的リソースプール*1でCPUセットを作成して特定のゾーンにCPUセットを割り当てることも可能なので、
CPUに関しては柔軟な負荷分散が可能であると考えられる。
各ゾーンのディスク容量については、ゾーン毎に専用スライスを割り当てるなどで制限する。

*1:今回使用したマシンがCPUが1発だったため、動的リソースプールは設定できなかった。