2010/02/01

少しだけ気合いを入れてkeepalived, lighttpdを試してみた

はじめに

サーバ/インフラを支える技術」を読んでkeepalivedの使い方はだいたいわかってきたので、なんちゃってWebクラスタを構築してみました。 今回は新たにProxyサーバにlighttpdを使っています。環境はVMWare Workstation 6.5にDebian lennyのクローンを8インスタンス準備しました。

この本の中ではロードバランサやWebサーバの冗長化は個別に扱われていて、全体を冗長化させる場合については特に記述がないんですよね…。 それに関連する設定については記述がなかったりもするので、テストする事にしました。

結果的には、前回までの作業を踏まえて環境を構築したところ実WebサーバのMACアドレスをProxyサーバがVirtual_IPのものとして記憶してしまったので、これを防ぐ方法をみつける作業が必要でした。 そのために下記の参考文献に追加であたる事になりました。

参考文献
目次

サーバ環境

OSはDebian lennyです。10.0/16ネットワークにあるサーバはLANに接続されていません。 そのため必要なdebパッケージはProxyサーバなどの/var/cache/apt/archivesからコピーし、直接dpkgコマンドでインストールしました。

ProxyとWebサーバの前段にkeepalivedによるロードバランサを配置し、負荷分散を行なっています。 Proxyサーバにはlighttpdを使用し、URLのパスによって違うWebサーバに振り分ける事を想定しています。 今回はサーバが少ないですから、全リクエストをWebサーバに振り分けています。

将来的にはWebサーバとそのVirtual_IPが増加すると考えています。

設計時の前提

負荷分散と設定の容易さを優先的に考えています。 DR構成を取っているロードバランサは負荷について十分な性能を持っている前提で、ルータ、スイッチの冗長化は考慮していません。

もしルータ、スイッチを冗長化する際には、各サーバでは各スイッチに接続されているNICをbond0インタフェースにまとめる対応が必要になるでしょう。

ロードバランサからProxyサーバのヘルスチェックにはHTTP_GETを使用していません。 これはロードバランサからはProxyサーバ、Webサーバのいずれかが停止しているか判断がつかないからです。

ロードバランサ追加時の追加作業

プライマリのロードバランサが停止した場合には、セカンダリに処理が引き継がれます。 この影響による接続断はTCP/IPに限定すると、ほぼないと考えられます。 サーバ復旧時には既にActiveになっているロードバランサが処理を継続するため、任意のタイミングでネットワークに接続し立ち上げる事ができます。

今回はVRRP構成の初期状態をBACKUP, nopreempt, priority値を同一にしていますが、 3台以上で構成する場合には、priorityパラメータを調整する必要があります。

Proxy/Webサーバ追加時の追加作業

Proxy/Webサーバが停止した場合には、ロードバランサが検出し、リクエストが届かなくなります。 この場合の影響はロードバランサが検出するまで、Webブラウザがサーバに接続できなくなるケースが考えられます。

ロードバランサはdelay_loopの設定値に従ってヘルスチェックの間隔を設定するため、短くすればProxy/Webサーバのアクセスログ書き出しなどの負荷は高まりますが、障害検出までの時間は短縮できます。 delay_loop値を設定しない設定を試したところ、私の環境で毎秒500件ほどのリクエストがProxyサーバに記録されていました。

負荷分散のためにProxy/Webサーバを追加した際には、ロードバランサにIPアドレスを含むエントリを加えます。 この場合はkeepalivedの設定変更と再起動をスタンバイ側から行なえば、サービスへの影響はほぼないと考えられます。

各サーバの設定

ロードバランサ

ロードバランサ自身のIPアドレスは重要ではないので、図中では".x"と書いています。 DR構成を取っているので192.168.1.140の80番ポートに届いたパケットは透過的にProxyサーバに転送されます。 基本的な設定は前回使ったkeepalived.confファイルのIPアドレスを書き換えたものを使っています。

ただしProxyサーバの停止だけを検出するように、前段のロードバランサではTCP_CHECKを使用しています。

$ sudo apt-get install keepalived

192.168.1.xのロードバランサでの/etc/keepalived/keepalived.conf変更部分

...
    TCP_CHECK {
      connect_timeout 2
    }
...

作業は/etc/keepalived/keepalived.confを配置して、keepalivedを起動するだけで完了です。

$ sudo /etc/init.d/keepalived start
Proxyサーバ

今回はlighttpdをProxyサーバとしてパッケージから導入しました。

$ sudo apt-get install lighttpd

設定ファイルは/etc/lighttpd以下に配置されています。 Proxy用の設定は/etc/lighttpd/conf-available以下にあるので、次のコマンドで有効にします。

$ sudo /usr/sbin/lighttpd-enable-mod proxy

実際には/etc/lighttpd/conf-enabledディレクトリ以下にリンクが作成されます。 このファイルの中に設定を加えていきます。

$ sudo vi /etc/lighttpd/conf-enabled/10-proxy.conf

10-proxy.confファイルの内容

server.modules   += ( "mod_proxy" )
proxy.balance = "fair" 
proxy.server  = ( "" => ( ( "host" => "10.0.30.1" ) ) )

2台のProxyサーバで同じ設定を使っています。

また今回はlo:0にクラスタのIPアドレスを追加しています。

/etc/network/interfacesファイルへの追記分

auto lo:0
iface lo:0 inet static
  address 192.168.1.140
  netmask 255.255.255.255

WebブラウザにProxyサーバのMACアドレスが192.168.1.140のものとして渡されないように、 ARPリクエストに答えないように設定を変更しています。 eth0は192.168.1.0/24ネットワークに接続されているNICです。

/etc/sysctl.confファイルの抜粋

...
net.ipv4.conf.eth0.arp_ignore=1
net.ipv4.conf.eth0.arp_announce=2
...

最後にlighttpdを起動して終りです。パッケージ導入時点で起動しているのでrestartをしています。

$ sudo /etc/init.d/lighttpd restart
Webサーバ

特別な設定項目はありません。 apacheを導入しデフォルトの/var/www/index.htmlファイルにホスト名を加えたものを使用しました。

$ sudo apt-get install apache2-mpm-worker

今回はlo:0ではなく、もう一つのiptablesを設定する方法を採用しました。

/etc/network/interfacesファイルのeth0設定抜粋

auto eth0
iface eth0 inet static
  address 10.0.30.2
  netmask 255.255.0.0
  post-up /sbin/iptables -t nat -A PREROUTING -p tcp -d 10.0.30.1 -j REDIRECT
  post-down /sbin/iptables -t nat -F

やはりARPリクエストに答えないようにsysctl.confファイルを修正しています。

/etc/sysctl.confファイルの抜粋

...
net.ipv4.conf.eth0.arp_ignore=1
net.ipv4.conf.eth0.arp_announce=2
...

apacheは既に起動しているので、再起動します。

$ sudo /etc/init.d/apache2 restart

まとめ

今回はsysctl.confの設定が追加で必要だということに気がつかずに、最後段のWebサーバのMACアドレスがProxyサーバのARPテーブルに記憶されてしまい振り分けが行なわれずに困ってしまいました。

もしWebサーバやProxyサーバを停止しても、フェイルオーバーが行なわれないとしたらVirtual_IPのMACアドレスがどこのものか確認してください。

JMeterを使って負荷をかけている最中にProxyやWebサーバを停止しましたが、ロードバランサはおおむね1秒以下でサーバのダウンを検出しています。

あとはFirewallをどこに設置するかという問題でしょうか。 各ロードバランサの前にルータ兼Firewallを配置するのは一番お手軽ですね。 ただそこにかけるお金がひどい事になりそうなので、社内LANぐらいなら、少し手間ですが、ProxyサーバをFirewallとして構成するのも良いかもしれません。

もしサーバが増えないのであれば、中段のロードバランサと斜めの接続はやめて上下で2系統にして、前段のロードバランサからWebサーバの稼働状況をヘルスチェックするような、シンプルな構成にするべきでしょうね。

0 件のコメント: