3.2. ダイレクトルーティングを使用するロードバランサー

ダイレクトルーティングを使用すると、実サーバーは LVS ルーターを介して送信パケットを渡さずに、直接パケットを処理して要求元ユーザーにルーティングできます。ダイレクトルーティングでは、実サーバーが LVS ルーターがあるネットワークセグメントに物理的に接続している必要があり、送信パケットを処理およびルーティングできる必要があります。
ネットワークレイアウト
ダイレクトルーティングのロードバランサー設定では、LVS ルーターが受信要求を受け取り、要求を処理する適切な実サーバーへルーティングする必要があります。その後、実サーバーは応答を直接クライアントへルーティングする必要があります。たとえば、クライアントがインターネット上にあり、LVS ルーター経由でパケットを実サーバーへ送信する場合、実サーバーはインターネット経由で直接クライアントに接続できる必要があります。これを実現するには、実サーバーのゲートウェイを設定し、パケットをインターネットに渡します。サーバープールの各サーバーは独自のゲートウェイを持ちます (各ゲートウェイはインターネットへの独自の接続を持ちます)。そのため、スループットやスケーラビリティーを最大限にします。しかし、一般的なロードバランサーの設定では実サーバーは 1 つのゲートウェイ (よって 1 つのネットワーク接続) を経由して通信できます。
ハードウェア
ダイレクトルーティングを使用するロードバランサーシステムのハードウェア要件は、他のロードバランサートポロジーと似ています。LVS ルーターは Red Hat Enterprise Linux を実行して受信要求を処理し、実サーバーの負荷分散を実行する必要がありますが、実サーバーが適切に機能するには Linux マシンである必要はありません。各 LVS ルーターには 1 つまたは 2 つの NIC が必要です (バックアップルーターがあるかによって異なります)。NIC を 2 つ使用すると設定が容易になり、受信要求は 1 つの NIC によって処理され、別の NIC によってパケットが実サーバーへルーティングされるため、トラフィックを区別できます。
実サーバーは LVS ルーターを迂回して送信パケットを直接クライアントに送信するため、インターネットへのゲートウェイが必要となります。パフォーマンスと可用性を最大化するには、クライアントが接続しているネットワーク (インターネットやイントラネットなど) に専用接続がある独自のゲートウェイに実サーバーを接続します。
ソフトウェア
ダイレクトルーティングでロードバランサーを使用するときに ARP の問題が発生する場合は、特に keepalived 以外の設定を行う必要があります。詳細は 「arptables を使用したダイレクトルーティング」 または 「iptables を使用したダイレクトルーティング」 を参照してください。

3.2.1. arptables を使用したダイレクトルーティング

arptables を使用してダイレクトルーティングを設定するには、実サーバーで仮想 IP アドレスが設定され、直接パケットをルーティングできる必要があります。VIP の ARP 要求は実サーバーによって完全に無視されます。VIP を含む送信される ARP パケットは、VIP ではなく実サーバーの IP が含まれるよう分割されます。
arptables メソッドを使用すると、アプリケーションを実サーバーが接続する個別の VIP またはポートにバインドすることができます。たとえば、arptables メソッドを使用すると Apache HTTP Server の複数のインスタンスを実行し、システム上の異なる VIP に明示的にバインドすることができます。
しかし、arptables メソッドを使うと、標準の Red Hat Enterprise Linux システム設定ツールを使用して起動時に VIP を開始する設定ができません。
それぞれの仮想 IP アドレスの ARP 要求を無視するように実サーバーを設定するには、以下の手順を実行します。
  1. 実サーバー上で仮想 IP アドレスの ARP テーブルのエントリーを作成します (real_ip とは実サーバーとの通信にディレクターが使用する IP のこと。多くの場合、eth0 にバインドされた IP)。
    arptables -A IN -d <virtual_ip> -j DROP
    arptables -A OUT -s <virtual_ip> -j mangle --mangle-ip-s <real_ip>
    これにより、仮想 IP アドレス向けのすべての ARP 要求を実サーバーが無視するようになります。また、他の方法では仮想 IP を含むことになる送信 ARP 反応を変更させて、それらがサーバーの実 IP を含むようになります。VIP の ARP 要求に反応する唯一のノードは、現在アクティブな LVS ノードです。
  2. これが実サーバー上で完了したら、実サーバー上で以下のコマンドを入力して ARP テーブルのエントリーを保存します。
    arptables-save > /etc/sysconfig/arptables
    systemctl enable arptables.service
    systemctl enable コマンドは、ネットワーク開始前にシステムが起動時に arptables 設定をリロードするようにします。
  3. ip addr コマンドを使用してすべての実サーバーに仮想 IP アドレスを設定し、IP エイリアスを作成します。例を以下に示します。
    # ip addr add 192.168.76.24 dev eth0
  4. ダイレクトルーティングを Keepalived に設定します。これには、lb_kind DRkeepalived.conf ファイルに追加します。詳細は 4章Keepalived を用いたロードバランサーの初期設定 を参照してください。

3.2.2. firewalld を使用したダイレクトルーティング

firewalld を使用してファイアウォールルールを作成すると、ダイレクトルーティングを使用した ARP の問題発生を防ぐことができます。ダイレクトルーティングを設定するには、VIP アドレスがシステム上に存在しなくても実サーバーが VIP アドレスに送信されたパケットに対応するよう、透過プロキシーを作成するルールを追加します。
ダイレクトルーティングメソッドは arptables メソッドよりも設定が簡単です。仮想 IP アドレスはアクティブ LVS ディレクター上にのみ存在するため、このメソッドでは LVS ARP の問題も完全に回避できます。
しかし、パケットが返されるたびに転送や IP マスカレードによるオーバーヘッドが発生するため、ダイレクトルーティングは arptables と比較してパフォーマンスに大きく影響します。
また、ダイレクトルーティングメソッドを使用するとポートを再利用できません。たとえば、2 つの別々の Apache HTTP Server サービスは両方とも仮想 IP アドレスではなく INADDR_ANY にバインドする必要があるため、ポート 80 にバインドされた 2 つの別々の Apache HTTP Server サービスを実行することはできません。
firewalld を使用して IPv4 のダイレクトルーティングを設定するには、実サーバーごとに以下の手順を実行します。
  1. LVS からパケットを受信するネットワークインターフェースのゾーンに対して IP マスカレードを有効にします。たとえば外部ゾーンの場合、root で以下を実行します。
    # firewall-cmd --zone=external --add-masquerade --permanent
    zone を省略すると、デフォルトのゾーンが使用されます。 --permanent オプションを指定すると設定が永続化されますが、次回のシステム起動後にコマンドが反映されます。設定を即座に反映する必要がある場合は、--permanent オプションを省略してコマンドを繰り返し実行します。
  2. 実サーバーが対応する目的の VIP、ポート、およびプロトコル (TCP または UDP) の組み合わせすべてに対してコマンドを以下の形式で実行します。
    firewall-cmd --zone=zone --add-forward-port=port=port_number:proto=protocol:toport=port_number:toaddr=virtual_IP_address
    たとえば、ポート 80 の TCP トラフィックを 192.168.10.10 でポート 3753 にリダイレクトするよう設定するには、以下を実行します。
    # firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=3753:toaddr=192.168.10.10 --permanent
    --permanent オプションを指定すると設定が永続化されますが、次回のシステム起動後にコマンドが反映されます。設定を即座に反映する必要がある場合は、--permanent オプションを省略してコマンドを繰り返し実行します。
    このコマンドで、実サーバーは与えられた VIP とポートが宛先となっているパケットを処理します。
  3. firewalld が稼働していることを確認する必要がある場合は、以下を実行します。
    # systemctl start firewalld
    システム起動時に firewalld が有効な状態で開始するようにするには、以下を実行します。
    # systemctl enable firewalld

3.2.3. iptables を使用したダイレクトルーティング

iptables ファイアウォールルールを作成することで、 ダイレクトルーティングメソッドを使用した場合の ARP 問題を回避することもできます。iptables を使用してダイレクトルーティングを設定するには、VIP アドレスがシステム上に存在しなくても VIP アドレスに送信されたパケットを実サーバーが扱うように透過プロキシを作成するルールを追加する必要があります。
iptables メソッドは arptables メソッドよりも設定が簡単です。仮想 IP アドレスがアクティブ LVS ディレクター上にのみ存在するため、このメソッドでは LVS ARP 問題も完全に回避できます。
しかし、パケットが転送またはマスカレードされるたびにオーバーヘッドが発生するため、iptables メソッドはarptables と比較するしてパフォーマンスに大きく影響します。
また、iptables メソッドを使用してポートを再利用することはできません。例えば、2 つの別々の Apache HTTP Server サービスは両方とも仮想 IP アドレスではなく INADDR_ANY にバインドする必要があるため、ポート 80 にバインドされた 2 つの別々の Apache HTTP Server サービスを実行することはできません。
iptables メソッドを使用してダイレクトルーティングを設定するには、以下の手順を実行します。
  1. 実サーバー上で、実サーバーに対応する目的の VIP、ポート、およびプロトコル (TCP または UDP) の組み合わせすべてに対して、以下のコマンドを実行します。
    iptables -t nat -A PREROUTING -p <tcp|udp> -d <vip> --dport <port> -j REDIRECT
    このコマンドで、実サーバーは与えられた VIP とポートが宛先となっているパケットを処理します。
  2. 実サーバー上で設定を保存します。
    # iptables-save > /etc/sysconfig/iptables
    # systemctl enable iptables.service
    systemctl enable コマンドは、ネットワーク開始前にシステムが起動時に iptables 設定をリロードするようにします。

3.2.4. sysctl を用いたダイレクトルーティング

sysctl インターフェースを使用して、ダイレクトルーティングの使用時に ARP の制限に対処することもできます。管理者は 2 つの systcl 設定を行い、実サーバーが ARP 要求で VIP をアナウンスしないようにし、VIP アドレスの ARP 要求へ応答しないようにします。この動作を有効にするには、以下のコマンドを実行します。
echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
この代わりに、以下の行を /etc/sysctl.d/arp.conf に設定することもできます。
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.eth0.arp_announce = 2