はじめに
こんにちは。サイオステクノロジー 小林です。
今回は haproxyとkeepalivedを組み合わせた 冗長化ロードバランサを構築するお話しです。
このブログが開設されて数年立ちますが、意外にもまだ haproxyを扱った記事がなく、個人的にも好きなソフトウェアなので、少しでも良さが伝わればと思いつつ、お話しさせて頂こうと思いました。
haproxy とは
haproxy とは、Linux系システムで利用可能なオープンソースソフトウェアのHTTPプロキシソフトウェアです。haproxy + keepalived で構成することにより、冗長化のL7ロードバランサ-(※1)として機能させることができます。
※1) オプションのパラメータを追加することによりtransparent proxy としてL4の振舞に変更することもできますが、今回のインストール編ではデフォルトのL7ロードバランサとしてご紹介します。
さて、本記事は全2回シリーズに分けてお話しさせて頂こうと思います。
- インストール編
- 動作確認編
環境構成
導入バージョン
・CentOS 7.5
・haproxy 1.5.18-8
・keepalived 1.3.5-8
・httpsd 2.4.6-88
Webサーバ構築
バックエンドとなるWebサーバ(Apache)の構築に関しては、以下記事を参照し構築してください。
【WEB01/WEB02/WEB03で以下実施】
https://tech-lab.sios.jp/archives/12738
構築
全体構成
以下のような構成を想定しています。
- ネットワークインターフェース名は、従来のethXX表記を使用
- eth0=”frontend”、eth1=”backend”としてfirewalldのゾーンを定義
- 割り振り先となるバックエンドサーバは、Webサーバ3ノード構成(Apacheを3インスタンスに分割)
- haproxyは Active-Standby構成
- SSLの終端をhaproxyが担う
- 自動フェイルバックは行わない

構築前提
- 手順上の操作はすべてrootで操作
- SELinuxは無効
インストール
haproxy及びkeepalivedをインストールします。また、今回SSLを利用するにあたり自己証明書を作成するため、opensslパッケージを追加でインストールします。
【PROXY01/PROXY02で実施】
# yum install -y haproxy keepalived openssl
firewalld設定
PROXY01及びPROXY02ノード間においてVRRPアドバタイズ通信できるようにfirewalldを許可します。
また、併せてクライアントからのHTTPS通信を許可します。
【PROXY01/PROXY02で実施】
# firewall-cmd --add-rich-rule='rule protocol value="vrrp" accept' --zone=frontend --permanent
# firewall-cmd --add-port=443/tcp --zone=frontend --permanent
# firewall-cmd --reload
# firewall-cmd --list-all --zone=frontend
frontend (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services:
ports: 443/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule protocol value="vrrp" accept
# 許可されたポートが追加されていることを確認
ログ出力設定
haproxyのログ出力設定
haproxyのログ出力設定を行います。haproxyはデフォルトでlocal2を使用して出力されます。
また、本手順では動作確認時の可読性を考慮して、プロキシログとヘルスチェック等のシステム系のログを分割して出力するよう設定しています。
【PROXY01/PROXY02で実施】
# mkdir /var/lib/haproxy/dev # mkdir /var/log/haproxy # vim /etc/rsyslog.conf ※rsyslog.confの最下行に追記 # haproxy $AddUnixListenSocket /var/lib/haproxy/dev/log $template haproxy,"%timegenerated:1:10:date-rfc3339% %timegenerated:12:23:date-rfc3339% %msg%\n local2.=info -/var/log/haproxy/haproxy.log;haproxy &stop local2.=notice -/var/log/haproxy/haproxy_admin.log;haproxy &stop
keepalivedのログ出力設定
keepalivedのログ出力設定を行います。keepalivedはデフォルトでlocal1を使用して出力されます。
【PROXY01/PROXY02で実施】
# mkdir /var/log/keepalived # vim /etc/rsyslog.conf ※rsyslog.confの最下行に追記 # keepalived local1.* -/var/log/keepalived/keepalived.log &stop
keepalived設定
HAの設定を行います。今回はフロントエンド側(eth0)からのHTTPリクエスト処理をWEBサーバへ振り分けを行いますので、eth0デバイスに対してVIPを設定します。
【PROXY01/PROXY02で実施】
# vim /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "killall -0 haproxy"
interval 3 fall 3
}
vrrp_instance VI_1 {
#自動フェイルバック無効
state BACKUP
#バインドさせるインターフェース名を指定
interface eth0
virtual_router_id 188
priority 100
#VRRPアドバタイズ間隔を以下で設定することで、フェイルオーバー時間をある程度制御できるように設定
advert_int 1
authentication {
auth_type PASS
auth_pass root2019t_04
}
virtual_ipaddress {
192.168.188.10 dev eth0
}
track_script {
chk_haproxy
}
}
haproxy設定
haproxyの設定を行います。Globalセクションではhaproxy全体に係る設定を行い、backendセクションでクライアントからリクエストを受けた処理を受け渡すホストを設定します。
【PROXY01/PROXY02で実施】
# vim /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
log /dev/log local2
log-send-hostname
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
nbproc 1
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#機能モードの指定。今回はHTTPプロキシのため「https」を設定
mode https
#---------------------------------------------------------------------
# listen
#---------------------------------------------------------------------
listen stats
bind 192.168.188.8:9090
mode https
maxconn 64
stats enable
stats uri /haproxy/
stats refresh 10s
stats auth admin:<yourpassword>
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend https-ex
♯リッスンさせるインターフェースを指定。今回SSL終端として機能させるため証明書を指定し、SSL3.0によるネゴシエーションを無効にします。
bind 192.168.188.10:443 ssl crt /etc/haproxy/ssl/proxy.lab.sios.com.crt no-sslv3
reqadd X-Forwarded-Proto:\ https
option forwardfor
use_backend TEST-WEB
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend TEST-WEB
mode https
#WEBサーバ3ノードに対してラウンドロビンによる負荷分散を設定
balance roundrobin
server WEB01 web01.lab.sios.com:8081 maxconn 200 check inter 3s fall 10 rise 5
server WEB02 web02.lab.sios.com:8082 maxconn 200 check inter 3s fall 10 rise 5
server WEB03 web03.lab.sios.com:8083 maxconn 200 check inter 3s fall 10 rise 5
サービス起動・起動確認
haproxy及びkeepalivedのサービスを起動します。また、keepalivedによりVIPがバインドされていること、haproxyのバックエンドに対するヘルスチェックが成功していることを確認します。
【PROXY01で以下実施】
# systemctl start keepalived.service # systemctl status keepalived.service # systemctl start haproxy.service # systemctl status haproxy.service
# ip a show
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:35:76:e0 brd ff:ff:ff:ff:ff:ff
inet 192.168.188.8/24 brd 192.168.188.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 192.168.188.10/32 scope global eth0
#VIPがバインドされていることを確認
# tail -n100 /var/log/haproxy/haproxy_admin.log
haproxy[20739]: Health check for server TEST-WEB/WEB01 succeeded, reason: Layer4 check passed, check duration: 3ms, status: 10/10 UP.
haproxy[20740]: Health check for server TEST-WEB/WEB02 succeeded, reason: Layer4 check passed, check duration: 8ms, status: 10/10 UP.
haproxy[20740]: Health check for server TEST-WEB/WEB03 succeeded, reason: Layer4 check passed, check duration: 2ms, status: 10/10 UP
#ヘルスチェックが成功していること
簡易動作確認
クライアントからcurlを利用してHTTPSのリクエスト送信して疎通を確認します。疎通が問題なければ、バックエンド側で用意したWebサーバのページが表示されます。
> curl -X GET https://192.168.188.10 -k THIS web01.lab.sios.com > curl -X GET https://192.168.188.10 -k THIS web02.lab.sios.com > curl -X GET https://192.168.188.10 -k THIS web03.lab.sios.com
続いて、haproxyのリクエストログを確認します。
クライアントからのリクエストが正常に送信されていることが確認できます。
2019-04-25 12:32:04.619 haproxy[12022]:***client address***:65410 [25/Apr/2019:12:32:04.593] https-ex~ TEST-WEB/WEB01 24/0/1/0/25 200 245 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" 2019-04-25 12:32:05.230 haproxy[12022]:***client address***:65411 [25/Apr/2019:12:32:05.215] https-ex~ TEST-WEB/WEB02 13/0/1/0/14 200 245 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" 2019-04-25 12:32:05.920 haproxy[12022]:***client address***:65415 [25/Apr/2019:12:32:05.895] https-ex~ TEST-WEB/WEB03 23/0/0/1/24 200 245 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
※以下記事で、動作確認について紹介しておりますので、あわせて確認ください。
https://tech-lab.sios.jp/archives/16123
最後に
今回はhaproxyとkeepalivedのインストール及び各種設定までをご紹介しました。
次回は実際にクライアントからリクエストを送信した際の挙動やStandbyへのフェイルオーバーの動作確認を紹介する予定です。

