Create: 2012/10/23
LastUpdate: 2012/10/27
同一サブネット内でWEBサーバの負荷分散を行うロードバランサを構築します。
構築イメージは下図のとおり。
クライアントから http://192.168.1.70/ にアクセスすると、WEBサーバ#1、WEBサーバ#2 に負荷分散します。
なお、Keepalived のルーティング方式はDSR(Direct Server Return)を使用します。下図のような同一サブネット内の構成ではルーティング方式にNATは使用できません。DSRとNATの違いについては「LVSで実現するロードバランサ - KLablabWiki」や「高トラフィックに対応できるLinuxロードバランサを目指して ~ LVSをNATからDSRへ」が参考になります。
1.仮想マシンの用意
ロードバランサ1台とWEBサーバ2台を XenServer6.02 の仮想マシンで用意します。
仮想マシンには、 こちら の手順で最小構成の CentOS6.0 をインストールしたあと、CentOS6.3 に yum で update しました。
この時点でのサーバの状態は以下のとおり。
- OS: CentOS6.3
- 導入パッケージ: 最小構成
- デフォルト言語: ja_JP.UTF-8
- タイムゾーン: Asia/Tokyo
- SELinux: 無効
- ファイヤーウォール: iptables 停止、ip6tables 停止
2.ロードバランサの構築
epel レポジトリ から keepalived と ipvsadm をインストールします。 ipvsadm は、IPVSを制御するためのツールです。
# yum --enablerepo=epel install keepalived ipvsadmkeepalived を以下のように設定します。
- スケジューリングアルゴリズム: rr (round-robin)
- ヘルスチェック種別: HTTP_GET
- ヘルスチェックページ: /index.html
- ヘルスチェックの条件: ステータスコードが200
- ヘルスチェックのタイムアウト: 5秒
# vi /etc/keepalived/keepalived.conf ! IPVS virtual_server_group WEB_GROUP1 { 192.168.1.70 80 } virtual_server group WEB_GROUP1 { delay_loop 3 lvs_sched rr lvs_method DR protocol TCP virtualhost example.org real_server 192.168.1.81 80 { weight 1 inhibit_on_failure HTTP_GET { url { path /index.html status_code 200 } } connect_port 80 connect_timeout 5 } real_server 192.168.1.82 80 { weight 1 inhibit_on_failure HTTP_GET { url { path /index.html status_code 200 } } connect_port 80 connect_timeout 5 } }設定ファイルの各パラメータの意味については、以下のページが参考になります。
Keepalived の設定ファイルに記載した仮想IP(192.168.1.70)をeth0にIPエイリアスします。今回は動作確認したいだけなので、一時的な設定にしています。再起動すると、この設定は消えます。再起動しても消えないようにしたい場合は、 ここ を参考にしてください。
# ifconfig eth0:0 192.168.1.70ロードバランサのネットワーク関連の状態は以下のとおり。赤字はコマンド。
# ifconfig -a eth0 Link encap:Ethernet HWaddr 46:C2:09:46:6D:DC inet addr:192.168.1.61 Bcast:192.168.1.255 Mask:255.255.255.0 inet6 addr: 2001:c90:8023:a9d1:44c2:9ff:fe46:6ddc/64 Scope:Global inet6 addr: fe80::44c2:9ff:fe46:6ddc/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12608 errors:0 dropped:0 overruns:0 frame:0 TX packets:2262 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2448862 (2.3 MiB) TX bytes:295391 (288.4 KiB) Interrupt:24 eth0:0 Link encap:Ethernet HWaddr 46:C2:09:46:6D:DC inet addr:192.168.1.70 Bcast:192.168.1.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 Interrupt:24 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) # route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 * 255.255.255.0 U 0 0 0 eth0 link-local * 255.255.0.0 U 1002 0 0 eth0 default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 # service iptables status iptables: ファイアウォールが稼働していません。
3.WEBサーバの構築
以下、WEBサーバ2台を同じように構築します。
まず、Apache をインストールします。
# yum install httpd動作確認とヘルスチェックを兼ねたページを作成します。動作確認でどちらのWEBサーバで動いたかわかるように、WEBサーバ#1 と WEBサーバ#2 ではページの内容を変えます。
# cat /var/www/html/index.html <html> <head> <title>WEB#1 - TOP PAGE</title> </head> <body> <h1>WEB#1 - Top Page</h1> </body> </html>Apache を起動します。
# service httpd startiptables コマンドを使用して、ロードバランサの仮想IP(192.168.1.70)宛てのパケット自分宛にDNATします。これは、DSR構成時だけに必要な対応です。
# iptables -t nat -A PREROUTING -p tcp -d 192.168.1.70 -j REDIRECTWEBサーバのネットワーク関連の状態は以下のとおり。赤字はコマンド
# ifconfig -a eth0 Link encap:Ethernet HWaddr 46:A5:F7:B9:DE:06 inet addr:192.168.1.81 Bcast:192.168.1.255 Mask:255.255.255.0 inet6 addr: 2001:c90:8023:a9d1:44a5:f7ff:feb9:de06/64 Scope:Global inet6 addr: fe80::44a5:f7ff:feb9:de06/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:15240 errors:0 dropped:0 overruns:0 frame:0 TX packets:3282 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:2740599 (2.6 MiB) TX bytes:471679 (460.6 KiB) Interrupt:247 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:18 errors:0 dropped:0 overruns:0 frame:0 TX packets:18 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1380 (1.3 KiB) TX bytes:1380 (1.3 KiB) # route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.1.0 * 255.255.255.0 U 0 0 0 eth0 link-local * 255.255.0.0 U 1002 0 0 eth0 default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 # service iptables status テーブル: nat Chain PREROUTING (policy ACCEPT) num target prot opt source destination 1 REDIRECT tcp -- 0.0.0.0/0 192.168.1.70 Chain POSTROUTING (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination
4.動作確認
WEBサーバ2台でApacheが起動していることを確認したら、ロードバランサで Keepalived を起動します。
# service keepalived startロードバランサで ipvsadm コマンドを実行して、仮想サーバテーブルにエントリが追加されているか確認します。
# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.1.70:80 rr -> 192.168.1.81:80 Route 1 0 0 -> 192.168.1.82:80 Route 1 0 0クライアントからブラウザで http://192.168.1.70/ にアクセスします。
再表示ボタンをクリックすると下図のページが交互に表示され負荷分散を確認できます。
ちにみに、ここではIE7を使用して確認していますが、IE7以外のブラウザで、毎回、"favicon.ico" をGETするタイプのブラウザは、ページが切り替わりません。再表示するたびに2回リクエストし、WEBサーバ#1から "index.html" をGETし、WEBサーバ#2から "favicon.ico" をGETするからです。
WEBサーバ#1のログを見ると、以下のとおり。"KeepAliveClient"は、ロードバランサのヘルスチェックです。クライアントからのアクセスには、クライアントのIPアドレスが記録され、ロードバランサからのアクセスは、仮想IPではなく実IPが記録されています。
192.168.1.61 - - [24/Oct/2012:09:44:36 +0900] "GET /index.html HTTP/1.0" 200 105 "-" "KeepAliveClient" 192.168.1.61 - - [24/Oct/2012:09:44:42 +0900] "GET /index.html HTTP/1.0" 200 105 "-" "KeepAliveClient" 192.168.1.10 - - [24/Oct/2012:09:44:47 +0900] "GET / HTTP/1.1" 200 105 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; InfoPath.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)" 192.168.1.61 - - [24/Oct/2012:09:44:48 +0900] "GET /index.html HTTP/1.0" 200 105 "-" "KeepAliveClient"