Linux Virtual ServerとKeepalivedで作る冗長化ロードバランサ

図3 2台のロードバランサを使用してロードバランサの冗長化を行う構成

 多数のクライアントがアクセスするような負荷の高いサービスや停止させられないサービスを運用する場合、複数のサーバーを使ってサービスの負荷分散や冗長化を行うのが一般的だ。本記事では、「Linux Virtual Server(LVS)」を使ってこのような構成を実現する方法について紹介する。

Linuxサーバーをロードバランサにする「Linux Virtual Server」(LVS)

 最近では多数のCPUコアを持つサーバーが安価で利用できるようになり、サーバー1台の処理能力は飛躍的に向上している。しかし、リクエストの処理に多くのリソースを使用するようなサービスや、短時間に多数のリクエストを処理する必要があるサービスでは、1台のサーバーだけでは処理能力が不足する場合がある。このような場合、複数台のサーバーで同じサービスを運用し、ロードバランサを使ってリクエストを振り分けることで負荷の分散を図ることが多い。

 ロードバランサは通常サーバーとクライアントの間に設置され、クライアントからのリクエストを受け取って一定のルールの下サーバーに振り分ける、という処理を行う。設置方法はネットワーク環境によって異なるが、ロードバランサ自体にクライアントからアクセスできるIPアドレスが与えられ、あたかもロードバランサがサービスを提供しているように見せる構成を取ることが多い(図1)。

図1 ロードバランサを使用する場合のネットワーク構成例
図1 ロードバランサを使用する場合のネットワーク構成例

 ロードバランサは専用のハードウェア製品として提供されるほか、ロードバランサ機能が搭載されたルーター製品もある。しかし、専用ハードウェアは比較的高価であるため、安価なLinuxサーバーをロードバランサとして利用する例も多い。Linuxサーバーをロードバランサとして使用するためのソフトウェアとして有名なのが、今回紹介する「Linux Virtual Server(LVS)」だ。

ロードバランサを提供するLinux Virtual Serverと冗長化機能を提供するKeepalived

 LVSはあらかじめ指定された条件に基づいてリクエストをサーバーに振り分けるという動作を行うソフトウェアだ。Linuxカーネルに組み込んで使用するカーネルモジュールと設定や管理を行うためのipvsadmコマンドから構成されており、Red Hat Enterprise Linuxやその互換ディストリビューションであるCentOSなどでは標準でカーネルにLVS機能が組み込まれている。

 また、LVSは「Keepalived」と呼ばれるソフトウェアと組み合わせて利用されることが多い。LVSにはロードバランス対象を監視する仕組みが用意されていないため、もしサービスを提供するサーバー群の一部がトラブルで停止した場合でも、それらのサーバーに対しリクエストを振り分けてしまう可能性がある。Keepalivedはサービスの稼働状態を監視するソフトウェアで、サービスが停止していたらそのサーバーへのリクエストの振り分けをやめるようLVSの設定を変更する、という機能を持っている。

 Keepalivedにはロードバランサ自体の稼働状況を監視し、ロードバランサが停止していたら自動的にバックアップとして用意しておいたロードバランサに切り替える機能も用意されている。ロードバランサを使っている場合、サービスを提供するサーバーが稼働していたとしても、ロードバランサ自体が停止してしまったら外部からサービスへのアクセスができなくなってしまう。keepalibedを使ってLVS自体を冗長化することで、サービスの冗長化をより完全なものとすることが可能となる。

 以下ではRed Hat Enterprise Linux(RHEL) 6.3互換のCentOS 6.3を使用し、まずLVSを使った基本的なロードバランサ設定について紹介する。続けてKeepalivedを用いたサービスの稼働状態の監視、そして最後にKeepalivedによるロードバランサの冗長化について解説していく。

LVS環境の構築とロードバランシング設定

 LVSを使ってロードバランサを構築するには、ロードバランサとして使用するサーバー側のLinuxカーネルにLVSをあらかじめ組み込んでおく必要がある。RHELおよびその互換OSでは、デフォルトでカーネルモジュール(ip_vsモジュール)としてLVSを組み込めるようになっているので、特別な設定は不要だ。ただし、カーネルのカスタマイズなどを行っている場合は、LVSを有効にできるように設定してカーネルをビルドしておく必要がある。

 LVSでは「ipvsadm」というコマンドを使用してロードバランサの設定を行う。RHELやその互換環境では同名のパッケージでこのコマンドが提供されているので、あらかじめインストールを行っておく。

# yum install ipvsadm

LVSを使ったロードバランサを実現するためのネットワーク構成

 ロードバランサはサーバーの代わりにクライアントからリクエストを受け取り、そのリクエストを一定のルールでサーバーに転送する処理を行う。LVSではTCP/IPレベルでパケットを転送する「レイヤ4スイッチング」という方式でこれを実現している。パケットの転送方式としてはNATおよびダイレクトルーティング、トンネリングという3つが用意されている(表1)。

表1 Linux Virtual Serverでのパケット転送方式
転送方式説明
NATIPパケットに対しロードバランサでNATを行ってパケットをサーバーに転送する
ダイレクトルーティングIPパケットを書き換えずにパケットをサーバーに転送する
トンネリングIPパケットをカプセル化した上でサーバーに転送する

 NAT方式はロードバランサでNATを行ってパケットを転送する方式で、ロードバランサはローカルネットワークとWANの接続部分に設置する。この方式はサーバーがローカルネットワーク内にある場合など、サーバーとクライアントが直接接続できない場合でも利用できるのが特徴だ。いっぽう、ダイレクトルーティング方式やトンネリング方式はクライアントからサーバーへの通信についてはロードバランサを経由するが、サーバーからクライアントへの通信についてはロードバランサを経由しないのが特徴となる。さらにトンネリング方式ではロードバランサとサーバー間の通信にカプセル化されたIPパケットが利用されるため、ロードバランサとサーバーが別のネットワーク上にあっても利用できるのが特徴だ。

 LVSではネットワーク構成に応じたパケット転送方式を選択できるが、もっとも一般的なのNATを利用する構成だ。その理由として、よりセキュリティを向上させることが可能である点が挙げられる。サーバーをインターネットから直接アクセスできないローカルネットワーク内に設置し、ロードバランサーに対してのみインターネットからのアクセスが可能な構成にすることで、サーバーを狙った攻撃をブロックすることができる。また、もしロードバランサが攻撃された場合でも、ロードバランサ上ではサービスは運用されていないため、サービスへの被害を最小限に抑えることができる。