ロードバランスしたい Part1

最近わけあって、 AWS を使う機会があったのですが、ELB を使ってのロードバランスがあまりにも簡単だったので驚きました。

今回はそんな便利なサービスを使わずにロードバランスしてみようということで、ローカル PC 上で VM を作成し、IPVS + KeepAlived でロードバランスをしてみます。

目次

1. 構成
2. Vagrant で VM を立ち上げる
3. web サーバの設定
4. ロードバランスの設定
5. 検証
6. まとめ
7. 参考にしたもの

1. 構成

今回は、ロードバランサと Webサーバが同一ネットワーク内にいる DSR 構成でのロードバランスをしてみたいと思います。

f:id:ryouta768:20140323230037p:plain

2. VagrantVM を立ち上げる

まずは Vagrant を使用して、ローカル PC 上に 今回使用する VM を作成します。

今回は 3 つの VM を使用するので、

$vagrant init [ボックス名]
$vagrant up

のようなコマンドを使って、 VM を 3 つ立ち上げます。

"vagrant init"コマンドを使用した後、3 つの VM をプライベートネットワークで繋ぐため、 Vagrantfile を編集します。

# config.vm.network :private_network, ip: "192.168.33.10" <- ここのコメントアウトを外す
config.vm.network :private_network, ip: "192.168.33.10" <- IP アドレスの部分を 3 つの VM で重複しないように変える

3. Web サーバの設定

Web サーバとして動作させる VM に "vagrant ssh" して、接続します。その後、apachephp をインストールします。

$vagrant ssh
$sudo yum -y install httpd
$sudo yum -y install php

ドキュメントルートである、/var/www/html に 以下の index.php を置きます。

<?php
printf("Hi, I'm [ホスト名] server.");
?>

ホスト名のところは、それぞれの Web サーバーの名前に変えて、ロードバランスがわかりやすいようにします。

ページが正しく表示されるか確認します。

f:id:ryouta768:20140323230050p:plain

f:id:ryouta768:20140323230054p:plain

KeepAlived が死活監視を行うためにアクセスするページ(/var/www/html/health.html)も設置しておきます。

<html><head><title>Health Check Page</title></head><body><h1>Health Check Page</h1></body></html>

4. ロードバランスの設定

IPVS + KeepAlived を使用して、ロードバランスをします。

IPVS はカーネルに組み込まれているため、まず KeepAlived と IPVSの設定に使うツール ipvsadm をインストールします。

$sudo yum -y install keepalived
$sudo yum -y install ipvsadm

次に、"/etc/keepalived/keepalived.conf" でロードバランスの設定を行います。

virtual_server_group example {
    192.168.33.254 80 <- 仮想IPアドレス
}
virtual_server group example {
        lvs_sched rr    <- ラウンドロビン
        lvs_method DR   <- DSR 構成
        protocol TCP
        virtualhost health
        real_server 192.168.33.11 80 { <- Web1サーバー
            weight 1
                HTTP_GET {
                    url {
                        path /health.html <- 死活監視のためのページ
                            status_code 200
                    }
                    connect_port 80
                    connect_timeout 5
                }
        }
        real_server 192.168.33.12 80 { <- Web2サーバー
            weight 1
                HTTP_GET {
                    url {
                        path /health.html <- 死活監視のためのページ
                            status_code 200
                    }
                    connect_port 80
                    connect_timeout 5
            }
        }
}

keepalived を起動します。

$sudo service keepalived start

ipvsadm を使用して、keepalived がweb1、web2 サーバーを認識しているか確認します。

$ sudo 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.33.254:80 rr
  -> 192.168.33.11:80             Route   1      0          0
  -> 192.168.33.12:80             Route   1      0          0

実はこのままでは、"http://192.168.33.254/"にアクセスしても、ページが返ってきません。

Web1サーバーとWeb2サーバーで"192.168.33.254"へのアクセスを受け入れる設定を行わなければなりません。

その設定には、iptables を使います。

$ sudo iptables -t nat -A PREROUTING -d 192.168.33.254 -j REDIRECT

上のコマンドを使用することにより、192.168.33.254宛のパケットを Web1、Web2 サーバーで受け取る事が出来るようになります。

5. 検証

ブラウザで、http://192.168.33.254/ にアクセスしてみます。

f:id:ryouta768:20140323230059p:plain

f:id:ryouta768:20140323230101p:plain

交互に表示されます。

ab コマンドを使用して、ラウンドロビンでロードバランスされていることを確認します。

$ ab -n 10 -c 10 http://192.168.33.254/?001 # 10クライアント同時接続で、10回リクエストを行う
[Web1]
$ sudo grep "?001" /var/log/httpd/access_log | wc -l
5
[Web2]
$ sudo grep "?001" /var/log/httpd/access_log | wc -l
5

ということで、ロードバランスされています。

6. まとめ

今回、IPVS + KeepAlived でロードバランスを行いました。

DSR 構成でのロードバランスだったので、次回は NAT 構成のロードバランスをしてみたいと思います。

また、パケットキャプチャでの検証も行ってみたいと思います。

7. 参考にしたもの

/etc/keepalived/keepalived.conf の設定については、

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

[24時間365日] サーバ/インフラを支える技術 ?スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)

を参考にしました。

その他参考にしたページは以下です。

[ELB]負荷分散とEC2へのリクエスト数との関係について調べてみた

負荷分散について考えてみる②: keepalivedの設定