第8章 ロード・バランシングの構成

この章では、ネットワーク・サービスへの継続的なアクセスを維持しながら、これらのアクセスを分散するためにKeepalivedおよびHAProxyテクノロジを構成する方法について説明します。

8.1 HAProxyについて

HAProxyは、アプリケーション・レイヤー(レイヤー7)のロード・バランシングおよび高可用性ソリューションであり、HTTPベースおよびTCPベースのインターネット・サービスにリバース・プロキシを実装するために使用できます。

haproxyデーモンの構成ファイルは、/etc/haproxy/haproxy.cfgです。このファイルが、ロード・バランシングまたは高可用性のためにHAProxyを構成する各サーバーに存在している必要があります。

詳細は、http://www.haproxy.org/#docs/usr/share/doc/haproxy-versionドキュメントおよびhaproxy(1)マニュアル・ページを参照してください。

8.2 HAProxyのインストールと構成

HAProxyをインストールするには、次のようにします。

  1. 各フロントエンド・サーバーにhaproxyパッケージをインストールします。

    # yum install haproxy
  2. /etc/haproxy/haproxy.cfgを編集して、各サーバーでHAProxyを構成します。8.2.1項「HAProxy構成ファイルについて」を参照してください。

  3. ローカルでないIPアドレスへのIP転送およびバインディングを有効にします。

    # echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
    # echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
    # sysctl -p
    net.ipv4.ip_forward = 1
    net.ipv4.ip_nonlocal_bind = 1
  4. HAProxyにより処理するサービスまたはポートへのアクセスを有効にします。

    たとえば、HTTPへのアクセスを有効にし、リブート後もこのルールを保持する場合は、次のコマンドを入力します。

    # firewall-cmd --zone=zone --add-service=http
    success
    # firewall-cmd --permanent --zone=zone --add-service=http
    success

    受信TCPリクエストをポート8080で許可するには:

    # firewall-cmd --zone=zone --add-port=8080/tcp
    success
    # firewall-cmd --permanent --zone=zone --add-port=8080/tcp
    success
  5. 各サーバーでhaproxyサービスを有効にし、起動します。

    # systemctl enable haproxy
    ln -s '/usr/lib/systemd/system/haproxy.service' \
      '/etc/systemd/system/multi-user.target.wants/haproxy.service'
    # systemctl start haproxy

    HAProxy構成を変更した場合は、haproxyサービスを再ロードします。

    # systemctl reload haproxy

8.2.1 HAProxy構成ファイルについて

/etc/haproxy/haproxy.cfg構成ファイルは、次の各セクションに分かれています。

global

syslog機能などのグローバル設定と、ロギングに使用するレベル、許可される最大同時接続数、およびデーモン・モードで開始するプロセス数を定義します。

defaults

後続のセクションのデフォルト設定を定義します。

listen

完全プロキシを定義し、frontendおよびbackendコンポーネントを暗黙的に挿入します。

frontend

クライアント接続を受け入れるポートを定義します。

backend

プロキシがクライアント接続を転送する先のサーバーを定義します。

HAProxyの構成方法の例は、次の項を参照してください。

8.3 HAProxyを使用した単純なロード・バランシングの構成

次の例では、HAProxyを使用して、受信リクエストを2つのバックエンドWebサーバー間で分散し、さらにバックエンド・サーバーでサービス停止を処理する機能も持つフロントエンド・サーバーを実装します。

図8.1に、外部公開ネットワーク(192.168.1.0/24)および内部ネットワーク(10.0.0.0/24)に接続されたHAProxyサーバー(10.0.0.10)を示します。内部ネットワークでは、websvr1 (192.168.1.71)およびwebsvr2 (192.168.1.72)という2つのWebサーバーにアクセス可能です。IPアドレス10.0.0.10はプライベート・アドレス範囲10.0.0.0/24内にあり、インターネット上でルーティングできません。アップストリーム・ネットワーク・アドレス変換(NAT)ゲートウェイまたはプロキシ・サーバーが、インターネットとの間のアクセスを提供します。

図8.1 ロード・バランシングのためのHAProxy構成の例
この図は、外部公開ネットワーク(192.168.1.0/24)および内部ネットワーク(10.0.0.0/24)に接続されたHAProxyサーバー(10.0.0.10)を示しています。内部ネットワークでは、2つのWebサーバーwebsvr1 (192.168.1.71)およびwebsvr2 (192.168.1.72)にアクセス可能です。IPアドレス10.0.0.10はプライベート・アドレス範囲10.0.0.0/24内にあり、インターネット上でルーティングできません。アップストリームNATゲートウェイまたはプロキシ・サーバーが、インターネットとの間のアクセスを提供します。


サーバーの/etc/haproxy/haproxy.cfgで次の構成を使用できます。

global
    daemon
    log 127.0.0.1 local0 debug
    maxconn 50000
    nbproc 1

defaults
    mode http
    timeout connect 5s
    timeout client 25s
    timeout server 25s
    timeout queue 10s

# Handle Incoming HTTP Connection Requests
listen  http-incoming
    mode http
    bind 10.0.0.10:80
# Use each server in turn, according to its weight value
    balance roundrobin
# Verify that service is available
    option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
# Insert X-Forwarded-For header
    option forwardfor
# Define the back-end servers, which can handle up to 512 concurrent connections each
    server websvr1 192.168.1.71:80 weight 1 maxconn 512 check
    server websvr2 192.168.1.72:80 weight 1 maxconn 512 check

この構成では、HTTPトラフィックが2つのバックエンドWebサーバーwebsvr1およびwebsvr2の間で分散され、これらのサーバーのファイアウォールは、ポート80で受信TCPリクエストを受け入れるように構成されています。

Webサーバーに単純な/var/www/html/index.htmlファイルを実装し、curlを使用して接続をテストした後は、次の出力に、HAProxyがどのようにトラフィックをこれらのサーバー間で分散し、どのようにwebsvr1でのhttpdサービス停止を処理するかが示されます。

$ while true; do curl http://10.0.0.10; sleep 1; done
This is HTTP server websvr1 (192.168.1.71).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr1 (192.168.1.71).
This is HTTP server websvr2 (192.168.1.72).
...
This is HTTP server websvr2 (192.168.1.72).
<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
...
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr1 (192.168.1.71).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr1 (192.168.1.71).
...
^C
$

この例では、websvr1httpdサービスが再起動され、websvr2に加えてこのサーバーも再び使用し始めたことが、HAProxyによって検出されました。

HAProxyのロード・バランシング機能をKeepalivedまたはOracle Clusterwareの高可用性機能と組み合せることにより、プライマリ・ロード・バランサの障害発生時にもサービスを継続できるようにバックアップ・ロード・バランサを構成できます。8.10項「Keepalivedを使用したHAProxyの高可用性の実現」および8.12項「Oracle Clusterwareを使用したHAProxyの高可用性の実現」を参照してください。

HAProxyをインストールおよび構成する方法の詳細は、8.2項「HAProxyのインストールと構成」を参照してください。

8.3.1 セッションの永続性のためのHAProxyの構成

多くのWebベース・アプリケーションでは、同じWebサーバーが永続的にユーザー・セッションを提供する必要があります。

Webセッションを同じサーバーに永続的に接続する場合は、hdrrdp-cookiesourceuriurl_paramなどのbalanceアルゴリズムを使用できます。

実装でleastconnroundrobinまたはstatic-rrアルゴリズムを使用する必要がある場合は、サーバー依存Cookieを使用してセッションの永続性を実装できます。

1つのWebサーバーですべてのページのセッションの永続性を有効にするには、次の例のように、cookieディレクティブを使用して、挿入するCookieの名前を定義し、cookieオプションとサーバー名をserverの行に追加します。

    cookie WEBSVR insert
    server websvr1 192.168.1.71:80 weight 1 maxconn 512 cookie 1 check
    server websvr2 192.168.1.72:80 weight 1 maxconn 512 cookie 2 check

HAProxyは、Webサーバーを識別する追加のSet-Cookie:ヘッダーをクライアントへの応答に含めます(例: Set-Cookie: WEBSVR=N; path=page_path)。以降にクライアントがリクエストでWEBSVR Cookieを指定すると、HAProxyは、server cookieの値がWEBSVRの値と一致するWebサーバーにリクエストを転送します。

次の例に、挿入されたCookieがセッションの永続性を確保する方法を示します。

$ while true; do curl http://10.0.0.10; sleep 1; done
This is HTTP server websvr1 (192.168.1.71).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr1 (192.168.1.71).
^C
$ curl http://10.0.0.10 -D /dev/stdout
HTTP/1.1 200 OK
Date: ...
Server: Apache/2.4.6 ()
Last-Modified: ...
ETag: "26-5125afd089491"
Accept-Ranges: bytes
Content-Length: 38
Content-Type: text/html; charset=UTF-8
Set-Cookie: WEBSVR=2; path=/

This is HTTP server svr2 (192.168.1.72).
$ while true; do curl http://10.0.0.10 --cookie "WEBSVR=2;"; sleep 1; done
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
^C

Webサーバーで選択的に永続性を有効にするには、次の例のように、cookieディレクティブを使用して、指定したCookie(通常はセッションID Cookieまたはその他の既存のCookie)の前にserver cookie値および~デリミタが付くことをHAProxyが必要とすることを指定します。

    cookie SESSIONID prefix
    server websvr1 192.168.1.71:80 weight 1 maxconn 512 cookie 1 check
    server websvr2 192.168.1.72:80 weight 1 maxconn 512 cookie 2 check

SESSIONIDの値の前にserver cookie値を付けると(例: Set-Cookie: SESSIONID=N~Session_ID;)、HAProxyは、SESSIONID Cookieから接頭辞とデリミタを取り除いてから、server cookie値がその接頭辞と一致するWebサーバーにリクエストを転送します。

次の例に、接頭辞付きのCookieの使用によってセッションの永続性を有効にする方法を示します。

$ while true; do curl http://10.0.0.10 --cookie "SESSIONID=1~1234;"; sleep 1; done
This is HTTP server websvr1 (192.168.1.71).
This is HTTP server websvr1 (192.168.1.71).
This is HTTP server websvr1 (192.168.1.71).
^C

実際のWebアプリケーションは通常、サーバー側にセッションIDを設定し、この場合、最初のHAProxyレスポンスでSet-Cookie:ヘッダーに接頭辞付きのCookieが含められます。

8.4 Keepalivedについて

Keepalivedは、IP Virtual Server (IPVS)カーネル・モジュールを使用してトランスポート・レイヤー(レイヤー4)のロード・バランシングを提供し、ネットワークベースのサービスに対するリクエストをサーバー・クラスタの個々のメンバーにリダイレクトします。IPVSは、各サーバーのステータスをモニターし、Virtual Router Redundancy Protocol (VRRP)を使用して高可用性を実装します。

keepalivedデーモンの構成ファイルは、/etc/keepalived/keepalived.confです。このファイルが、ロード・バランシングまたは高可用性のためにKeepalivedを構成する各サーバーに存在している必要があります。

詳細は、https://www.keepalived.org/documentation.html/usr/share/doc/keepalive-versionドキュメント、keepalived(8)およびkeepalived.conf(5)マニュアル・ページを参照してください。

8.5 Keepalivedのインストールと構成

Keepalivedをインストールするには、次のようにします。

  1. 各サーバーにkeepalivedパッケージをインストールします。

    # yum install keepalived
  2. /etc/keepalived/keepalived.confを編集して、各サーバーでKeepalivedを構成します。8.5.1項「Keepalived構成ファイルについて」を参照してください。

  3. 次のように、IP転送を有効にします。

    # echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
    # sysctl -p
    net.ipv4.ip_forward = 1
  4. 次の例のように、各ネットワーク・インタフェースでKeepalivedが制御するマルチキャストIPアドレス224.0.0.18およびVRRPプロトコル(112)を使用してVRRP通信を行うことを許可するファイアウォール・ルールを追加します。

    # firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 \
      --in-interface enp0s8 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
    success
    # firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 \
      --out-interface enp0s8 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
    success
    # firewall-cmd --reload
    success
  5. 各サーバーでkeepalivedサービスを有効にし、起動します。

    # systemctl enable keepalived
    ln -s '/usr/lib/systemd/system/keepalived.service' \
      '/etc/systemd/system/multi-user.target.wants/keepalived.service'
    # systemctl start keepalived

    Keepalived構成を変更した場合は、keepalivedサービスを再ロードします。

    # systemctl reload keepalived

8.5.1 Keepalived構成ファイルについて

/etc/keepalived/keepalived.conf構成ファイルは、次の各セクションに分かれています。

global_defs

通知メッセージを送信するための電子メール・アドレス、SMTPサーバーのIPアドレス、SMTP接続のタイムアウト値(秒)、ホスト・マシンを識別する文字列、VRRP IPv4およびIPv6マルチキャスト・アドレス、SNMPトラップを有効にするかどうかなど、グローバル設定を定義します。

static_ipaddressstatic_routes

VRRPが変更できない静的IPアドレスおよび静的ルートを定義します。サーバーでアドレスおよびルートがすでに定義されており、これらのサーバーにすでにネットワーク接続があれば、これらのセクションは必要ありません。

vrrp_sync_group

一緒にフェイルオーバーするVRRPインスタンスのVRRP同期グループを定義します。

vrrp_instance

状態遷移中に他のグループ・メンバーを随伴するVRRP同期グループの内部または外部のネットワーク・インタフェースのメンバーに対して移動可能な仮想IPアドレスを定義します。各VRRPインスタンスには、プライマリ・サーバーとバックアップ・サーバー上のどのインタフェースを特定の仮想IPアドレスに割り当てることができるかを指定する、一意のvirtual_router_id値が必要です。また、BACKUPMASTERおよびFAULTへの状態遷移時に実行されるスクリプトと、状態遷移に対してSMTPアラートをトリガーするかどうかを指定することもできます。

vrrp_script

Keepalivedが一定の間隔で実行できる追跡スクリプトを定義して、vrrp_instanceまたはvrrp_sync_groupセクションから監視アクションを実行します。

virtual_server_group

実サーバーを複数の仮想サーバー・グループのメンバーにできるように、仮想サーバー・グループを定義します。

virtual_server

複数の実サーバーで構成される、ロード・バランシングのための仮想サーバーを定義します。

Keepalivedの構成方法の例は、次の項を参照してください。

8.6 Keepalivedを使用した単純な仮想IPアドレス・フェイルオーバーの構成

一般的なKeepalived高可用性構成は、1つのプライマリ・サーバーと1つ以上のバックアップ・サーバーからなります。VRRPインスタンスとして定義された1つ以上の仮想IPアドレスがプライマリ・サーバーのネットワーク・インタフェースに割り当てられます。それにより、それがネットワーク・クライアントにサービスを提供できるようになります。バックアップ・サーバーは、プライマリ・サーバーが一定の間隔で送信するマルチキャストVRRP通知パケットをリスニングします。デフォルトの通知間隔は1秒です。連続する3つのVRRP通知をバックアップ・ノードが受信できなかった場合、最も高い優先度が割り当てられたバックアップ・サーバーが引き継いでプライマリ・サーバーとなり、仮想IPアドレスをそれ自体のネットワーク・インタフェースに割り当てます。複数のバックアップ・サーバーの優先度が同じである場合は、IPアドレス値が最も大きいバックアップ・サーバーがプライマリ・サーバーとなります。

次の例では、Keepalivedを使用して2つのサーバー上に単純なフェイルオーバー構成を実装します。1つのサーバーがプライマリ・サーバーとして機能し、その他のサーバーがバックアップとして機能します。プライマリ・サーバーの優先度はバックアップ・サーバーよりも高くなります。

次の図は、どのように仮想IPアドレス10.0.0.100が最初にプライマリ・サーバー(10.0.0.71)に割り当てられるかを示しています。プライマリ・サーバーに障害が発生すると、バックアップ・サーバー(10.0.0.72)が新しいプライマリ・サーバーとなり、仮想IPアドレス10.0.0.100がそれに割り当てられます。

図8.2 仮想IPアドレス・フェイルオーバーのためのKeepalived構成の例
この図は、どのように仮想IPアドレス10.0.0.100が最初にプライマリ・サーバー(10.0.0.71)に割り当てられるかを示しています。プライマリ・サーバーに障害が発生すると、バックアップ・サーバー(10.0.0.72)が新しいプライマリ・サーバーとなり、仮想IPアドレス10.0.0.100がそれに割り当てられます。

プライマリ(マスター)・サーバー上の/etc/keepalived/keepalived.confで、次の構成を使用できます。

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from svr1@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_instance VRRP1 {
    state MASTER
#   Specify the network interface to which the virtual address is assigned
    interface enp0s8
#   The virtual router ID must be unique to each VRRP instance that you define
    virtual_router_id 41
#   Set the value of priority higher on the primary server than on a backup server
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1066
    }
    virtual_ipaddress {
        10.0.0.100/24
    }
}

バックアップ・サーバーの構成は、notification_email_fromstateおよびpriorityの値(およびシステム・ハードウェア構成が異なる場合はinterfaceの値)を除けば同じです。

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from svr2@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_instance VRRP1 {
    state BACKUP
#   Specify the network interface to which the virtual address is assigned
    interface enp0s8
    virtual_router_id 41
#   Set the value of priority lower on the backup server than on the primary server
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1066
    }
    virtual_ipaddress {
        10.0.0.100/24
    }
}

プライマリ・サーバー(svr1)に障害が発生した場合、keepalivedは仮想IPアドレス10.0.0.100/24をバックアップ・サーバー(svr2)のenp0s8インタフェースに割り当て、これがプライマリ・サーバーとなります。

サーバーがプライマリ・サーバーとして機能しているかどうかを判別するには、次の例のように、ipコマンドを使用して、仮想アドレスがアクティブかどうかを調べます。

# ip addr list enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:cb:a6:8d brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.72/24 brd 10.0.0.255 scope global enp0s8
    inet 10.0.0.100/24 scope global enp0s8
    inet6 fe80::a00:27ff:fecb:a68d/64 scope link 
       valid_lft forever preferred_lft forever

または、次の例のように、/var/log/messages内で状態間の遷移を示すKeepalivedメッセージを検索します。

...51:55 ... VRRP_Instance(VRRP1) Entering BACKUP STATE
...
...53:08 ... VRRP_Instance(VRRP1) Transition to MASTER STATE
...53:09 ... VRRP_Instance(VRRP1) Entering MASTER STATE
...53:09 ... VRRP_Instance(VRRP1) setting protocol VIPs.
...53:09 ... VRRP_Instance(VRRP1) Sending gratuitous ARPs on enp0s8 for 10.0.0.100
注意

プライマリ(マスター)・サーバーとしてアクティブになるサーバーは、常に1つのみです。複数のサーバーがプライマリ・サーバーとして構成されている場合、サーバー間のVRRP通信に問題がある可能性があります。各サーバーでインタフェースごとにネットワーク設定を確認し、ファイアウォールでマルチキャストIPアドレス224.0.0.18の受信VRRPパケットと送信VRRPパケットが両方とも許可されることを確認してください。

Keepalivedをインストールおよび構成する方法の詳細は、8.5項「Keepalivedのインストールと構成」を参照してください。

8.7 NATモードでのKeepalivedを使用したロード・バランシングの構成

次の例では、NATモードでKeepalivedを使用して、2つのサーバー上に単純なフェイルオーバーおよびロード・バランシングの構成を実装します。1つのサーバーがプライマリ・サーバーとして機能し、その他のサーバーがバックアップとして機能します。プライマリ・サーバーの優先度はバックアップ・サーバーよりも高くなります。各サーバーには2つのネットワーク・インタフェースがあり、一方のインタフェースは外部ネットワーク(192.168.1.0/24)に面した側に接続され、もう一方のインタフェースは、2つのWebサーバーにアクセス可能な内部ネットワーク(10.0.0.0/24)に接続されています。

次の図は、Keepalivedプライマリ・サーバーのネットワーク・アドレスが192.168.1.10192.168.1.1 (仮想)、10.0.0.10および10.0.0.100 (仮想)であることを示しています。Keepalivedバックアップ・サーバーのネットワーク・アドレスは192.168.1.11および10.0.0.11です。Webサーバーwebsvr1およびwebsvr2のネットワーク・アドレスは、それぞれ10.0.0.71および10.0.0.72です。

図8.3 NATモードでのロード・バランシングのためのKeepalived構成の例
この図は、Keepalivedプライマリ・サーバーのネットワーク・アドレスが192.168.1.10、192.168.1.1 (仮想)、10.0.0.10および10.0.0.100 (仮想)であることを示しています。Keepalivedバックアップ・サーバーのネットワーク・アドレスは192.168.1.11および10.0.0.11です。Webサーバーwebsvr1およびwebsvr2のネットワーク・アドレスは、それぞれ10.0.0.71および10.0.0.72です。

プライマリ・サーバー上の/etc/keepalived/keepalived.confで、次の構成を使用できます。

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from svr1@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_sync_group VRRP1 {
#   Group the external and internal VRRP instances so they fail over together
    group {
        external
        internal
        }
}

vrrp_instance external {
    state MASTER
    interface enp0s8
    virtual_router_id 91
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
#   Define the virtual IP address for the external network interface
    virtual_ipaddress {
        192.168.1.1/24
    }
}

vrrp_instance internal {
    state MASTER
    interface enp0s9
    virtual_router_id 92
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
#   Define the virtual IP address for the internal network interface
    virtual_ipaddress {
        10.0.0.100/24
    }
}

# Define a virtual HTTP server on the virtual IP address 192.168.1.1
virtual_server 192.168.1.1 80 {
    delay_loop 10
    protocol TCP
#   Use round-robin scheduling in this example
    lb_algo rr
#   Use NAT to hide the back-end servers
    lb_kind NAT
#   Persistence of client sessions times out after 2 hours
    persistence_timeout 7200

    real_server 10.0.0.71 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }

    real_server 10.0.0.72 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }
}

前の構成は、第8.6項「Keepalivedを使用した単純な仮想IPアドレス・フェイルオーバーの構成」に示した構成に似ており、それに、フェイルオーバー時にネットワーク・インタフェースがまとめて割り当てられるようにvrrp_sync_groupセクションの定義が追加され、Keepalivedがロード・バランシング用に使用する実バックエンド・サーバーを定義するvirtual_serverセクションが追加されています。lb_kindの値はNATモードに設定されており、これは、Keepalivedサーバーがバックエンド・サーバーに代わってクライアントのインバウンド・ネットワーク・トラフィックとアウトバウンド・ネットワーク・トラフィックの両方を処理するということです。

バックアップ・サーバーの構成は、notification_email_fromstateおよびpriorityの値(およびシステム・ハードウェア構成が異なる場合はinterfaceの値)を除けば同じです。

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from svr2@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_sync_group VRRP1 {
#   Group the external and internal VRRP instances so they fail over together
    group {
        external
        internal
        }
}

vrrp_instance external {
    state BACKUP
    interface enp0s8
    virtual_router_id 91
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
#   Define the virtual IP address for the external network interface
    virtual_ipaddress {
        192.168.1.1/24
    }
}

vrrp_instance internal {
    state BACKUP
    interface enp0s9
    virtual_router_id 92
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
#   Define the virtual IP address for the internal network interface
    virtual_ipaddress {
        10.0.0.100/24
    }
}

# Define a virtual HTTP server on the virtual IP address 192.168.1.1
virtual_server 192.168.1.1 80 {
    delay_loop 10
    protocol TCP
#   Use round-robin scheduling in this example
    lb_algo rr
#   Use NAT to hide the back-end servers
    lb_kind NAT
#   Persistence of client sessions times out after 2 hours
    persistence_timeout 7200

    real_server 10.0.0.71 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }

    real_server 10.0.0.72 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }
}

さらに2つの構成変更が必要です。

Keepalivedをインストールおよび構成する方法の詳細は、8.5項「Keepalivedのインストールと構成」を参照してください。

8.7.1 Keepalived NATモード・ロード・バランシングのためのファイアウォール・ルールの構成

内部ネットワーク上のサーバーでロード・バランシングにNATモードを使用するようにKeepalivedを構成した場合、Keepalivedサーバーはすべてのインバウンド・ネットワーク・トラフィックとアウトバウンド・ネットワーク・トラフィックを処理し、送信パケット内の実バックエンド・サーバーのソースIPアドレスを外部ネットワーク・インタフェースの仮想IPアドレスでリライトすることによりバックエンド・サーバーの存在を隠します。

ロード・バランシングにNATモードを使用するようにKeepalivedサーバーを構成するには:

  1. ファイアウォールを構成して、外部ネットワーク側のインタフェースが、内部ネットワーク側のインタフェースとは別のゾーンになるようにします。

    次の例では、どのようにインタフェースenp0s9internalゾーンに移動し、インタフェースenp0s8publicゾーンに残すかを示しています。

    # firewall-cmd --get-active-zones
    public
      interfaces: enp0s8 enp0s9
    # firewall-cmd --zone=public --remove-interface=enp0s9
    success
    # firewall-cmd --zone=internal --add-interface=enp0s9
    success
    # firewall-cmd --permanent --zone=public --remove-interface=enp0s9
    success
    # firewall-cmd --permanent --zone=internal --add-interface=enp0s9
    success
    # firewall-cmd --get-active-zones
    internal
      interfaces: enp0s9
    public
      interfaces: enp0s8
  2. 次の例のように、外部ネットワーク・インタフェースでNATモード(マスカレード)を構成します。

    # firewall-cmd --zone=public --add-masquerade
    success
    # firewall-cmd --permanent --zone=public --add-masquerade
    success
    # firewall-cmd --zone=public --query-masquerade
    yes
    # firewall-cmd --zone=internal --query-masquerade
    no
  3. 次の例のように、外部ネットワーク・インタフェースと内部ネットワーク・インタフェースの間の転送ルールを構成します(ファイアウォールに対してまだ有効にしていない場合)。

    # firewall-cmd --direct --permanent --add-rule ipv4 filter FORWARD 0 \
      -i enp0s8 -o enp0s9 -m state --state RELATED,ESTABLISHED -j ACCEPT
    success
    # firewall-cmd --direct --permanent --add-rule ipv4 filter FORWARD 0 \
      -i enp0s9 -o enp0s8 -j ACCEPT
    success
    # firewall-cmd --direct --permanent --add-rule ipv4 filter FORWARD 0 \
      -j REJECT --reject-with icmp-host-prohibited
    success
    # firewall-cmd --reload
  4. Keepalivedにより処理するサービスまたはポートへのアクセスを有効にします。

    たとえば、HTTPへのアクセスを有効にし、リブート後もこのルールを保持する場合は、次のコマンドを入力します。

    # firewall-cmd --zone=public --add-service=http
    success
    # firewall-cmd --permanent --zone=public --add-service=http
    success

8.7.2 Keepalived NATモード・ロード・バランシングのためのバックエンド・サーバー・ルーティングの構成

Keepalivedロード・バランサで使用する各バックエンド実サーバーで、ルーティング表に、ロード・バランサの内部ネットワーク・インタフェースの仮想IPアドレスのデフォルト・ルートが含まれていることを確認してください。

たとえば、仮想IPアドレスが10.0.0.100である場合、ipコマンドを使用してルーティング表を調べ、デフォルト・ルートを設定できます。

# ip route show
10.0.0.0/24 dev enp0s8  proto kernel  scope link  src 10.0.0.71 
# ip route add default via 10.0.0.100 dev enp0s8
# ip route show
default via 10.0.0.100 dev enp0s8 
10.0.0.0/24 dev enp0s8  proto kernel  scope link  src 10.0.0.71 

enp0s8のデフォルト・ルートを再起動後も維持するには、ファイル/etc/sysconfig/network-scripts/route-enp0s8を作成します。

# echo "default via 10.0.0.100 dev enp0s8" > /etc/sysconfig/network-scripts/route-enp0s8

8.8 DRモードでのKeepalivedを使用したロード・バランシングの構成

次の例では、直接ルーティング(DR)モードでKeepalivedを使用して、2つのサーバー上に単純なフェイルオーバーおよびロード・バランシングの構成を実装します。1つのサーバーがプライマリ・サーバーとして機能し、その他のサーバーがバックアップとして機能します。プライマリ・サーバーの優先度はバックアップ・サーバーよりも高くなります。各Keepalivedサーバーは単一のネットワーク・インタフェースを持ち、各サーバーは、2つのWebサーバーにアクセス可能な同じネットワーク・セグメント(10.0.0.0/24)に接続されています。

図8.4に、Keepalivedプライマリ・サーバーのネットワーク・アドレスが10.0.0.11および10.0.0.1 (仮想)であることを示します。Keepalivedバックアップ・サーバーのネットワーク・アドレスは10.0.0.12です。Webサーバーwebsvr1およびwebsvr2のネットワーク・アドレスは、それぞれ10.0.0.71および10.0.0.72です。さらに、どちらのWebサーバーも仮想IPアドレス10.0.0.1で構成されていて、その宛先アドレスを持つパケットを受け入れます。着信リクエストはプライマリ・サーバーに受け取られ、Webサーバーにリダイレクトされて、Webサーバーが直接応答します。

図8.4 DRモードでのロード・バランシングのためのKeepalived構成の例
この図は、Keepalivedプライマリ・サーバーのネットワーク・アドレスが10.0.0.11および10.0.0.1であることを示しています。Keepalivedバックアップ・サーバーのネットワーク・アドレスは10.0.0.12です。Webサーバーwebsvr1およびwebsvr2のネットワーク・アドレスは、それぞれ10.0.0.71および10.0.0.72です。さらに、どちらのWebサーバーも仮想IPアドレス10.0.0.1で構成されていて、その宛先アドレスを持つパケットを受け入れます。着信リクエストはプライマリ・サーバーに受け取られ、Webサーバーにリダイレクトされて、Webサーバーが直接応答します。


プライマリ・サーバー上の/etc/keepalived/keepalived.confで、次の構成を使用できます。

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from svr1@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_instance external {
    state MASTER
    interface enp0s8
    virtual_router_id 91
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
    virtual_ipaddress {
        10.0.0.1/24
    }
}

virtual_server 10.0.0.1 80 {
    delay_loop 10
    protocol TCP
    lb_algo rr
#   Use direct routing
    lb_kind DR
    persistence_timeout 7200

    real_server 10.0.0.71 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }

    real_server 10.0.0.72 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }
}

仮想サーバー構成は、lb_kindDR (直接ルーティング)に設定されていることを除けば、8.7項「NATモードでのKeepalivedを使用したロード・バランシングの構成」と同様で、Keepalivedサーバーが、クライアントからのすべてのインバウンド・ネットワーク・トラフィックを処理してからバックエンド・サーバーにルーティングし、バックエンド・サーバーがKeepalivedサーバーをバイパスしてクライアントに直接返信します。この構成では、Keepalivedサーバーにかかる負荷は軽減されますが、各バックエンド・サーバーに外部アクセスが必要であるうえ、攻撃の前面に晒される可能性があるため、セキュリティは弱くなります。一部の実装では、追加のネットワーク・インタフェースを使用し、Webサーバーごとに、レスポンス・ネットワーク・トラフィックを処理するための専用ゲートウェイがあります。

バックアップ・サーバーの構成は、notification_email_fromstateおよびpriorityの値(およびシステム・ハードウェア構成が異なる場合はinterfaceの値)を除けば同じです。

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from svr2@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_instance external {
    state BACKUP
    interface enp0s8
    virtual_router_id 91
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1215
    }
    virtual_ipaddress {
        10.0.0.1/24
    }
}

virtual_server 10.0.0.1 80 {
    delay_loop 10
    protocol TCP
    lb_algo rr
#   Use direct routing
    lb_kind DR
    persistence_timeout 7200

    real_server 10.0.0.71 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }

    real_server 10.0.0.72 80 {
        weight 1
        TCP_CHECK {
          connect_timeout 5
          connect_port 80
        }
    }
}

さらに2つの構成変更が必要です。

Keepalivedをインストールおよび構成する方法の詳細は、8.5項「Keepalivedのインストールと構成」を参照してください。

8.8.1 Keepalived DRモード・ロード・バランシングのためのファイアウォール・ルールの構成

Keepalivedにより処理するサービスまたはポートへのアクセスを有効にします。

たとえば、HTTPへのアクセスを有効にし、リブート後もこのルールを保持する場合は、次のコマンドを入力します。

# firewall-cmd --zone=public --add-service=http
success
# firewall-cmd --permanent --zone=public --add-service=http
success

8.8.2 Keepalived DRモード・ロード・バランシングのためのバックエンド・サーバーの構成

この構成例では、プライマリKeepalivedサーバーおよび各バックエンド・サーバーで仮想IPアドレスが構成されている必要があります。Keepalived構成では、プライマリKeepalivedサーバーで仮想IPアドレスが管理されます。

プライマリKeepalivedサーバーのみが、仮想IPアドレスのARPリクエストに応答する必要があります。各バックエンド・サーバーのネットワーク・インタフェースのARPパラメータarp_ignoreおよびarp_announceを設定して、これらが仮想IPアドレスのARPリクエストに応答しないように設定できます。

各バックエンド・サーバーでARPパラメータおよび仮想IPアドレスを構成するには:

  1. プライマリ・ネットワーク・インタフェース(enp0s8など)のARPパラメータを構成します。

    # echo "net.ipv4.conf.enp0s8.arp_ignore = 1" >> /etc/sysctl.conf
    # echo "net.ipv4.conf.enp0s8.arp_announce = 2" >> /etc/sysctl.conf
    # sysctl -p
    net.ipv4.conf.enp0s8.arp_ignore = 1
    net.ipv4.conf.enp0s8.arp_announce = 2
  2. 再起動しても維持される仮想IPアドレスを定義するには、/etc/sysconfig/network-scripts/ifcfg-ifaceを編集し、次のように仮想IPアドレスのIPADDR1およびPREFIX1エントリを追加します。

    ...
    NAME=enp0s8
    ...
    IPADDR0=10.0.0.72
    GATEWAY0=10.0.0.100
    PREFIX0=24
    IPADDR1=10.0.0.1
    PREFIX1=24
    ...

    この例では、バックエンド・サーバーの既存の実IPアドレスに加えて、enp0s8の仮想IPアドレス10.0.0.1を定義しています。

  3. システムをリブートし、仮想IPアドレスが設定されたことを確認します。

    # ip addr show enp0s8
    2: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
        link/ether 08:00:27:cb:a6:8d brd ff:ff:ff:ff:ff:ff
        inet 10.0.0.72/24 brd 10.0.0.255 scope global enp0s8
        inet 10.0.0.1/24 brd 10.0.0.255 scope global secondary enp0s8
        inet6 fe80::a00:27ff:fecb:a68d/64 scope link 
           valid_lft forever preferred_lft forever

8.9 セッションの永続性とファイアウォール・マークのためのKeepalivedの構成

多くのWebベース・アプリケーションでは、同じWebサーバーが永続的にユーザー・セッションを提供する必要があります。

Keepalivedでロード・バランサが永続性を使用できるようにすると、前の接続からタイムアウト期間(persistence_timeout)が経過していなければ、クライアントは同じサーバーに接続します。

Keepalivedが異なるポート(HTTP (80)やHTTPS (443)など)上のクライアント接続を同じサーバーに転送するようにセッション・アクセスを制御するには、次の例のように、ファイアウォール・マークを使用することもできます。

# firewall-cmd --direct --permanent --add-rule ipv4 mangle PREROUTING 0 \
  -d virtual_IP_addr/32 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 123
success
# firewall-cmd --reload

これらのコマンドによって、ポート80または443上の指定された仮想IPアドレスを宛先とするパケットにファイアウォール・マーク値123が設定されます。

また、次の例のように、宛先の仮想IPアドレスとポートではなく、仮想サーバー上でファイアウォール・マーク(fwmark)値を設定することにより、ファイアウォール・マーク値をKeepalivedに対して宣言する必要もあります。

virtual_server fwmark 123 {
   ...
}

この構成では、Keepalivedは、宛先の仮想IPアドレスとポートではなく、ファイアウォール・マーク値に基づいてパケットをルーティングします。ファイアウォール・マークをセッションの永続性と組み合せて使用すると、1つのクライアント・セッションで使用されるすべてのポートが同じサーバーによって処理されるように設定できます。

8.10 Keepalivedを使用したHAProxyの高可用性の実現

次の例では、Keepalivedを使用して、プライマリ・サーバーに障害が発生した場合にHAProxyサービスによりバックアップ・サーバーへのフェイルオーバーが行われるように設定します。

次の図では、2つのHAProxyサーバーを示しており、それらは10.0.0.11および10.0.0.12として外部公開ネットワーク(10.0.0.0/24)に接続され、192.168.1.11および192.168.1.12として内部ネットワーク(192.168.1.0/24)に接続されています。一方のHAProxyサーバー(10.0.0.11)は仮想IPアドレスが10.0.0.10のKeepalivedプライマリ・サーバーとして構成され、もう一方(10.0.0.12)はKeepalivedバックアップ・サーバーとして構成されています。内部ネットワークでは、2つのWebサーバーwebsvr1 (192.168.1.71)およびwebsvr2 (192.168.1.72)にアクセス可能です。IPアドレス10.0.0.10はプライベート・アドレス範囲10.0.0.0/24内にあり、インターネット上でルーティングできません。アップストリーム・ネットワーク・アドレス変換(NAT)ゲートウェイまたはプロキシ・サーバーが、インターネットとの間のアクセスを提供します。

図8.5 個別ネットワークのWebサーバーと組み合せたHAProxyおよびKeepalived構成の例
この図では、2つのHAProxyサーバーを示しており、それらは10.0.0.11および10.0.0.12として外部公開ネットワーク(10.0.0.0/24)に接続され、192.168.1.11および192.168.1.12として内部ネットワーク(192.168.1.0/24)に接続されています。一方のHAProxyサーバー(10.0.0.11)は仮想IPアドレスが10.0.0.10のKeepalivedプライマリ・サーバーとして構成され、もう一方(10.0.0.12)はKeepalivedバックアップ・サーバーとして構成されています。内部ネットワークでは、2つのWebサーバーwebsvr1 (192.168.1.71)およびwebsvr2 (192.168.1.72)にアクセス可能です。IPアドレス10.0.0.10はプライベート・アドレス範囲10.0.0.0/24内にあり、インターネット上でルーティングできません。アップストリームNATゲートウェイまたはプロキシ・サーバーが、インターネットとの間のアクセスを提供します。

10.0.0.1110.0.0.12のどちらのHAProxy構成も、第8.3項「HAProxyを使用した単純なロード・バランシングの構成」と非常によく似ています。HAProxyが受信リクエストをリスニングするIPアドレスは、Keepalivedが制御する仮想IPアドレスです。

global
    daemon
    log 127.0.0.1 local0 debug
    maxconn 50000
    nbproc 1

defaults
    mode http
    timeout connect 5s
    timeout client 25s
    timeout server 25s
    timeout queue 10s

# Handle Incoming HTTP Connection Requests on the virtual IP address controlled by Keepalived
listen  http-incoming
    mode http
    bind 10.0.0.10:80
# Use each server in turn, according to its weight value
    balance roundrobin
# Verify that service is available
    option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
# Insert X-Forwarded-For header
    option forwardfor
# Define the back-end servers, which can handle up to 512 concurrent connections each
    server websvr1 192.168.1.71:80 weight 1 maxconn 512 check
    server websvr2 192.168.1.72:80 weight 1 maxconn 512 check

また、次の図に示すように、HAProxyとKeepalivedをWebサーバーで直接構成することもできます。前の例で示したように、一方のHAProxyサーバー(10.0.0.11)は仮想IPアドレスが10.0.0.10のKeepalivedプライマリ・サーバーとして構成され、もう一方(10.0.0.12)はKeepalivedバックアップ・サーバーとして構成されています。プライマリ・サーバー上のHAProxyサービスはポート80でリスニングし、(ポート8080でリスニングする) httpdサービスの1つに受信リクエストを転送します。

図8.6 統合Webサーバーと組み合せたHAProxyおよびKeepalived構成の例
この図では、一方のHAProxyサーバー(10.0.0.11)を示しており、これは、仮想IPアドレスが10.0.0.10のKeepalivedプライマリ・サーバーとして構成されています。もう一方のIPアドレス(10.0.0.12)は、Keepalivedバックアップ・サーバーとして構成されています。プライマリ・サーバー上のHAProxyサービスはポート80でリスニングし、(ポート8080でリスニングする) httpdサービスの1つに受信リクエストを転送します。

HAProxy構成は、WebサーバーのIPアドレスとポートを除けば、前の例と同じです。

...
    server websvr1 10.0.0.11:8080 weight 1 maxconn 512 check
    server websvr2 10.0.0.12:8080 weight 1 maxconn 512 check

各サーバーのファイアウォールは、ポート8080で受信TCPリクエストを受け入れるよう構成する必要があります。

どちらの構成例のKeepalived構成も、8.6項「Keepalivedを使用した単純な仮想IPアドレス・フェイルオーバーの構成」に示されている構成と似ています。

プライマリ(マスター)・サーバーのKeepalived構成は次のとおりです。

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from haproxy1@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_instance VRRP1 {
    state MASTER
#   Specify the network interface to which the virtual address is assigned
    interface enp0s8
#   The virtual router ID must be unique to each VRRP instance that you define
    virtual_router_id 41
#   Set the value of priority higher on the primary server than on a backup server
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1066
    }
    virtual_ipaddress {
        10.0.0.10/24
    }
}

バックアップ・サーバーの構成は、notification_email_fromstateおよびpriorityの値(およびシステム・ハードウェア構成が異なる場合はinterfaceの値)を除けば同じです。

global_defs {
   notification_email {
     root@mydomain.com
   }
   notification_email_from haproxy2@mydomain.com
   smtp_server localhost
   smtp_connect_timeout 30
}

vrrp_instance VRRP1 {
    state BACKUP
#   Specify the network interface to which the virtual address is assigned
    interface enp0s8
    virtual_router_id 41
#   Set the value of priority lower on the backup server than on the primary server
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1066
    }
    virtual_ipaddress {
        10.0.0.10/24
    }
}

プライマリ・サーバー(haproxy1)に障害が発生した場合、keepalivedは仮想IPアドレス10.0.0.10/24をバックアップ・サーバー (haproxy2)のenp0s8インタフェースに割り当て、これがプライマリ・サーバーとなります。

HAProxyとKeepalivedをインストールおよび構成する方法の詳細は、第8.2項「HAProxyのインストールと構成」および第8.5項「Keepalivedのインストールと構成」を参照してください。

8.11 Keepalivedの通知スクリプトと追跡スクリプトについて

通知スクリプトは、サーバーの状態が変更されたときにKeepalivedによって起動される実行可能プログラムです。通知スクリプトを実装すると、ネットワーク・インタフェースの再構成や、サービスの起動、再ロード、停止などのアクションを実行できます。

通知スクリプトを起動するには、vrrp_instanceまたはvrrp_sync_groupセクション内に次のいずれかの行を挿入します。

notify program_path

次の引数を使用してprogram_pathを起動します。

$1

Keepalivedがプログラムをvrrp_instanceから起動したかvrrp_sync_groupから起動したかに応じて、INSTANCEまたはGROUPに設定します。

$2

vrrp_instanceまたはvrrp_sync_groupの名前に設定します。

$3

遷移の最終状態(BACKUPFAULTまたはMASTER)に設定します。

notify_backup program_pathnotify_backup "program_path arg ..."

遷移の最終状態がBACKUPのときにprogram_pathを起動します(program_pathは実行可能スクリプトまたはバイナリのフルパス名)。プログラムに引数がある場合は、プログラム・パスと引数の両方をカッコで囲んでください。

notify_fault program_pathnotify_fault "program_path arg ..."

遷移の最終状態がFAULTのときにprogram_pathを起動します。

notify_master program_pathnotify_master "program_path arg ..."

遷移の最終状態がMASTERのときにprogram_pathを起動します。

次の実行可能スクリプトは、notifyの汎用バージョンを処理するために使用できます。

#!/bin/bash

ENDSTATE=$3
NAME=$2
TYPE=$1

case $ENDSTATE in
    "BACKUP") # Perform action for transition to BACKUP state
              exit 0
              ;;
    "FAULT")  # Perform action for transition to FAULT state
              exit 0
              ;;
    "MASTER") # Perform action for transition to MASTER state
              exit 0
              ;;
    *)        echo "Unknown state ${ENDSTATE} for VRRP ${TYPE} ${NAME}"
              exit 1
              ;;
esac

追跡スクリプトは、Keepalivedがvrrp_script定義に従って一定の間隔で実行するプログラムです。

vrrp_script script_name {
  script       "program_path arg ..."
  interval i  # Run script every i seconds
  fall f      # If script returns non-zero f times in succession, enter FAULT state
  rise r      # If script returns zero r times in succession, exit FAULT state
  timeout t   # Wait up to t seconds for script before assuming non-zero exit code
  weight w    # Reduce priority by w on fall
}

この例では、program_pathは、実行可能スクリプトまたはバイナリのフルパス名です。

次の例のように、track_script句を指定することにより、追跡スクリプトをvrrp_instanceセクションと組み合せて使用できます。

vrrp_instance instance_name {
  state MASTER
  interface enp0s8
  virtual_router_id 21
  priority 200
  advert_int 1
  virtual_ipaddress {
    10.0.0.10/24
  }
  track_script {
    script_name
    ...
  }
}

構成済のスクリプトがゼロ以外の終了コードを連続してf回返した場合、KeepalivedはVRRPインスタンスまたはグループの状態をFAULTに変更し、仮想IPアドレス10.0.0.10enp0s8から削除し、優先度の値をwだけ小さくして、マルチキャストVRRPパケットの送信を停止します。その後、スクリプトがゼロの終了コードを連続してr回返した場合、VRRPインスタンスまたはグループはFAULT状態を終了し、その新しい優先度に応じてMASTERまたはBACKUP状態に遷移します。

1つ以上のインタフェースが停止した場合にサーバーをFAULT状態にするには、次の例のように、track_interface句を使用することもできます。

  track_interface {
    enp0s8
    enp0s9
  }

応用例として、Keepalivedサーバーの一部が通信を失ったときのスプリットブレイン条件を処理する追跡スクリプトを作成することもできます。たとえば、スクリプトによって、他のKeepalivedサーバーの存在を追跡したり、共有ストレージやバックアップ通信チャネルを使用して投票メカニズムを実装したりできます。ただし、スプリット・ブレイン条件を回避するようにKeepalivedを構成することは複雑であり、スクリプトによるソリューションでは対応できない場合もあります。

代替ソリューションの詳細は、8.12項「Oracle Clusterwareを使用したHAProxyの高可用性の実現」を参照してください。

8.12 Oracle Clusterwareを使用したHAProxyの高可用性の実現

2つ以上のサーバーでKeepalivedを使用する場合、ネットワーク接続が失われることによりスプリットブレイン状況が発生し、複数のサーバーがプライマリ・サーバーとなり、データが破損する可能性があります。このシナリオを回避するため、Keepalivedに優先して仮想IPアドレス・フェイルオーバーをサポートするように、HAProxyをOracle Clusterwareなどのshoot the other node in the head (STONITH)ソリューションと組み合せて使用することをお薦めします。

Oracle Clusterwareは、個々のサーバーが単一クラスタとして連携するように構成できるポータブル・クラスタ化ソフトウェア・ソリューションです。クラスタ内の個々のサーバーは連携するため、外部クライアント・アプリケーションには単一サーバーのように見えます。

次の例では、各クラスタ・ノードで、HTTPD Webサーバー・インスタンスに対するロード・バランシングのために、Oracle ClusterwareをHAProxyと組み合せて使用します。HAProxyおよびHTTPDインスタンスを実行しているノードに障害が発生すると、サービスおよびその仮想IPアドレスが他のクラスタ・ノードにフェイルオーバーします。

次の図は、外部公開ネットワークに接続された2つのクラスタ・ノードを示しています。これらのノードは、クラスタ・ハートビートに使用されるプライベート・ネットワークによってもリンクされています。これらのノードは、サービス構成データとアプリケーション・データだけでなく、投票ディスクとOracle Cluster Registry (OCR)が格納された認定済のSANまたはNASストレージへの共有アクセス権を持ちます。

図8.7 2つのノードが存在するOracle Clusterware構成の例
この図は、外部公開ネットワークに接続された2つのクラスタ・ノードを示しています。これらのノードは、クラスタ・ハートビートに使用されるプライベート・ネットワークによってもリンクされています。これらのノードは、サービス構成データとアプリケーション・データだけでなく、投票ディスクとOracle Cluster Registry (OCR)が格納された認定済のSANまたはNASストレージへの共有アクセス権を持ちます。

高可用性構成では、ネットワーク、ハートビートおよびストレージの接続を複合的な冗長構成にし、少なくとも3つの投票ディスクを構成することをお薦めします。

次の手順は、このタイプのクラスタの構成方法を示しています。

  1. クラスタ・ノードとして機能する各システムにOracle Clusterwareをインストールします。

  2. 各ノードにhaproxyおよびhttpdパッケージをインストールします。

  3. appvipcfgコマンドを使用して、HAProxyの仮想IPアドレスと、HTTPDサービス・インスタンスごとに個別の仮想IPアドレスを作成します。たとえば、2つのHTTPDサービス・インスタンスがある場合、3つの異なる仮想IPアドレスを作成する必要があります。

  4. HAProxyとHTTPDサービスを開始、停止、クリーンアップおよび確認するクラスタ・スクリプトを各ノードに実装します。これらのスクリプトは、成功すると0を返し、失敗すると1を返します。

  5. 共有ストレージを使用して、構成ファイル、HTMLファイル、ログ、および各ノード上のHAProxyとHTTPDサービスが起動するのに必要なすべてのディレクトリとファイルを共有します。

    Oracle Linux Supportサブスクリプションがある場合は、NFSや他のタイプの共有ファイル・システムのかわりに、OCFS2またはASM/ACFSを共有ストレージで使用できます。

  6. 各HTTPDサービス・インスタンスを構成して、正しい仮想IPアドレスにバインドします。また、各サービス・インスタンスには、1つのノードに障害が発生したときにすべてのサービス・インスタンスが同じサーバーに共存できるように、構成ファイル、ログ・ファイルおよびその他の必要なファイルからなる個別セットが必要です。

  7. crsctlコマンドを使用して、HAProxyごと、およびHTTPDサービス・インスタンスごとにクラスタ・リソースを作成します。HTTPDサービス・インスタンスが2つ以上存在する場合、これらのインスタンスのバインディングを最初にクラスタ・ノード間で分散する必要があります。最初はいずれかのノードでHAProxyサービスを起動できます。

Oracle Clusterwareを、フロントエンドのロード・バランサ、Webサーバー、データベース・サーバーおよび他のコンポーネントからなる多層システムを保護する、より複雑なソリューションの基礎として使用できます。

詳細は、『Oracle Clusterware管理およびデプロイメント・ガイド11g』および『Oracle Clusterware管理およびデプロイメント・ガイド12c』を参照してください。