【第5回】AlmaLinux 9:LVSとKeepalivedによるWAP負荷分散クラスターの構築

本連載ではこれまで、M365のハイブリッド認証を支えるWindowsベースのコンポーネント(ADDS、ADFS、WAP)の設計と構築を進めてきました。第4回でDMZに配置したWAP(Web Application Proxy)は、インターネットからの全認証トラフィックを受け止める極めて重要なフロントエンドですが、1台のみの構成では単一障害点(SPOF)となり、朝のログインストームなど高負荷なトラフィックに耐え切れません。

そこで今回、いよいよ私たちLinuxエンジニアの真骨頂である「AlmaLinux 9を用いた超高速L4ロードバランサー(LVS: Linux Virtual Server)」の構築に挑みます。
商用ハードウェアロードバランサー(F5 BIG-IPやCitrix ADC等)に匹敵するパケット処理性能を、オープンソースの「IPVS」カーネルモジュールと「Keepalived」による冗長化クラスターで実現し、WAPへのTCP 443(HTTPS)通信を無停止で負荷分散させるエンタープライズアーキテクチャを完成させましょう。

コウ君

リナックス先生!ついにLinuxの出番ですね!でも、ロードバランサーならNginxやHAProxyの方が設定ファイルも読みやすいし、Web上の解説記事も多いと思うんですが、どうしてわざわざカーネルモジュールのIPVS(LVS)を使うんですか?

リナックス先生

コウ君、第1回でも少し触れたけれど、WAPの前段にリバースプロキシ(L7)を置くのはアーキテクチャの多重化になってオーバーヘッドが大きすぎるの。LVSは「L4(トランスポート層)」で単純にTCPパケットの宛先IPを書き換えてWAPに流すだけだから、暗号化通信の復号(SSLターミネーション)を行わず、極めて低いCPU負荷で数万コネクションをさばけるのよ。M365認証のフロントエンドとしては、LVSの「トランスペアレント(透過的)なルーティング」が最強のソリューションなの!


1. LVS(Linux Virtual Server)とKeepalivedのアーキテクチャ

構築に入る前に、LVSがパケットをどのように処理し、Keepalivedがどのように高可用性を担保するのか、システムの全体像を正確に理解しておく必要があります。この基礎知識が、後々のトラブルシューティングで強力な武器となります。

1-1. L4ロードバランシングの優位性とIPVSの仕組み

LVSの正体は、Linuxカーネルに組み込まれた「IPVS (IP Virtual Server)」というモジュールです。IPVSはOSI参照モデルのレイヤー4(TCP/UDP層)で動作し、受信したパケットの送信元・宛先IPアドレスやポート番号のみを解析して、バックエンドのリアルサーバー(今回であればWAP)へ転送します。

NginxやHAProxyなどのL7リバースプロキシは、一度TCPコネクションを自身のユーザー空間で終端(Terminate)し、バックエンドへ新しいTCPコネクションを張り直すため、ソケットファイルディスクリプタやメモリを大量に消費します。一方、IPVSはカーネル空間内でパケットのヘッダーを書き換えるだけでフォワーディングするため、トラフィックがどれほど増大してもCPUやメモリの消費が極めて少なく、ハードウェアのネットワークカードの限界に近いスループットを叩き出します。

1-2. LVS-NAT方式 vs LVS-DR(DSR)方式の選択

LVSがパケットをバックエンドに転送するルーティング方式には、主にNAT方式とDR方式(DSR方式)の2つがあります。それぞれの特徴を比較します。

  • LVS-DR (Direct Routing) 方式:
    LVSはパケットの宛先MACアドレスのみをバックエンドのMACアドレスに書き換えて転送します。バックエンド(WAP)は受け取ったパケットを処理し、LVSを経由せずに直接クライアントへ応答(Direct Server Return)します。スループットは最強ですが、WAP側に仮想IP(VIP)を持たせるためのループバックアダプターの設定やARP応答の抑制など、Windows環境でのネットワーク設定が極めて複雑になります。
  • LVS-NAT (Network Address Translation) 方式:
    LVSはパケットの宛先IPをVIPからWAPの物理IPに書き換えて(DNAT)転送します。WAPからの戻りパケットは必ずLVSを経由し、LVSが送信元IPをVIPに書き換えて(SNAT)クライアントへ応答します。すべての通信がLVSを経由するためLVS自体がボトルネックになる可能性はありますが、設定がシンプルで、Windows側のネットワーク変更が最小限で済むため、本連載では運用保守性を重視し「LVS-NAT方式」を採用します。現代のCPU性能であれば、認証トラフィック程度でNAT処理がボトルネックになることはまずありません。

1-3. KeepalivedによるVRRP冗長化とヘルスチェック

IPVS自体は単なるカーネルのルーティングモジュールであり、自身のサーバー冗長化やバックエンドの死活監視(ヘルスチェック)機能を持っていません。これを補完する強力な相棒が「Keepalived」デーモンです。

Keepalivedは、VRRP(Virtual Router Redundancy Protocol)というプロトコルを用いて、複数台のLVSサーバー間で「仮想IP(VIP)」を共有し、Active/Standby(Master/Backup)のクラスターを構成します。Masterノードがダウンすると、瞬時にBackupノードがVIPを引き継ぎます。同時に、バックエンドのWAPに対して定期的にTCPアクセス等のヘルスチェックを行い、ダウンを検知したWAPを自動的にIPVSのルーティングテーブルから切り離すという、LVS運用における必須のパートナーです。

2. AlmaLinux 9:OSの初期設定とパッケージ導入

それでは、AlmaLinux 9をインストールした2台のサーバー(例: lvs01, lvs02)を用意し、LVS-NAT方式のクラスターを構築していきます。

2-1. ネットワークとパケットフォワーディング(sysctl)の設定

LVS-NAT方式では、LVSサーバー自身がルーターとしてパケットを中継(フォワード)するため、LinuxカーネルのIPフォワーディング機能を有効にする必要があります。これを忘れると、パケットがLVSで破棄されてしまいます。

# 両方のLVSサーバー(lvs01, lvs02)で実行
# IPv4のパケットフォワーディングを有効化
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-ipforward.conf

# 設定の反映
sudo sysctl -p /etc/sysctl.d/99-ipforward.conf

⚠️ 注意点:SELinuxの状態について
ロードバランサーのようなネットワークインフラ機器において、SELinuxがパケットフォワーディングやKeepalivedのプロセスに干渉し、原因不明のルーティング障害を引き起こすことがあります。高度なポリシーチューニングができる場合はEnforcingでも構いませんが、LVS専用機として構築する場合、トラブルシューティングの観点から Permissive に設定する運用もエンタープライズの現場では多く見られます。

2-2. ipvsadmとKeepalivedのインストール

IPVSモジュールをユーザー空間から操作・確認するための管理ツール ipvsadm と、冗長化・ヘルスチェックを担う keepalived をインストールします。

# 必要なパッケージのインストール
sudo dnf install -y keepalived ipvsadm

# Keepalivedの自動起動の有効化
sudo systemctl enable keepalived

2-3. firewalldにおけるVRRPとフォワーディングの許可

AlmaLinux 9の標準ファイアウォールである firewalld は、デフォルトで外部からの通信やフォワーディングを厳格に制限しています。LVSとして正常に動作させるためには、以下の通信を明示的に許可しなければなりません。

  1. クライアントからのHTTPS通信(TCP 443)
  2. LVSノード間(lvs01とlvs02)のVRRPマルチキャスト通信(プロトコル番号112)
  3. NAT方式における内部ネットワークへのパケットマスカレード(IPマスカレード許可)
# パブリックゾーン(DMZ向けインターフェース側)でのHTTPS許可
sudo firewall-cmd --zone=public --add-service=https --permanent

# VRRP通信(プロトコル112)の許可(スプリットブレイン防止に必須)
sudo firewall-cmd --zone=public --add-protocol=vrrp --permanent

# NAT/フォワーディングのためのマスカレード有効化
sudo firewall-cmd --zone=public --add-masquerade --permanent

# 設定のリロード
sudo firewall-cmd --reload
コウ君

firewalldの設定、いつも「とりあえず全部許可」にしたくなっちゃうんですけど、VRRP(プロトコル番号112)を明示的に許可しないと、lvs01とlvs02がお互いの死活を確認できなくて、両方とも自分がMasterだと思い込む「スプリットブレイン」が発生しちゃうんですね。過去にネットワークがループして社内が全滅したトラウマがあるので、ここは絶対忘れないようにします!

3. Keepalived.confの設計と詳細パラメータ解説

インフラの振る舞いを決定づけるのが、Keepalivedのメイン設定ファイル /etc/keepalived/keepalived.conf です。今回はM365の認証トラフィック(SAML/HTTPS)を想定した、プロフェッショナルな設定を記述します。

以下の設定を lvs01(Masterノード)に記述します。

sudo cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.org
sudo nano /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL_01  # lvs02の場合は LVS_DEVEL_02 など一意の名前に変更
}

# --- VRRPインスタンス(仮想IP)の設定 ---
vrrp_instance VI_1 {
    state MASTER           # lvs02の場合は BACKUP に設定
    interface eth0         # DMZ側のネットワークインターフェース名に合わせて変更
    virtual_router_id 51   # LVSノード間で同一のIDを設定
    priority 100           # MASTERの優先度(BACKUPは90などに下げる)
    advert_int 1           # VRRPパケットの送信間隔(秒)

    authentication {
        auth_type PASS
        auth_pass 1111     # LVSノード間で共通のパスワード
    }
    virtual_ipaddress {
        192.168.10.100/24  # 外部からアクセスされる仮想IP(VIP)
    }
}

# --- 仮想サーバー(ロードバランサー)の設定 ---
virtual_server 192.168.10.100 443 {
    delay_loop 6           # ヘルスチェックのポーリング間隔(秒)
    lb_algo rr             # スケジューリングアルゴリズム: ラウンドロビン(rr)
    lb_kind NAT            # ルーティング方式: LVS-NAT方式
    persistence_timeout 1800 # セッション維持時間(重要: 30分 = 1800秒)
    protocol TCP           # 対象プロトコル: TCP

    # リアルサーバー 1(WAP01)の設定
    real_server 10.0.0.11 443 {
        weight 1           # 重み付け(均等)
        TCP_CHECK {
            connect_timeout 3  # 接続タイムアウト(秒)
            nb_get_retry 3     # リトライ回数
            delay_before_retry 3 # リトライ間隔(秒)
        }
    }

    # リアルサーバー 2(WAP02)の設定
    real_server 10.0.0.12 443 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

lvs02(Backupノード)もほぼ同じ設定ですが、router_id を一意にし、stateBACKUPpriority90 に変更します。

3-1. vrrp_instance(仮想ルーター)の設定

vrrp_instance ブロックは、LVSノード間でVIP(仮想IP)をどのように共有するかを定義します。Masterノードがダウンすると、VRRPパケットが途絶え、Backupノードが瞬時にインターフェースにVIP(上記例では 192.168.10.100)をアタッチし、通信を無停止で引き継ぎます。

3-2. virtual_server(LVSロードバランサー)の設定

virtual_server ブロックでIPVSの挙動を定義します。

  • lb_algo rr(ラウンドロビン):新しい接続を各WAPサーバーへ順番に均等に振り分けます。WAPのスペックが同等であれば rr で十分です。
  • lb_kind NAT:本構成のキモであるLVS-NAT方式を指定します。
  • TCP_CHECK:KeepalivedがバックエンドのWAPに対し、定期的にTCP 443ポートへの接続を試みます。ダウンを検知すると、IPVSのルーティングテーブルから即座に該当のWAPを除外します。

3-3. セッション維持(persistence_timeout)の重要性

M365認証のLVS設計において最も重要かつトラブルになりやすいのが、persistence_timeout 1800(セッションパーシステンス/維持)の設定です。
SAML認証は、クラウド(Entra ID)からWAPへリダイレクトされ、WAPが認証情報を受け取り、再びクラウドへリダイレクトするという「一連のHTTPトランザクション」を伴います。
もしこのトランザクションの途中で、LVSがラウンドロビンによって「別のWAPサーバー」へパケットを振り分けてしまうと、SAMLの認証コンテキストが途切れ、ユーザーの画面に「認証セッションが無効です」といったエラーが表示され、サインインループに陥ります。

persistence_timeout を設定することで、LVSは一度特定のWAPへ振り分けたクライアント(送信元IPアドレスベース)からの通信を、指定された時間(例:1800秒=30分間)は常に同じWAPサーバーへ固定的に振り分け続けるようになります。これにより、認証フローの整合性が保たれます。

リナックス先生

この persistence_timeout は、単なる静的Webサイトの負荷分散なら必要ないことが多いけど、SAML認証やステートフルなWebアプリケーションのフロントエンドにおいては「命綱」よ。認証の不具合調査でLinuxエンジニアが呼ばれたら、真っ先にこのセッションパーシステンスの設定が漏れていないか疑うべきね!

設定が完了したら、Keepalivedを起動(または再起動)します。

sudo systemctl restart keepalived
sudo systemctl status keepalived

4. Windows Server (WAP) 側のルーティング設定(LVS-NAT環境)

AlmaLinux 9側のLVS構築が終わっても、まだ通信は成立しません。LVS-NAT方式において、インフラエンジニアが絶対に忘れてはならない「戻りパケットのルーティング」というネットワークの原則があります。

4-1. WAPサーバーのデフォルトゲートウェイ変更

LVS-NAT方式では、LVSはパケットの宛先IPをWAPのIP(例: 10.0.0.11)にDNATして転送します。しかし、送信元IPアドレスは「インターネット上のクライアントのIP」のままです。

WAPがこのパケットを受け取って応答(SAMLトークンなど)を返す際、宛先は「インターネット上のクライアント」になります。もしWAPのデフォルトゲートウェイが「DMZの通常ルーター」を向いていると、戻りパケットはLVSを経由せずに別の経路からインターネットへ出ていこうとします。これを「非対称ルーティング(Asymmetric Routing)」と呼び、ルーターやクライアントのファイアウォールで不審なパケットとして破棄(Drop)されてしまいます。

これを防ぐため、WAPサーバーのデフォルトゲートウェイ(またはインターネット宛の静的ルート)を、LVSの内部側のIPアドレス(DIP:Director IP)に向けておく必要があります。

# --- WAPサーバー(Windows Server 2025)のPowerShellで実行 ---
# インターネット宛(0.0.0.0/0)のデフォルトゲートウェイをLVSの内部IP(例: 10.0.0.100)に変更する
Set-NetIPInterface -InterfaceAlias "Ethernet0" -DefaultGateway "10.0.0.100"

※LVSが冗長化されている場合は、LVSの内部ネットワーク側にも「内部VIP」を持たせ、WAPのゲートウェイをその内部VIPに向けるのがベストプラクティスです。

4-2. スプリットルーティングの罠と静的ルートの追加

WAPのデフォルトゲートウェイをLVSに向けた場合、WAPからインターネットへの通信はLVSを経由して出ていくことになります。しかし、WAPは内部ネットワークのADFSとも通信しなければなりません。
もしADFSが存在するセグメント(例: 192.168.20.0/24)へのルーティングが不足していると、ADFSへの通信までLVSへ向かってしまい、迷子になります。

WAPサーバー上で、内部ネットワーク(ADFSやADDS)への静的ルート(Static Route)を確実に定義しておきましょう。

# WAPから内部ネットワーク(ADFS等が存在するセグメント)への静的ルートを追加
# 例:内部ネットワークのルーターIPが 10.0.0.1 の場合
New-NetRoute -DestinationPrefix "192.168.20.0/24" -InterfaceAlias "Ethernet0" -NextHop "10.0.0.1"

5. 動作確認とプロのトラブルシューティング手法

LVSとWAPの設定が完了したら、実際に通信を流して動作確認を行います。

5-1. ipvsadmによるアクティブセッションと分散状況の確認

Linuxエンジニアにとって、LVSの状態確認は ipvsadm コマンドがすべてです。Masterノードで以下のコマンドを実行します。

# IPVSのルーティングテーブルとリアルサーバーの状態を確認
sudo ipvsadm -Ln

出力例の確認ポイント:
・仮想IP(VIP)の下に、バックエンドのWAP(10.0.0.11, 10.0.0.12)が表示されているか。
Weight が 1 になっており、ActiveConn(アクティブなコネクション)や InActConn(非アクティブなコネクション)の数値がカウントアップされているか。
もしリアルサーバーが表示されていない場合、Keepalivedのヘルスチェック(TCP_CHECK)が失敗しています。WAP側のファイアウォール(Windows Defender Firewall)でTCP 443が許可されているか確認してください。

さらに、接続元のIPアドレスごとにセッションがパーシステンス(維持)されているかを確認するには以下のコマンドを使用します。

# パーシステント接続の追跡情報を確認
sudo ipvsadm -Lnc

5-2. フェイルオーバーのテストとログ解析

HAクラスターを構築したら、必ず「障害テスト」を実施します。

  1. Masterノード(lvs01)のKeepalivedプロセスを意図的に停止します(sudo systemctl stop keepalived)。
  2. Backupノード(lvs02)で ip a コマンドを実行し、瞬時にVIP(192.168.10.100)がインターフェースに付与されたか確認します。
  3. この状態で、外部のブラウザからM365の認証(WAPへのアクセス)が途切れることなく継続できれば、フェイルオーバーは成功です。

KeepalivedのVRRPの挙動やヘルスチェックの失敗理由は、すべてSyslog(/var/log/messages または journalctl -u keepalived)に詳細に記録されます。「Keepalivedがなぜかリアルサーバーを切り離した」というトラブルに直面した際は、必ずこのログを追跡してください。

6. 第5回の総まとめと次回の予告

本記事では、M365認証の最前線を守るWAPの負荷分散として、AlmaLinux 9とIPVS(LVS)+Keepalivedを用いたエンタープライズアーキテクチャの構築手順を解説しました。

高額な商用ロードバランサーがなくても、Linuxカーネルに組み込まれたL4ルーティング技術を駆使し、非対称ルーティングを防ぐネットワーク設計(WAPのゲートウェイ設定)や、SAML認証特有のセッション維持(persistence_timeout)のチューニングを施すことで、秒間数万パケットを無停止でさばく強固なインフラが構築可能です。OSの垣根を越え、ネットワークのパケットレベルからシステムを俯瞰するスキルこそが、インフラエンジニアの真価です。

これで、ADDS、ADFS、WAP、そしてLVSという認証インフラの「器」はすべて完成しました。しかし、現状では単なるオンプレミスの認証基盤に過ぎません。
次回の【第6回】M365 (Entra ID) とADFSのフェデレーション信頼の確立では、いよいよ完成したADFSをクラウド(M365)の世界とつなぎます。「Microsoft Entra Connect」を用いたディレクトリの同期と、フェデレーション(信頼関係)の確立プロセスを解説し、ユーザーがM365へシームレスにログインできるSSO環境を完成させます。お楽しみに!

▼ 【LVSクラスターの検証環境を構築しよう】 ▼

AlmaLinux 9でLVSを動かす
「高コスパおすすめVPS」

VPSランキングを見る

OSの垣根を超えたフルスタックエンジニアへ
「ITエンジニア専門転職」

転職エージェントを見る

コメント