[Solaris] Integrated Load Balancer

Solaris 11にはIntegrated Load Balancer(以下、ILB)が組み込まれており、実装サンプルがこのエントリで紹介されています。

System Administration Guide: IP Services - Integrated Load Balancer Overview
http://download.oracle.com/docs/cd/E19963-01/html/821-1453/gijjm.html

今回、サーバーでログを取得する上で好ましいため、ILB Operation モードはHALF-NAT(クライアントIPアドレスをマッピングしないためサーバーは本当のアドレスを知ることができるモード)を使用しました。Operationモードについて詳細は以下のリンクを参照して下さい。

System Administration Guide: IP Services - Features of ILB
ILB Operation Modes
http://download.oracle.com/docs/cd/E19963-01/html/821-1453/gkfcq.html#gkfbv

2ゾーンへ(どちらのゾーンでもApache Tomcatが動作)のトラフィックを負荷分散します。ILBはマルチホームゾーンとして構成します。

構成方法は以下の通りです。

Step-1 VNICを作成する
まず全てのインターフェースのVNICを作成するところから始めます。
bleonard@solaris:~$ sudo dladm create-vnic -l e1000g0 ilb0
bleonard@solaris:~$ sudo dladm create-vnic -l e1000g0 ilb1
bleonard@solaris:~$ sudo dladm create-vnic -l e1000g0 server1
bleonard@solaris:~$ sudo dladm create-vnic -l e1000g0 server2

Step-2 ゾーンを作成する
まだゾーンのファイルシステムを作っていない場合は…
bleonard@solaris:~$ sudo zfs create -o mountpoint=/zones rpool/zones
ILBゾーンを作成します。
bleonard@solaris:~$ sudo zonecfg -z ilb-zone
ilb-zone: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:ilb-zone> create
zonecfg:ilb-zone> set zonepath=/zones/ilb-zone
zonecfg:ilb-zone> set ip-type=exclusive
zonecfg:ilb-zone> add net
zonecfg:ilb-zone:net> set physical=ilb0
zonecfg:ilb-zone:net> end
zonecfg:ilb-zone> add net
zonecfg:ilb-zone:net> set physical=ilb1
zonecfg:ilb-zone:net> end
zonecfg:ilb-zone> verify
zonecfg:ilb-zone> exit 
Serverゾーンを2個(Server1、Server2)作成します。
bleonard@solaris:~$ sudo zonecfg -z server1-zone
server1-zone: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:server1-zone> create
zonecfg:server1-zone> set zonepath=/zones/server1-zone
zonecfg:server1-zone> set ip-type=exclusive
zonecfg:server1-zone> add net
zonecfg:server1-zone:net> set physical=server1
zonecfg:server1-zone:net> end
zonecfg:server1-zone> verify
zonecfg:server1-zone> exit

Step-3 ILBゾーンをインストールする
Serverゾーンはこのゾーンのクローンを使って構成します。
bleonard@solaris:~$ sudo zoneadm -z ilb-zone install
A ZFS file system has been created for this zone.
   Publisher: Using solaris (http://pkg.oracle.com/solaris/release/ ).
       Image: Preparing at /zones/ilb-zone/root.
       Cache: Using /var/pkg/download.
Sanity Check: Looking for 'entire' incorporation.
  Installing: Core System (output follows)
------------------------------------------------------------
Package: pkg://solaris/consolidation/osnet/osnet-incorporation@0.5.11,5.11-0.151.0.1:20101104T230646Z
License: usr/src/pkg/license_files/lic_OTN

Oracle Technology Network Developer License Agreement

...

               Packages to install:     1
           Create boot environment:    No
DOWNLOAD                                  PKGS       FILES    XFER (MB)
Completed                                  1/1         1/1      0.0/0.0

PHASE                                        ACTIONS
Install Phase                                  11/11

PHASE                                          ITEMS
Package State Update Phase                       1/1 
Image State Update Phase                         2/2 
               Packages to install:    45
           Create boot environment:    No
               Services to restart:     3
DOWNLOAD                                  PKGS       FILES    XFER (MB)
Completed                                45/45 12511/12511    89.1/89.1

PHASE                                        ACTIONS
Install Phase                            17953/17953 

PHASE                                          ITEMS
Package State Update Phase                     45/45 
Image State Update Phase                         2/2 
  Installing: Additional Packages (output follows)
               Packages to install:    46
           Create boot environment:    No
               Services to restart:     2
DOWNLOAD                                  PKGS       FILES    XFER (MB)
Completed                                46/46   4498/4498    26.5/26.5

PHASE                                        ACTIONS
Install Phase                              6139/6139 

PHASE                                          ITEMS
Package State Update Phase                     46/46 
Image State Update Phase                         2/2 

        Note: Man pages can be obtained by installing SUNWman
 Postinstall: Copying SMF seed repository ... done.
 Postinstall: Applying workarounds.
        Done: Installation completed in 499.617 seconds.

  Next Steps: Boot the zone, then log into the zone console (zlogin -C)
              to complete the configuration process.
sysidcfg ファイルを使って、ゾーンのシステム構成を自動化します。今回、rootパスワードを"abc123"にしました。
bleonard@solaris:~$ sudo cat /zones/ilb-zone/root/etc/sysidcfg 

system_locale=C
terminal=xterms
network_interface=ilb0 {
    primary
    hostname=ilb-ext
    ip_address=10.0.2.21
    netmask=255.255.255.0
    default_route=10.0.2.2
    protocol_ipv6=no}
network_interface=ilb1 {
    hostname=ilb-int
    ip_address=192.168.1.21

        default_route=NONE
    netmask=255.255.255.0
     protocol_ipv6=no}
security_policy=none
name_service=NONE
nfs4_domain=dynamic
timezone=US/Eastern
root_password=fto/dU8MKwQRI

起動して、ゾーンにログインします。
bleonard@solaris:~$ sudo zoneadm -z ilb-zone boot
bleonard@solaris:~$ sudo zlogin -C ilb-zone

[Connected to zone 'ilb-zone' console]
100/100
Hostname: ilb-zone
Loading smf(5) service descriptions: 3/3
 network_interface=ilb0 {
ilb0 is not a valid network interface  line 3 position 19
Creating new rsa public/private host key pair
Creating new dsa public/private host key pair
Configuring network interface addresses: ilb0 ilb1.

ilb-ext console login: root
Password: abc123
Jul  1 10:54:37 ilb-ext login: ROOT LOGIN /dev/console
Oracle Corporation      SunOS 5.11      snv_151a        November 2010
root@ilb-ext:~# 

ILBゾーンには2個のネットワークインターフェースがあるため、異なるネットワーク上のホスト宛てのパケットがILBゾーンのネットワークインターフェースに到着すると、適切なインターフェイスに転送するように設定する必要があります。
 root@ilb-ext:~# svcadm enable ipv4-forwarding

Step-4 Server1ゾーンをインストールする
ILBゾーンをコピーして、Server1ゾーンを作成します。Server1ゾーンを構成後、複製してServer2ゾーンを作成します。

まずilb-zoneを停止します。
bleonard@solaris:~$ sudo zoneadm -z ilb-zone halt
複製を作ります。
bleonard@solaris:~$ sudo zoneadm -z server1-zone clone ilb-zone
以下はserver1ゾーンで使うsysidcfgファイルです。
bleonard@solaris:~$ sudo cat /zones/server1-zone/root/etc/sysidcfg

system_locale=C
terminal=xterms
network_interface=PRIMARY {
 hostname=server1-zone
 ip_address=192.168.1.50
 netmask=255.255.255.0
 default_route=none
 protocol_ipv6=no}
security_policy=none
name_service=NONE
nfs4_domain=dynamic
timezone=US/Eastern
root_password=fto/dU8MKwQRI
Server1ゾーンを立ち上げてログインします。
bleonard@solaris:~$ sudo zoneadm -z server1-zone boot
Password: 
bleonard@solaris:~$ sudo zlogin -C server1-zone
[Connected to zone 'server1-zone' console]
Hostname: server1-zone
Creating new rsa public/private host key pair
Creating new dsa public/private host key pair
Configuring network interface addresses: server1.

server1-zone console login: root

Password: abc123
Jul  1 14:53:20 server1-zone login: ROOT LOGIN /dev/console
Last login: Fri Jul  1 13:54:37 on console
Oracle Corporation      SunOS 5.11      snv_151a        November 2010
ILBゾーンを起動します。
bleonard@solaris:~$ sudo zoneadm -z ilb-zone boot
Password: 

Step-5 インターネットアクセスを構成する
ILBゾーンから外向けにpingを発行し、疎通しているかを確認します。
root@ilb-ext:~# ping www.oracle.com

ping: unknown host www.oracle.com
別のターミナルを開きます。このターミナルはグローバルゾーンですので、/etc/resolve.confと/etc/nsswitch.confをグローバルゾーンからILBゾーンとServer1ゾーンにコピーします。
bleonard@solaris:~$ sudo cp /etc/resolv.conf /zones/ilb-zone/root/etc/.

Password: 
bleonard@solaris:~$ sudo cp /etc/nsswitch.conf /zones/ilb-zone/root/etc/.
bleonard@solaris:~$ sudo cp /etc/resolv.conf /zones/server1-zone/root/etc/.
bleonard@solaris:~$ sudo cp /etc/nsswitch.conf /zones/server1-zone/root/etc/. 
ILBゾーンに戻り、外部につながっていることを確認します。
root@ilb-ext:~# ping www.oracle.com
www.oracle.com is alive 
Server1ゾーンの場合、ILBゾーンを通って外部に接続するため、ルーティングを設定し、ルーティングルールを永続化しておきましょう。
root@server1-zone:~# route -p add  default 192.168.1.21
add net default: gateway 192.168.1.21
add persistent net default: gateway 192.168.1.21

root@server1-zone:~# ping www.oracle.com
www.oracle.com is alive 

Step-6 Tomcatをインストールする
root@server1-zone:~# pkg install tomcat tomcat-examples runtime/java
               Packages to install:     3
           Create boot environment:    No
               Services to restart:     2
DOWNLOAD                                  PKGS       FILES    XFER (MB)
Completed                                  3/3   1166/1166    38.9/38.9

PHASE                                        ACTIONS
Install Phase                              1504/1504 

PHASE                                          ITEMS
Package State Update Phase                       3/3 
Image State Update Phase                         2/2 
Loading smf(5) service descriptions: 1/1

root@server1-zone:~# svcadm enable http:tomcat6

Step-7 Serverゾーンへのルーティングを構成する
グローバルゾーンからServerゾーンに到達するためには、以下のルーティングルールを追加する必要があります。
bleonard@solaris:~$ sudo route -p add 192.168.1.0 10.0.2.21

Password: 
add net 192.168.1.0: gateway 10.0.2.21
add persistent net 192.168.1.0: gateway 10.0.2.21
これでグローバルゾーンからTomcatに接続できるようになりました。


Step-8 Serverゾーンの複製を作る
Server1ゾーンを停止して、ゾーンの複製を作成します。
bleonard@solaris:~$ sudo zoneadm -z server1-zone halt

bleonard@solaris:~$ sudo zoneadm -z server2-zone clone server1-zone
以下はServer1ゾーンで使ったsysidcfgファイルをServer2ゾーンで使うためにコピーします。
bleonard@solaris:~$ sudo cp /zones/server1-zone/root/etc/sysidcfg /zones/server2-zone/root/etc/sysidcfg


ホスト名とIPアドレスを変更し、デフォルトゲートウェイを設定しておきます。
修正後は以下のようになりました。
bleonard@solaris:~$ sudo cat /zones/server2-zone/root/etc/sysidcfg

system_locale=C
terminal=xterms
network_interface=PRIMARY {
 hostname=server2-zone
 ip_address=192.168.1.60
 netmask=255.255.255.0
 default_route=192.168.1.21
 protocol_ipv6=no}
security_policy=none
name_service=NONE
nfs4_domain=dynamic
timezone=US/Eastern
root_password=fto/dU8MKwQRI
Server2ゾーンを立ち上げ、ログインします。
bleonard@solaris:~$ sudo zoneadm -z server2-zone boot

bleonard@solaris:~$ sudo zlogin -C server2-zone
[Connected to zone 'server2-zone' console]
Hostname: server2-zone
Creating new rsa public/private host key pair
Creating new dsa public/private host key pair
Configuring network interface addresses: server2.

server2-zone console login: root
Password: abc123
Jul  6 10:39:54 server2-zone login: ROOT LOGIN /dev/console
Last login: Fri Jul  1 16:19:45 on console
Oracle Corporation      SunOS 5.11      snv_151a        November 2010
root@server2-zone:~# 
Server2ゾーンのインストールが非常に簡単に完了しただけでなく、Tomcatも既に動いている状態です。


Solarisを使うと、クラウド環境でスケールさせることがこんなに簡単なのですね。
忘れないうちに、Server1を立ち上げておきましょう。
bleonard@solaris:~$ sudo zoneadm -z server1-zone boot

Step-9 負荷分散を構成する
ここからがこのエントリのメインです。2個のサーバーに対して負荷分散するように設定しましょう。
ILBゾーンでILBをインストールし、起動します。
root@ilb-ext:~# pkg install ilb

               Packages to install:     1
           Create boot environment:    No
               Services to restart:     1
DOWNLOAD                                  PKGS       FILES    XFER (MB)
Completed                                  1/1       11/11      0.2/0.2

PHASE                                        ACTIONS
Install Phase                                  38/38 

PHASE                                          ITEMS
Package State Update Phase                       1/1 
Image State Update Phase                         2/2 
Loading smf(5) service descriptions: 1/1

root@ilb-ext:~# svcadm enable ilb
サーバーグループを定義します。
root@ilb-ext:~# ilbadm create-servergroup -s servers=192.168.1.50:8080,192.168.1.60:8080 tomcatgroup

root@ilb-ext:~# ilbadm show-servergroup 
SGNAME         SERVERID            MINPORT MAXPORT IP_ADDRESS
tomcatgroup    _tomcatgroup.0      8080    8080    192.168.1.50
tomcatgroup    _tomcatgroup.1      8080    8080    192.168.1.60
負荷分散のルールを設定します。今回は簡単なルールにしました。
  • インバウンドパケット(-i)の宛先が仮想IPアドレス(vip)およびポート番号 10.0.2.20:80に一致しているものを対象にする
  • パケットはラウンドロビン(rr)で振り分け(-m)られる
  • パケットの宛先(-o)はサーバーグループ(tomcatgroup)
  • ルールの名称はtomcatrule_rr
  • このルールを有効(-e)にし、永続化(-p)する
root@ilb-ext:~# ilbadm create-rule -e -p -i vip=10.0.2.20,port=80 -m lbalg=rr,type=HALF-NAT -o servergroup=tomcatgroup tomcatrule_rr
結果、以下のようなルールを確認できるはずです。
root@ilb-ext:~# ilbadm show-rule

RULENAME            STATUS LBALG       TYPE    PROTOCOL VIP         PORT
tomcatrule_rr       E      roundrobin  HALF-NAT TCP 10.0.2.20       80
root@ilb-ext:~# ilbadm show-rule -f
       RULENAME: tomcatrule_rr
         STATUS: E
           PORT: 80
       PROTOCOL: TCP
          LBALG: roundrobin
           TYPE: HALF-NAT
      PROXY-SRC: --
          PMASK: /32
        HC-NAME: --
        HC-PORT: --
     CONN-DRAIN: 0
    NAT-TIMEOUT: 120
PERSIST-TIMEOUT: 60
    SERVERGROUP: tomcatgroup
            VIP: 10.0.2.20
        SERVERS: _tomcatgroup.0,_tomcatgroup.1

最後に、外部に対し、VIP(10.0.2.20)向けのパケットはilb0に送られるように指示する必要があります。まず、ilb0のMACアドレスを確認します。
root@ilb-ext:~# dladm show-vnic ilb0

LINK         OVER         SPEED  MACADDRESS        MACADDRTYPE         VID
ilb0         ?            1000   2:8:20:bf:2a:d9   random              0
arpコマンドを使って、インターフェースilb0のアドレスを解決します。
root@ilb-ext:~# arp -s 10.0.2.20 2:8:20:bf:2a:d9 pub permanent

ここで、VIPへ向けてpingを打ってみましょう。
root@ilb-ext:~# ping 10.0.2.20
10.0.2.20 is alive

Step-10 負荷分散
ブラウザで仮想IPアドレスを閲覧してみましょう。Tomcatから応答が返るはずです。

ただ、これではどちらのサーバーが応答を返したのかわからないので、snoop.jspを編集して、サーバーのホスト名、IPアドレスを返すようにしてみましょう。snoop.jspを各サーバーゾーンの/var/tomcat6/webapps/examples/jsp/snpディレクトリに保存しましょう。
bleonard@solaris:~$ sudo cp Downloads/snoop.jsp /zones/server1-zone/root/var/tomcat6/webapps/examples/jsp/snp/.

bleonard@solaris:~$ sudo cp Downloads/snoop.jsp /zones/server2-zone/root/var/tomcat6/webapps/examples/jsp/snp/.
サーバーサイドIPアドレスのセクションをページの最下部に追加してみました。

Step-11 死活監視
簡単のためにヘルスチェックを無視していました。ですが、死んだサーバーに対してリクエストを送り続けるのは無意味です。死活監視では、ping probe、TCP probe、UDP probe、ユーザー定義スクリプトの4種類を使うことができます。今回は簡単なスクリプトで死活監視することにします。
root@ilb-ext:~# cat /var/hc-tomcat 

#!/bin/bash
result=`curl -s http://$2:8080`
if [ ${result:0:5} = "<meta" ]; then
        echo 0
else
        echo -1 
fi
ILBは次の変数をカスタムスクリプトのために提供しています。今回は$2のみを使っています。
$1 - VIP (literal IPv4 or IPv6 address)
$2 - Server IP (literal IPv4 or IPv6 address)
$3 - Protocol (UDP, TCP as a string)
$4 - Numeric port range (the user-specified value for hc-port)
$5 - maximum time (in seconds) that the test should wait before returning a failure. If the test runs beyond the specified time, it might be stopped, and the test would be considered failed. This value is user-defined and specified in hc-timeout.
スクリプトに実行権限があることを確認します(ilbdデーモンがスクリプトを実行しますが、これはrootユーザーではありません)。
root@ilb-ext:~# chmod +x /var/hc-tomcat
簡単にテストしてみましょう。
root@ilb-ext:~# /var/hc-tomcat n/a 192.168.1.50

0
以下のような死活監視ルールを作成します。
root@ilb-ext:~# ilbadm create-healthcheck -h hc-test=/var/hc-tomcat,hc-timeout=2,hc-count=1,hc-interval=10 hc-tomcat
hc-timeoutは死活監視時における応答待ちのタイムアウト時間です。hc-countはサーバーが死んでいると判断するまでに試行する回数です。hc-intervalは死活監視をする間隔です。
ルールを作成すると、以下のように設定した死活監視ルールを確認することができます。
root@ilb-ext:~# ilbadm show-hc

HCNAME        TIMEOUT COUNT   INTERVAL DEF_PING TEST
hc-tomcat     2       1       10       Y        /var/hc-script
死活監視ルールを作ったので、これを負荷分散ルールに組み込む必要があります。不幸にもilbadmには既存の負荷分散ルールを修正するコマンドがないので、作成した負荷分散ルールを削除の上、サイド作成する必要があります。
root@ilb-ext:~# ilbadm delete-rule tomcatrule_rr
今度は死活監視ルールを組み込んで、負荷分散のルールを作成します。
root@ilb-ext:~# ilbadm create-rule -e -p -i vip=10.0.2.20,port=80 -m lbalg=rr,type=HALF-NAT -h hc-name=hc-tomcat -o servergroup=tomcatgroup tomcatrule_rr
新しいルールができると、死活監視が有効になります。以下のように状況を確認できます。
root@ilb-ext:~# ilbadm show-hc-result
RULENAME      HCNAME        SERVERID      STATUS   FAIL LAST     NEXT     RTT
tomcatrule_rr hc-tomcat     _tomcatgroup.0 alive   0    10:39:51 10:40:02 2509
tomcatrule_rr hc-tomcat     _tomcatgroup.1 alive   0    10:39:57 10:40:09 1869
では、Server1のTomcatが停止している場合を想定します。
root@server1-zone:~# svcadm disable tomcat6
ブラウザをリフレッシュすると、Server2に振り向けられます。当然ながら、Server1での作業内容は失われてしまいます。ilbadm show-hc-resultコマンドを使ってServer1が死んでいることを確認できます。
root@ilb-ext:~# ilbadm show-hc-result

RULENAME      HCNAME        SERVERID      STATUS   FAIL LAST     NEXT     RTT
tomcatrule_rr hc-tomcat     _tomcatgroup.0 dead    4    10:43:36 10:43:45 1102
tomcatrule_rr hc-tomcat     _tomcatgroup.1 alive   0    10:43:42 10:43:53 5919
より詳細の情報が必要な方は、以下のリンクを参照して下さい。

System Administration Guide: IP Services - Administering Health Checks in ILB
http://download.oracle.com/docs/cd/E19963-01/html/821-1453/gkkjd.html

この環境を構成するには、かなりの作業が必要でした。負荷分散を事前に構成したVMをダウンロードできるようにすることは価値がありそうですかね?


原文はこちら。
http://blogs.oracle.com/observatory/entry/integrated_load_balancer

0 件のコメント:

コメントを投稿