入口でシステムがダウン:HAProxyが物理的限界に達する時
私はかつて、約50万件の同時接続を支えるAPIクラスターを扱ったことがあります。皮肉なことに、バックエンドノードはCPU使用率20%で「手持ち無沙汰」な状態である一方、HAProxyを実行しているサーバーは95〜98%という限界状態で悲鳴を上げていました。レイテンシ(遅延)は10msから一気に500msまで跳ね上がりました。問題は設定ミスではなく、ユーザ空間(userspace)のアーキテクチャにありました。パケットがカーネルとアプリケーション層の間で何度もコピーされるため、頻繁なコンテキストスイッチが発生し、帯域幅が埋まる前にCPUが過負荷になっていたのです。
もし、毎秒数百万パケット(PPS)を処理するスピードを持つレイヤー4(TCP/UDP)のトラフィック制御が必要なら、IPVS (IP Virtual Server)こそが求めていた「武器」です。面倒なインストールは不要で、IPVSは実際にはLinuxカーネルに組み込まれているモジュールであり、サーバーを高性能なロードバランサーに変えることができます。
IPVSの圧倒的な速さの秘密
IPVSの最大の強みは、カーネルのNetfilter内部で直接動作することです。NginxやHAProxyのようにパケットをアプリケーション層まで「段階的に引き上げる」のではなく、IPVSはネットワーク層でパケットをインターセプトし、即座にリダイレクトします。
このモデルでは、サーバーはDirector(ディレクター)としての役割を果たします。ハッシュテーブルをO(1)の速度で検索し、パケットをほぼ瞬時に転送します。その結果、10Gbpsのデータフローを処理しても, CPU負荷は非常に低いまま維持されます。
注意すべき3つの動作モードがあります:
- NAT (Network Address Translation): Directorが宛先IPを書き換えてReal Serverに転送します。設定は簡単ですが、往路と復路の両方を処理するため、Directorがボトルネックになりやすいのが難点です。
- DR (Direct Routing): これが最も「神」に近いモードです。DirectorはMACアドレスのみを書き換えます。Real Serverはパケットを受け取り、復路ではDirectorを介さずクライアントに直接レスポンスを返します。パフォーマンスにおいてこれに勝るものはありません。
- TUN (IP Tunneling): Real Serverが異なるネットワークセグメントにあり、VPNやインターネット経由で接続されている場合に使用します。
ipvsadmを使用したIPVS構築の実践
IPVSを制御するには、ipvsadmというツールを使用します。シンプルなWebサーバークラスターに対してNATモードを設定してみましょう。
1. ネットワーク構成の計画
以下のパラメータを準備します:
- Load Balancer (Director):
192.168.1.10 - Backend 1 & 2:
192.168.1.21および192.168.1.22 - Virtual IP (VIP):
10.0.0.100(クライアントがアクセスするアドレス)
大規模なクラスターのIP範囲を設計する場合、手動でのサブネット計算はミスが発生しやすいものです。私はいつも toolcraft.app/ja/tools/developer/ip-subnet-calculator を使用して、/27や/28のCIDR範囲を素早く計算し、最初から正確なバックエンド用の固定IPを計画しています。
2. インストールとカーネルの設定
Ubuntuに管理ツールをインストールします:
sudo apt-get update && sudo apt-get install ipvsadm -y
パケット転送機能を有効にするのを忘れないでください。これを忘れるとNATモードが動作しません:
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
3. 負荷分散ルールの設定
ラウンドロビン(rr)アルゴリズムを使用して、ポート80で動作する仮想サービスを作成します:
sudo ipvsadm -A -t 10.0.0.100:80 -s rr
-m パラメータ(NATモード)を使用して、2台のバックエンドサーバーをリストに追加します:
sudo ipvsadm -a -t 10.0.0.100:80 -r 192.168.1.21:80 -m
sudo ipvsadm -a -t 10.0.0.100:80 -r 192.168.1.22:80 -m
4. 成果の確認
次のコマンドを入力して、リアルタイムの転送テーブルを確認します:
sudo ipvsadm -L -n --stats
システムを流れるパケットの送受信数(Packet In/Out)とバイト数が透過的に表示されます。
HAProxyの代わりにIPVSを使うべきタイミングは?
最強のツールを選ぶことよりも、適切なツールを選ぶことの方が重要です。処理する層(レイヤー)に基づいて検討してください:
- HAProxyを選ぶ場合: ヘッダーの読み取り、Cookieの確認、SQLインジェクションの遮断、またはSSLの復号化(レイヤー7)が必要な場合です。IPVSはIPとポートしか見ないため、そこまで「スマート」ではありません。
- IPVSを選ぶ場合: 生のTCP/UDPを極めて高いスループットで転送するだけでよい場合です。IPVSは非常に安定しており、ユーザ空間で複雑な状態を維持しないため、メモリ不足(OOM)エラーが発生することはほとんどありません。
WikipediaやGitHubのような大手サイトでは、よく両方を組み合わせています。IPVSを最前面に置いて数百万PPSの負荷を受け止め、その後段にHAProxyクラスターを配置してアプリケーションロジックを処理させています。
実運用に向けて:Keepalivedを忘れずに
ipvsadm コマンドを叩くのは第一歩に過ぎません。本番環境で、唯一のDirectorノードがダウンすれば、システム全体が「行方不明」になってしまいます。
IPVSをKeepalivedと組み合わせることをお勧めします。Keepalivedは、Directorのペアを作成し、マスター・バックアップ構成を実現します。マスターに障害が発生した場合、バックアップが数秒以内に自動的にVIPを引き継ぎます。同時に、KeepalivedはReal Serverのヘルスチェック(Health Check)を自動的に行い、故障中のサーバーにパケットが送られないように保証します。
結論として、もしロードバランサーが「息切れ」しているなら、それをカーネル層に落とし込んでください。それが、ハードウェアのアップグレードに一銭もかけずにパフォーマンスを最適化する最も賢い方法です。

