8 ロード・バランシングの構成
この章では、ネットワーク・サービスへの継続的なアクセスを維持しながら、これらのアクセスを分散するためにKeepalivedおよびHAProxyテクノロジを構成する方法について説明します。
HAProxyについて
HAProxyは、アプリケーション・レイヤー(レイヤー7)のロード・バランシングおよび高可用性ソリューションであり、HTTPベースおよびTCPベースのインターネット・サービスにリバース・プロキシを実装するために使用できます。
haproxy
デーモンの構成ファイルは、/etc/haproxy/haproxy.cfg
です。このファイルが、ロード・バランシングまたは高可用性のためにHAProxyを構成する各サーバーに存在している必要があります。
詳細は、http://www.haproxy.org/#docs、/usr/share/doc/haproxy-version
ドキュメントおよびhaproxy(1)
マニュアル・ページを参照してください。
HAProxyのインストールと構成
HAProxyをインストールするには、次のようにします。
-
各フロントエンド・サーバーに
haproxy
パッケージをインストールします。sudo yum install haproxy
-
/etc/haproxy/haproxy.cfg
を編集して、各サーバーでHAProxyを構成します。HAProxy構成ファイルについてを参照してください。 -
ローカルでない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
-
HAProxyにより処理するサービスまたはポートへのアクセスを有効にします。
たとえば、HTTPへのアクセスを有効にし、リブート後もこのルールを保持する場合は、次のコマンドを入力します。
sudo firewall-cmd --zone=zone --add-service=http
success
sudo firewall-cmd --permanent --zone=zone --add-service=http
success
受信TCPリクエストをポート8080で許可するには:
sudo firewall-cmd --zone=zone --add-port=8080/tcp
success
sudo firewall-cmd --permanent --zone=zone --add-port=8080/tcp
success
-
各サーバーで
haproxy
サービスを有効にし、起動します。sudo systemctl enable haproxy ln -s '/usr/lib/systemd/system/haproxy.service' '/etc/systemd/system/multi-user.target.wants/haproxy.service' sudo systemctl start haproxy
HAProxy構成を変更した場合は、
haproxy
サービスを再ロードします。sudo systemctl reload haproxy
HAProxy構成ファイルについて
/etc/haproxy/haproxy.cfg
構成ファイルは、次の各セクションに分かれています。
-
global
-
syslog
機能などのグローバル設定と、ロギングに使用するレベル、許可される最大同時接続数、およびデーモン・モードで開始するプロセス数を定義します。 -
defaults
-
後続のセクションのデフォルト設定を定義します。
-
listen
-
完全プロキシを定義し、
frontend
およびbackend
コンポーネントを暗黙的に挿入します。 -
frontend
-
クライアント接続を受け入れるポートを定義します。
-
backend
-
プロキシがクライアント接続を転送する先のサーバーを定義します。
HAProxyの構成方法の例は、次の項を参照してください。
HAProxyを使用した単純なロード・バランシングの構成
次の例では、HAProxyを使用して、受信リクエストを2つのバックエンドWebサーバー間で分散し、さらにバックエンド・サーバーでサービス停止を処理する機能も持つフロントエンド・サーバーを実装します。
図8-1に、外部公開ネットワーク(10.0.0.0/24
)および内部ネットワーク(192.168.1.0/24
)に接続されたHAProxyサーバー(10.0.0.10
)を示します。内部ネットワークでは、websvr1
(192.168.1.71
)およびwebsvr2
(192.168.1.72
)という2つのWebサーバーにアクセス可能です。IPアドレス192.168.1.10はプライベート・アドレス範囲192.168.1.0/24
内にあり、インターネット上でルーティングできません。アップストリーム・ネットワーク・アドレス変換(NAT)ゲートウェイまたはプロキシ・サーバーが、インターネットとの間のアクセスを提供します。
図8-1 ロード・バランシングのためのHAProxy構成の例
![この図は、外部公開ネットワーク(10.0.0.0/24)および内部ネットワーク(192.168.1.0/24)に接続されたHAProxyサーバー(10.0.0.10)を示しています。内部ネットワークでは、2つのWebサーバーwebsvr1 (192.168.1.71)およびwebsvr2 (192.168.1.72)にアクセス可能です。IPアドレス192.168.1.10はプライベート・アドレス範囲192.168.1.0/24内にあり、インターネット上でルーティングできません。アップストリームNATゲートウェイまたはプロキシ・サーバーが、インターネットとの間のアクセスを提供します。 この図は、外部公開ネットワーク(10.0.0.0/24)および内部ネットワーク(192.168.1.0/24)に接続されたHAProxyサーバー(10.0.0.10)を示しています。内部ネットワークでは、2つのWebサーバーwebsvr1 (192.168.1.71)およびwebsvr2 (192.168.1.72)にアクセス可能です。IPアドレス192.168.1.10はプライベート・アドレス範囲192.168.1.0/24内にあり、インターネット上でルーティングできません。アップストリームNATゲートウェイまたはプロキシ・サーバーが、インターネットとの間のアクセスを提供します。](img/haproxy1.png)
サーバーの/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 $
この例では、websvr1
でhttpd
サービスが再起動され、websvr2
に加えてこのサーバーも再び使用し始めたことが、HAProxyによって検出されました。
HAProxyのロード・バランシング機能をKeepalivedまたはOracle Clusterwareの高可用性機能と組み合せることにより、プライマリ・ロード・バランサの障害発生時にもサービスを継続できるようにバックアップ・ロード・バランサを構成できます。Keepalivedを使用したHAProxyの高可用性の実現およびOracle Clusterwareを使用したHAProxyの高可用性の実現を参照してください。
HAProxyをインストールおよび構成する方法の詳細は、HAProxyのインストールと構成を参照してください。
セッションの永続性のためのHAProxyの構成
多くのWebベース・アプリケーションでは、同じWebサーバーが永続的にユーザー・セッションを提供する必要があります。
Webセッションを同じサーバーに永続的に接続する場合は、hdr
、rdp-cookie
、source
、uri
、url_param
などのbalance
アルゴリズムを使用できます。
実装でleastconn
、roundrobin
または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).
^CC 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が含められます。
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)
マニュアル・ページを参照してください。
Keepalivedのインストールと構成
Keepalivedをインストールするには、次のようにします。
-
各サーバーに
keepalived
パッケージをインストールします。sudo yum install keepalived
-
/etc/keepalived/keepalived.conf
を編集して、各サーバーでKeepalivedを構成します。Keepalived構成ファイルについてを参照してください。 -
次のように、IP転送を有効にします。
sudo echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf sudo sysctl -p
net.ipv4.ip_forward = 1
-
各ネットワーク・インタフェースでKeepalivedが制御するマルチキャストIPアドレス224.0.0.18およびVRRPプロトコル(112)を使用してVRRP通信を行うことを許可するファイアウォール・ルールを追加します。たとえば:
sudo firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 \ --in-interface enp0s8 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
success
sudo firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 \ --out-interface enp0s8 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
success
sudo firewall-cmd --reload
success
-
各サーバーで
keepalived
サービスを有効にし、起動します。sudo systemctl enable keepalived sudo ln -s '/usr/lib/systemd/system/keepalived.service' '/etc/systemd/system/multi-user.target.wants/keepalived.service' sudo systemctl start keepalived
Keepalived構成を変更した場合は、
keepalived
サービスを再ロードします。sudo systemctl reload keepalived
Keepalived構成ファイルについて
/etc/keepalived/keepalived.conf
構成ファイルは、次の各セクションに分かれています。
-
global_defs
-
通知メッセージを送信するための電子メール・アドレス、SMTPサーバーのIPアドレス、SMTP接続のタイムアウト値(秒)、ホスト・マシンを識別する文字列、VRRP IPv4およびIPv6マルチキャスト・アドレス、SNMPトラップを有効にするかどうかなど、グローバル設定を定義します。
-
static_ipaddress
-
static_routes
-
VRRPが変更できない静的IPアドレスおよび静的ルートを定義します。サーバーでアドレスおよびルートがすでに定義されており、これらのサーバーにすでにネットワーク接続があれば、これらのセクションは必要ありません。
-
vrrp_sync_group
-
一緒にフェイルオーバーするVRRPインスタンスのVRRP同期グループを定義します。
-
vrrp_instance
-
状態遷移中に他のグループ・メンバーを随伴するVRRP同期グループの内部または外部のネットワーク・インタフェースのメンバーに対して移動可能な仮想IPアドレスを定義します。各VRRPインスタンスには、プライマリ・サーバーとバックアップ・サーバー上のどのインタフェースを特定の仮想IPアドレスに割り当てることができるかを指定する、一意の
virtual_router_id
値が必要です。また、BACKUP
、MASTER
およびFAULT
への状態遷移時に実行されるスクリプトと、状態遷移に対してSMTPアラートをトリガーするかどうかを指定することもできます。 -
vrrp_script
-
Keepalivedが一定の間隔で実行できる追跡スクリプトを定義して、
vrrp_instance
またはvrrp_sync_group
セクションから監視アクションを実行します。 -
virtual_server_group
-
実サーバーを複数の仮想サーバー・グループのメンバーにできるように、仮想サーバー・グループを定義します。
-
virtual_server
-
複数の実サーバーで構成される、ロード・バランシングのための仮想サーバーを定義します。
Keepalivedの構成方法の例は、次の項を参照してください。
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がそれに割り当てられます。 この図は、どのように仮想IPアドレス10.0.0.100が最初にプライマリ・サーバー(10.0.0.71)に割り当てられるかを示しています。プライマリ・サーバーに障害が発生すると、バックアップ・サーバー(10.0.0.72)が新しいプライマリ・サーバーとなり、仮想IPアドレス10.0.0.100がそれに割り当てられます。](img/keepalived1.png)
プライマリ(マスター)・サーバー上の/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_from
、state
および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コマンドを使用して、仮想アドレスがアクティブかどうかを調べます。
sudo 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をインストールおよび構成する方法の詳細は、Keepalivedのインストールと構成を参照してください。
NATモードでのKeepalivedを使用したロード・バランシングの構成
次の例では、NATモードでKeepalivedを使用して、2つのサーバー上に単純なフェイルオーバーおよびロード・バランシングの構成を実装します。1つのサーバーがプライマリ・サーバーとして機能し、その他のサーバーがバックアップとして機能します。プライマリ・サーバーの優先度はバックアップ・サーバーよりも高くなります。各サーバーには2つのネットワーク・インタフェースがあり、一方のインタフェースは外部ネットワーク(192.168.1.0/24
)に面した側に接続され、もう一方のインタフェースは、2つのWebサーバーにアクセス可能な内部ネットワーク(10.0.0.0/24
)に接続されています。
次の図は、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
です。
図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です。 この図は、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です。](img/keepalived2.png)
プライマリ・サーバー上の/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
}
}
}
前の構成は、Keepalivedを使用した単純な仮想IPアドレス・フェイルオーバーの構成に示した構成に似ており、それに、フェイルオーバー時にネットワーク・インタフェースがまとめて割り当てられるようにvrrp_sync_group
セクションの定義が追加され、Keepalivedがロード・バランシング用に使用する実際のバックエンド・サーバーを定義するvirtual_server
セクションも追加されています。lb_kind
の値はNATモードに設定されており、これは、Keepalivedサーバーがバックエンド・サーバーに代わってクライアントのインバウンド・ネットワーク・トラフィックとアウトバウンド・ネットワーク・トラフィックの両方を処理するということです。
バックアップ・サーバーの構成は、notification_email_from
、state
および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 NATモード・ロード・バランシングのためのファイアウォール・ルールの構成の説明に従って、ロード・バランサとして構成する各Keepalivedサーバー(プライマリおよびバックアップ)でファイアウォール・ルールを構成します。
-
Keepalived NATモード・ロード・バランシングのためのバックエンド・サーバー・ルーティングの構成の説明に従って、Keepalivedロード・バランサで使用する各バックエンド・サーバーで、ロード・バランサの内部ネットワーク・インタフェースの仮想IPアドレスのデフォルト・ルートを構成します。
Keepalivedをインストールおよび構成する方法の詳細は、Keepalivedのインストールと構成を参照してください。
Keepalived NATモード・ロード・バランシングのためのファイアウォール・ルールの構成
内部ネットワーク上のサーバーでロード・バランシングにNATモードを使用するようにKeepalivedを構成した場合、Keepalivedサーバーはすべてのインバウンド・ネットワーク・トラフィックとアウトバウンド・ネットワーク・トラフィックを処理し、送信パケット内の実バックエンド・サーバーのソースIPアドレスを外部ネットワーク・インタフェースの仮想IPアドレスでリライトすることによりバックエンド・サーバーの存在を隠します。
ロード・バランシングにNATモードを使用するようにKeepalivedサーバーを構成するには:
-
ファイアウォールを構成して、外部ネットワーク側のインタフェースが、内部ネットワーク側のインタフェースとは別のゾーンになるようにします。
次の例では、どのようにインタフェース
enp0s9
をinternal
ゾーンに移動し、インタフェースenp0s8
をpublic
ゾーンに残すかを示しています。sudo firewall-cmd --get-active-zones
public interfaces: enp0s8 enp0s9
sudo firewall-cmd --zone=public --remove-interface=enp0s9
success
sudo firewall-cmd --zone=internal --add-interface=enp0s9
success
sudo firewall-cmd --permanent --zone=public --remove-interface=enp0s9
success
sudo firewall-cmd --permanent --zone=internal --add-interface=enp0s9
success
sudo firewall-cmd --get-active-zones
internal interfaces: enp0s9 public interfaces: enp0s8
-
外部ネットワーク・インタフェースでNATモード(マスカレード)を構成します。たとえば:
sudo firewall-cmd --zone=public --add-masquerade
success
sudo firewall-cmd --permanent --zone=public --add-masquerade
success
sudo firewall-cmd --zone=public --query-masquerade
yes
sudo firewall-cmd --zone=internal --query-masquerade
no
-
ファイアウォールに対してまだ有効にしていない場合、外部ネットワーク・インタフェースと内部ネットワーク・インタフェースの間の転送ルールを構成します。たとえば:
sudo firewall-cmd --direct --permanent --add-rule ipv4 filter FORWARD 0 \ -i enp0s8 -o enp0s9 -m state --state RELATED,ESTABLISHED -j ACCEPT
success
sudo firewall-cmd --direct --permanent --add-rule ipv4 filter FORWARD 0 \ -i enp0s9 -o enp0s8 -j ACCEPT
success
sudo firewall-cmd --direct --permanent --add-rule ipv4 filter FORWARD 0 \ -j REJECT --reject-with icmp-host-prohibited
success
sudo firewall-cmd --reload
-
Keepalivedにより処理するサービスまたはポートへのアクセスを有効にします。
たとえば、HTTPへのアクセスを有効にし、リブート後もこのルールを保持する場合は、次のコマンドを入力します。
sudo firewall-cmd --zone=public --add-service=http
success
sudo firewall-cmd --permanent --zone=public --add-service=http
success
Keepalived NATモード・ロード・バランシングのためのバックエンド・サーバー・ルーティングの構成
Keepalivedロード・バランサで使用する各バックエンド実サーバーで、ルーティング表に、ロード・バランサの内部ネットワーク・インタフェースの仮想IPアドレスのデフォルト・ルートが含まれていることを確認してください。
たとえば、仮想IPアドレスが10.0.0.100
である場合、ipコマンドを使用してルーティング表を調べ、デフォルト・ルートを設定できます。
sudo ip route show
10.0.0.0/24 dev enp0s8 proto kernel scope link src 10.0.0.71
sudo ip route add default via 10.0.0.100 dev enp0s8 sudo 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
を作成します。
sudo echo "default via 10.0.0.100 dev enp0s8" > /etc/sysconfig/network-scripts/route-enp0s8
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サーバーが直接応答します。 この図は、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サーバーが直接応答します。](img/keepalived3.png)
プライマリ・サーバー上の/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_kind
がDR
(直接ルーティング)に設定されていることを除けば、NATモードでのKeepalivedを使用したロード・バランシングの構成と同様で、Keepalivedサーバーが、クライアントからのすべてのインバウンド・ネットワーク・トラフィックを処理してからバックエンド・サーバーにルーティングし、バックエンド・サーバーがKeepalivedサーバーをバイパスしてクライアントに直接返信します。この構成では、Keepalivedサーバーにかかる負荷は軽減されますが、各バックエンド・サーバーに外部アクセスが必要であるうえ、攻撃の前面に晒される可能性があるため、セキュリティは弱くなります。一部の実装では、追加のネットワーク・インタフェースを使用し、Webサーバーごとに、レスポンス・ネットワーク・トラフィックを処理するための専用ゲートウェイがあります。
バックアップ・サーバーの構成は、notification_email_from
、state
および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 DRモード・ロード・バランシングのためのファイアウォール・ルールの構成の説明に従って、ロード・バランサとして構成する各Keepalivedサーバー(プライマリおよびバックアップ)でファイアウォール・ルールを構成します。
-
Keepalived DRモード・ロード・バランシングのためのバックエンド・サーバーの構成の説明に従って、Keepalivedロード・バランサで使用する各バックエンド・サーバーで、ネットワーク・インタフェースのARPパラメータ(
arp_ignore
およびarp_announce
)と仮想IPアドレスを構成します。
Keepalivedをインストールおよび構成する方法の詳細は、Keepalivedのインストールと構成を参照してください。
Keepalived DRモード・ロード・バランシングのためのファイアウォール・ルールの構成
Keepalivedにより処理するサービスまたはポートへのアクセスを有効にします。
たとえば、HTTPへのアクセスを有効にし、リブート後もこのルールを保持する場合は、次のコマンドを入力します。
sudo firewall-cmd --zone=public --add-service=http
success
sudo firewall-cmd --permanent --zone=public --add-service=http
success
Keepalived DRモード・ロード・バランシングのためのバックエンド・サーバーの構成
この構成例では、プライマリKeepalivedサーバーおよび各バックエンド・サーバーで仮想IPアドレスが構成されている必要があります。Keepalived構成では、プライマリKeepalivedサーバーで仮想IPアドレスが管理されます。
プライマリKeepalivedサーバーのみが、仮想IPアドレスのARPリクエストに応答する必要があります。各バックエンド・サーバーのネットワーク・インタフェースのARPパラメータarp_ignore
およびarp_announce
を設定して、これらが仮想IPアドレスのARPリクエストに応答しないように設定できます。
各バックエンド・サーバーでARPパラメータおよび仮想IPアドレスを構成するには:
-
プライマリ・ネットワーク・インタフェース(
enp0s8
など)のARPパラメータを構成します。sudo echo "net.ipv4.conf.enp0s8.arp_ignore = 1" >> /etc/sysctl.conf sudo echo "net.ipv4.conf.enp0s8.arp_announce = 2" >> /etc/sysctl.conf sudo sysctl -p
net.ipv4.conf.enp0s8.arp_ignore = 1 net.ipv4.conf.enp0s8.arp_announce = 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
を定義しています。 -
システムをリブートし、仮想IPアドレスが設定されたことを確認します。
sudo 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
セッションの永続性とファイアウォール・マークのためのKeepalivedの構成
多くのWebベース・アプリケーションでは、同じWebサーバーが永続的にユーザー・セッションを提供する必要があります。
Keepalivedでロード・バランサが永続性を使用できるようにすると、前の接続からタイムアウト期間(persistence_timeout
)が経過していなければ、クライアントは同じサーバーに接続します。
Keepalivedが異なるポート(HTTP (80)やHTTPS (443)など)上のクライアント接続を同じサーバーに転送するようにセッション・アクセスを制御するには、次の例のように、ファイアウォール・マークを使用することもできます。
sudo 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
sudo firewall-cmd --reload
これらのコマンドによって、ポート80または443上の指定された仮想IPアドレスを宛先とするパケットにファイアウォール・マーク値123が設定されます。
また、宛先の仮想IPアドレスとポートではなく、仮想サーバー上でファイアウォール・マーク(fwmark
)値を設定することにより、ファイアウォール・マーク値をKeepalivedに対して宣言する必要もあります。たとえば:
virtual_server fwmark 123 { ... }
この構成では、Keepalivedは、宛先の仮想IPアドレスとポートではなく、ファイアウォール・マーク値に基づいてパケットをルーティングします。ファイアウォール・マークをセッションの永続性と組み合せて使用すると、1つのクライアント・セッションで使用されるすべてのポートが同じサーバーによって処理されるように設定できます。
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ゲートウェイまたはプロキシ・サーバーが、インターネットとの間のアクセスを提供します。 この図では、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ゲートウェイまたはプロキシ・サーバーが、インターネットとの間のアクセスを提供します。](img/hapka1.png)
10.0.0.11
と10.0.0.12
のどちらのHAProxy構成も、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サーバー(10.0.0.11)を示しており、これは、仮想IPアドレスが10.0.0.10のKeepalivedプライマリ・サーバーとして構成されています。もう一方のIPアドレス(10.0.0.12)は、Keepalivedバックアップ・サーバーとして構成されています。プライマリ・サーバー上のHAProxyサービスはポート80でリスニングし、(ポート8080でリスニングする) httpdサービスの1つに受信リクエストを転送します。](img/hapka2.png)
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構成も、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_from
、state
および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をインストールおよび構成する方法の詳細は、HAProxyのインストールと構成およびKeepalivedのインストールと構成を参照してください。
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
-
遷移の最終状態(
BACKUP
、FAULT
またはMASTER
)に設定します。
-
- notify_backup program_path
- notify_backup"program_patharg ..."
-
遷移の最終状態が
BACKUP
のときにprogram_pathを起動します(program_pathは実行可能スクリプトまたはバイナリのフルパス名)。プログラムに引数がある場合は、プログラム・パスと引数の両方をカッコで囲んでください。 - notify_fault program_path
- notify_fault"program_patharg ..."
-
遷移の最終状態が
FAULT
のときにprogram_pathを起動します。 - notify_master program_path
- notify_master"program_patharg ..."
-
遷移の最終状態が
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.10
をenp0s8
から削除し、優先度の値をwだけ小さくして、マルチキャストVRRPパケットの送信を停止します。その後、スクリプトがゼロの終了コードを連続してr回返した場合、VRRPインスタンスまたはグループはFAULT
状態を終了し、その新しい優先度に応じてMASTER
またはBACKUP
状態に遷移します。
1つ以上のインタフェースが停止した場合にサーバーをFAULT
状態にするには、track_interface
句を使用することもできます。たとえば:
track_interface { enp0s8 enp0s9 }
応用例として、Keepalivedサーバーの一部が通信を失ったときのスプリットブレイン条件を処理する追跡スクリプトを作成することもできます。たとえば、スクリプトによって、他のKeepalivedサーバーの存在を追跡したり、共有ストレージやバックアップ通信チャネルを使用して投票メカニズムを実装したりできます。ただし、スプリット・ブレイン条件を回避するようにKeepalivedを構成することは複雑であり、スクリプトによるソリューションでは対応できない場合もあります。
代替ソリューションの詳細は、Oracle Clusterwareを使用したHAProxyの高可用性の実現を参照してください。
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ストレージへの共有アクセス権を持ちます。 この図は、外部公開ネットワークに接続された2つのクラスタ・ノードを示しています。これらのノードは、クラスタ・ハートビートに使用されるプライベート・ネットワークによってもリンクされています。これらのノードは、サービス構成データとアプリケーション・データだけでなく、投票ディスクとOracle Cluster Registry (OCR)が格納された認定済のSANまたはNASストレージへの共有アクセス権を持ちます。](img/hapocw.png)
高可用性構成では、ネットワーク、ハートビートおよびストレージの接続を複合的な冗長構成にし、少なくとも3つの投票ディスクを構成することをお薦めします。
次の手順は、このタイプのクラスタの構成方法を示しています。
-
クラスタ・ノードとして機能する各システムにOracle Clusterwareをインストールします。
-
各ノードに
haproxy
およびhttpd
パッケージをインストールします。 -
appvipcfgコマンドを使用して、HAProxyの仮想IPアドレスと、HTTPDサービス・インスタンスごとに個別の仮想IPアドレスを作成します。たとえば、2つのHTTPDサービス・インスタンスがある場合、3つの異なる仮想IPアドレスを作成する必要があります。
-
HAProxyとHTTPDサービスを開始、停止、クリーンアップおよび確認するクラスタ・スクリプトを各ノードに実装します。これらのスクリプトは、成功すると0を返し、失敗すると1を返します。
-
共有ストレージを使用して、構成ファイル、HTMLファイル、ログ、および各ノード上のHAProxyとHTTPDサービスが起動するのに必要なすべてのディレクトリとファイルを共有します。
Oracle Linux Supportサブスクリプションがある場合は、NFSや他のタイプの共有ファイル・システムのかわりに、OCFS2またはASM/ACFSを共有ストレージで使用できます。
-
各HTTPDサービス・インスタンスを構成して、正しい仮想IPアドレスにバインドします。また、各サービス・インスタンスには、1つのノードに障害が発生したときにすべてのサービス・インスタンスが同じサーバーに共存できるように、構成ファイル、ログ・ファイルおよびその他の必要なファイルからなる個別セットが必要です。
-
crsctlコマンドを使用して、HAProxyごと、およびHTTPDサービス・インスタンスごとにクラスタ・リソースを作成します。HTTPDサービス・インスタンスが2つ以上存在する場合、これらのインスタンスのバインディングを最初にクラスタ・ノード間で分散する必要があります。最初はいずれかのノードでHAProxyサービスを起動できます。
Oracle Clusterwareを、フロントエンドのロード・バランサ、Webサーバー、データベース・サーバーおよび他のコンポーネントからなる多層システムを保護する、より複雑なソリューションの基礎として使用できます。
詳細は、『Oracle Clusterware管理およびデプロイメント・ガイド11g』および『Oracle Clusterware管理およびデプロイメント・ガイド12c』を参照してください。