はじめに
ロードバランサ(負荷分散装置)はネスペ試験の構成図でほぼ確実に出てきます。
また、実際の運用でも負荷分散を行っていることがほとんどだと思います。
机上の学習以外にも実機を触ってロードバランサの動きを確認してみましょう。
ここでは、HAProxyを使ったロードバランサについて学んだのでその内容を記載しています。
HAProxyとは
高速かつ信頼性の高い ロードバランサ(負荷分散装置)兼プロキシサーバ。
特にWebシステムや大規模サービスで、トラフィックを複数のバックエンドサーバに分散させます。HAProxyの特徴を以下にまとめます。
| 項目 | 内容 |
|---|---|
| ソフトウェア名 | HAProxy(High Availability Proxy) |
| 開発言語 | C言語 |
| 主な用途 | 負荷分散(Load Balancing)、プロキシ(Proxy) |
| 対応プロトコル | TCP(レイヤ4)、HTTP/HTTPS(レイヤ7) |
| 主な利用分野 | Webサーバ、APIサーバ、アプリケーションロードバランサなど |
| 主な競合 | Nginx、Envoy、F5 BIG-IP、AWS ALBなど |
HAProxyを利用したイメージ
HAProxyを使った負荷分散通信イメージは以下のようになります。
クライアント端末のWebブラウザからアクセスするとHAProxyがWebサーバ1~3に振り分けます。
ここでクライアントがアクセスするのはHAProxyサーバです。
※今回の構成ではDNSサーバは利用しません。
┌────────────┐
│ Client │
└─────┬──────┘
│ HTTPリクエスト
┌─────▼──────┐
│ HAProxy │
└─────┬──────┘
┌──────────────┼──────────────┐
│ │ │
┌──▼──┐ ┌──▼──┐ ┌──▼──┐
│Web01│ │Web02│ │Web03│
└─────┘ └─────┘ └─────┘
今回の構成情報
まずは以下の構成で構築していきます。
ロードバランサの動作確認のためには複数のサーバが必要になりますが、複数の端末を準備するのは大変です。私はVirtualBoxを利用して複数の環境を準備しました。
IPアドレスは自由に置き換えていただいて構いません。適宜ご自身の環境に合わせて変更してください。
| 項目 | HAProxyサーバ | Webサーバ1号 | Webサーバ2号 | Webサーバ3号 |
|---|---|---|---|---|
| OS | AlmaLinux9.6 | AlmaLinux9.6 | AlmaLinux9.6 | AlmaLinux9.6 |
| IPアドレス | 192.168.0.100 | 192.168.0.5 | 192.168.0.6 | 192.168.0.7 |
| サービス | haproxy | httpd | httpd | httpd |
よって構成図は以下のようになります。
┌──────────────┐
│ Client │
└──────┬───────┘
│ HTTP
┌────────▼────────┐
│ HAProxy (:80) │
│ 192.168.0.100 │
└────────┬────────┘
┌────────────────┼───────────────┐
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ web01 │ │ web02 │ │ web03 │
│192.168.0.5│ │192.168.0.6│ │192.168.0.7│
└───────────┘ └───────────┘ └───────────┘
最初にWebサーバの準備をしよう
最初に振り分け対象のWebサーバを3台構築します。
構成情報にも記載していますが、今回はAlmaLinux9.6の最小構成でセットアップしている状態から作業を開始します。
# Webサーバ1にApacheをインストール(192.168.0.5)
# ルートユーザに切り替え
su -
# httpdをインストール
dnf install -y httpd
# httpdを有効化
systemctl enable --now httpd
systemctl is-active httpd
# http用のポートを開ける
firewall-cmd --zone=public --add-service=http
firewall-cmd --runtime-to-permanent
# Webサーバ1のテストファイルを配置
echo "Hello Server1" >> /var/www/html/test.html
同じようにWebサーバ2を構築します。
# Webサーバ2にApacheをインストール(192.168.0.6)
# ルートユーザに切り替え
su -
# httpdをインストール
dnf install -y httpd
# httpdを有効化
systemctl enable --now httpd
systemctl is-active httpd
# http用のポートを開ける
firewall-cmd --zone=public --add-service=http
firewall-cmd --runtime-to-permanent
# Webサーバ2のテストファイルを配置
echo "Hello Server2" >> /var/www/html/test.html
最後にWebサーバ3を構築します。
# Webサーバ3にApacheをインストール(192.168.0.7)
# ルートユーザに切り替え
su -
# httpdをインストール
dnf install -y httpd
# httpdを有効化
systemctl enable --now httpd
systemctl is-active httpd
# http用のポートを開ける
firewall-cmd --zone=public --add-service=http
firewall-cmd --runtime-to-permanent
# Webサーバ3のテストファイルを配置
echo "Hello Server3" >> /var/www/html/test.html
これでWebサーバが3台構築できました。
クライアント端末からそれぞれ以下のURLでアクセスしてみましょう。
http://192.168.0.5/test.html
http://192.168.0.6/test.html
http://192.168.0.7/test.html
以下のような画面がそれぞれ表示されます。
どのサーバに振り分けられているか分かるように「Hello Server」の後に数値を入れています。
HAProxyを構築
準備ができたので、HAProxyを構築してWebサーバへのアクセスを振り分けてみましょう。
# LBサーバにHAProxyをインストール
su -
dnf install -y haproxy
# HAProxyの設定ファイルhaproxy.cfgを作成する
cd /etc/haproxy/
mv haproxy.cfg haproxy.cfg.org
vi haproxy.cfg
設定ファイルを作成します。ここでは以下のように記述しました。
global
log /dev/log local0
maxconn 2048 # 同時接続数の上限(2048接続まで受け付ける)
daemon
defaults
log global
mode http # HTTPモードで動作
option httplog
timeout connect 5s # バックエンドサーバへの接続タイムアウト
timeout client 50s # クライアントとの通信タイムアウト
timeout server 50s # サーバとの通信タイムアウト
frontend http_front
bind *:80 # ポート80(HTTP)でリクエストを待ち受け
default_backend web_back
backend web_back
balance roundrobin # 負荷分散方式:ラウンドロビン。接続を順番にサーバへ振り分けます。
# 以下サーバ名:web01~3、接続先:192.168.0.5~7:80。checkでヘルスチェック(死活監視)を有効化
server web01 192.168.0.5:80 check
server web02 192.168.0.6:80 check
server web03 192.168.0.7:80 check
設定ファイルが作成できたらサービスを起動させて動作確認してみましょう。
# 設定ファイルの読み込み権限変更
chmod 600 /etc/haproxy/haproxy.cfg
# haproxyサービスの起動
systemctl enable --now haproxy
systemctl is-active haproxy
# ポートの設定(haproxyサービスを外部から利用できるようにする)
firewall-cmd --zone=public --add-service=http
firewall-cmd --runtime-to-permanent
以下にアクセスしてF5を何度か叩いてみましょう。
Webサーバ1~3へと順番に振り分けられていることが確認できるかと思います。
http://192.168.0.100/test.html
Webサーバ3を停止した状態で振り分けはどうなるか確認してみよう
Webサーバ3のhttpdサービスを停止してみましょう。
# Webサーバ3で以下を実行
systemctl stop httpd
再度以下にアクセスしてF5を何度か叩いてみると、
Webサーバ3は表示されずに1と2が交互に表示されることが確認できるかと思います。
これでサーバ3に異常が発生した場合もサービスを継続することができます。
http://192.168.0.100/test.html
確認ができたらWebサーバ3を起動しておきましょう。
systemctl start httpd
統計情報を確認してみよう
HAProxyの統計情報を確認してみましょう。
統計情報を確認するにはhaproxy.cfgを変更する必要があります。
今回はこのタイミングで変更を入れますが、構築のタイミングでこの設定を入れておいて問題ありません。
# haproxy.cfgファイルを編集
cd /etc/haproxy/
vi haproxy.cfg
global
log /dev/log local0
maxconn 2048
daemon
defaults
log global
mode http
option httplog
timeout connect 5s
timeout client 50s
timeout server 50s
frontend http_front
bind *:80
default_backend web_back
backend web_back
balance roundrobin
server web01 192.168.0.5:80 check
server web02 192.168.0.6:80 check
server web03 192.168.0.7:80 check
# 以下を追加
stats enable # 統計画面の有効化
stats hide-version # HAPorxyバージョン表示を隠す
stats uri /stats # /statsでアクセス
stats auth haproxyadmin:password1234 # 認証情報
変更したらサービスの再起動が必要です。
# haproxyを再起動
systemctl restart haproxy
以下にアクセスして統計情報を確認してみましょう。
http://192.168.0.100/stats
認証を求められるので、コンフィグに入力している認証情報を入力しましょう。
ログインすると以下のような統計情報を見ることができます。
Webサーバに何度か接続して、統計情報がどのように変化するか確認してみてください。
http://192.168.0.100/test.html
HAProxyを冗長化しよう
これでWebサーバの冗長化をすることができました。
しかし、HAProxyがダウンしたら結局Webサーバへのアクセスができなくなってしまいます。
そこでHAProxyを冗長化してさらに可用性を高めてみましょう。
ここでは以下のような構成を構築していきます。
これでマスター側のHAProxyがダウンしてもバックアップがその役割を引き継ぐので、継続してWebサーバにアクセスできます。
┌──────────────┐
│ Client │
└──────┬───────┘
│
│ HTTPアクセス
▼
┌────────────────────┐
│ VIP: 192.168.0.100 │
│ 仮想IP(VRRPで浮動) │
└─────────┬──────────┘
│
┌─────────────────┴────────────────────┐
│ │
┌───────────────────┐ ┌──────────────────┐
│ MASTER-Node │ │ BACKUP-Node │
│ 192.168.0.98 │ │ 192.168.0.99 │
└─────────┬─────────┘ └─────────┬────────┘
│ │
│ │
│ │
┌────────▼──────────┐ ┌────────▼──────────┐
│ Web01:192.168.0.5 │ │ Web02:192.168.0.5 │
│ Web02:192.168.0.6 │ │ Web02:192.168.0.6 │
│ Web03:192.168.0.7 │ │ Web03:192.168.0.7 │
└───────────────────┘ └───────────────────┘
| 項目 | HAProxyサーバ1号 | HAProxyサーバ2号 | Webサーバ1号 | Webサーバ2号 | Webサーバ3号 |
|---|---|---|---|---|---|
| OS | AlmaLinux9.6 | AlmaLinux9.6 | AlmaLinux9.6 | AlmaLinux9.6 | AlmaLinux9.6 |
| IPアドレス | 192.168.0.98 | 192.168.0.99 | 192.168.0.5 | 192.168.0.6 | 192.168.0.7 |
| サービス | haproxy,keepalived | haproxy,keepalived | httpd | httpd | httpd |
VIPで192.168.0.100を利用するので、まずは、現在のHAProxyのIPを変更しておく必要があります。
ここでは100番を98番に変更します。
# NICを確認
nmcli connection show
# 以下出力からNICはenp0s3であることを確認
NAME UUID TYPE DEVICE
enp0s3 17a9eb31-fd19-3a34-9363-543658acef14 ethernet enp0s3
lo d37ec84e-d42a-47ed-abbd-b6c0a68cc006 loopback lo
# IPを変更(各々の環境に合わせて変更)
nmcli connection modify enp0s3 ipv4.method manual ipv4.addresses 192.168.0.98/24 ipv4.gateway 192.168.0.1 ipv4.dns "192.168.0.1"
nmcli connection up enp0s3
マスターの環境構築
それでは準備ができたので、まずはマスターの環境を構築していきましょう。
# マスター側の設定(192.168.0.98)
# keepalivedをインストール
dnf install -y keepalived
# 設定ファイルの記述
cd /etc/keepalived
mv keepalived.conf keepalived.conf.org
vi keepalived.conf
マスターの設定ファイルは以下のように記述しています。
vrrp_script chk_haproxy{
script
interval
weight
}
vrrp_instance VI_1 {
interface enp0s3 # 対象のNICを入力
state MASTER
virtual_router_id 51
priority 101 # priorityを入力(大きいほうが優先)
virtual_ipaddress {
192.168.0.100/24 # Virtual IP
}
track_script{
chk_haproxy
}
}
Keepalivedでは、VRRPを使って冗長化構成を実現するので、
HAProxyサーバの1号機と2号機の両方で、VRRPによる疎通を有効化する必要があります。
# VRRPの疎通を有効化
firewall-cmd --zone=public --add-rich-rule='rule protocol value="vrrp" accept'
firewall-cmd --runtime-to-permanent
# keepalivedサービスを有効化
systemctl enable --now keepalived
systemctl is-active keepalived
バックアップの環境構築
続いてバックアップサーバの設定をしていきましょう。
まずはHAProxyをセットアップします。
# HAProxyを構築(192.168.0.99)
su -
dnf install -y haproxy
cd /etc/haproxy/
mv haproxy.cfg haproxy.cfg.org
# scpで設定ファイルを持ってくる
scp -p root@192.168.0.100:/etc/haproxy/haproxy.cfg /etc/haproxy/
# 設定ファイルの読み込み権限変更
chmod 600 /etc/haproxy/haproxy.cfg
# サービスの起動
systemctl enable --now haproxy
systemctl is-active haproxy
# ポートの設定(haproxyサービスを外部から利用できるようにする)
firewall-cmd --zone=public --add-service=http
firewall-cmd --runtime-to-permanent
続いてkeepalivedをインストールします。
# バックアップ側の設定(192.168.0.99)
# keepalivedをインストール
dnf install -y keepalived
# 設定ファイルの記述
cd /etc/keepalived
mv keepalived.conf keepalived.conf.org
vi keepalived.conf
バックアップの設定ファイルは以下のように記述しています。
vrrp_script chk_haproxy{
script
interval
weight
}
vrrp_instance VI_1 {
interface enp0s3 # 対象のNICを入力
state BACKUP
virtual_router_id 51
priority 100 # priorityを入力(マスターより小さい値を設定)
virtual_ipaddress {
192.168.0.100/24 # Virtual IP
}
track_script{
chk_haproxy
}
}
VRRPによる疎通を有効化してkeepalivedサービスを起動する。
firewall-cmd --zone=public --add-rich-rule='rule protocol value="vrrp" accept'
firewall-cmd --runtime-to-permanent
systemctl enable --now keepalived
systemctl is-active keepalived
まずは、ロードバランシング状態を確認してみましょう。
以下のページにアクセスして負荷分散されることを確認します。
http://192.168.0.100/test.html
今までと同様にWebサーバが振り分けられていることを確認できます。
HAProxyの冗長化を確認しよう
では本題です。HAProxyが冗長化できているか確認しましょう。
マスター側のHAProxyを停止してみます。
# 以下のコマンドを実行後にブラウザでアクセスしてみる
killall haproxy
ブラウザにアクセスして正常に表示されることを確認しましょう。
http://192.168.0.100/test.html
切り替わりの発生によりブラウザの読み込みに多少時間がかかります。
これでHAProxyも冗長化することができました。
終わりに
HAProxyを構築してロードバランサについて学習しました。
机上で学習するだけでなく実機で動きを確認することで知識がさらに身になると思います。
ここではラウンドロビンの振り分けを試しましたがほかにも接続数が少ない順に振り分けたり、クライアントIPごとに振り分ける方法があります。様々な設定を試してみましょう。





