HAProxy
高性能TCP/HTTPロードバランサー。高可用性、負荷分散、プロキシ機能を提供。毎秒数万の同時接続を処理。詳細な統計とモニタリング機能。
サーバー
HAProxy
概要
HAProxyは「高可用性、負荷分散、プロキシ」を意味する略語で、世界で最も使用されているオープンソースロードバランサーの一つです。TCP/HTTPレベルでの高性能負荷分散・プロキシソリューションとして、毎秒数万の同時接続を処理できる能力を持ち、世界最大級のWebサイトで採用されています。シンプルかつ明確な設定構文、詳細な統計・監視機能、高度なヘルスチェック機能により、ミッションクリティカルな環境での運用に最適化されています。
詳細
HAProxyは2000年にWilly Tarreauによって開発が開始され、20年以上の歴史を持つ成熟したロードバランサーです。現在のバージョン3.1では、HTTP/2、HTTP/3(QUIC)、WebSocket、gRPC等のモダンプロトコルを完全サポートし、マイクロサービスアーキテクチャにも対応しています。イベント駆動型の非ブロッキングI/Oアーキテクチャにより、限られたメモリ使用量で大量の同時接続を効率的に処理できます。設定ファイルベースの宣言的設定により、Dockerコンテナ、Kubernetes、オンプレミス環境での運用が可能です。
主な特徴
- 高性能アーキテクチャ: イベント駆動型の単一プロセス設計で最大性能を実現
- 豊富な負荷分散アルゴリズム: ラウンドロビン、最小接続数、一貫性ハッシュ等をサポート
- 高度なヘルスチェック: HTTP、TCP、SSL、カスタムチェックによる詳細な監視
- SSL/TLS完全対応: 証明書管理、SNI、OCSP stapling、セキュアプロトコル対応
- 詳細な統計・監視: リアルタイム統計、管理インターフェース、Prometheus連携
- ゼロダウンタイム設定再読み込み: 無停止での設定変更とプロセス置き換え
メリット・デメリット
メリット
- 業界標準として確立された信頼性と実績(Amazon、GitHub、Reddit等で採用)
- 極めて高いパフォーマンスと低いメモリ使用量
- 柔軟で強力な設定システムとACL(アクセス制御リスト)機能
- 豊富なドキュメントとコミュニティサポート
- 商用サポート(HAProxy Enterprise)による企業向けサービス
- Kubernetesエコシステムとの統合(HAProxy Ingress Controller)
デメリット
- 設定ファイルの学習コストが高く、複雑な構成では可読性が低下する可能性
- ダイナミック設定変更にはリロードが必要(ただし無停止)
- Web UI管理画面が限定的(サードパーティツールの使用を推奨)
- 高度な機能の一部は商用版(HAProxy Enterprise)でのみ利用可能
- 初期設定時のパフォーマンスチューニングに専門知識が必要
- モダンなサービスメッシュ機能には追加の統合作業が必要
参考ページ
書き方の例
インストールと基本設定
# Ubuntu/Debian
sudo apt update
sudo apt install haproxy
# CentOS/RHEL
sudo yum install haproxy
# ソースからのビルド
wget https://www.haproxy.org/download/3.1/src/haproxy-3.1.0.tar.gz
tar -xzf haproxy-3.1.0.tar.gz
cd haproxy-3.1.0
make TARGET=linux-glibc USE_OPENSSL=1 USE_PCRE=1 USE_SYSTEMD=1
sudo make install
# サービス有効化・開始
sudo systemctl enable haproxy
sudo systemctl start haproxy
基本的な負荷分散設定
# /etc/haproxy/haproxy.cfg
global
log stdout local0
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
# Webフロントエンド
frontend web_frontend
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/
redirect scheme https if !{ ssl_fc }
# ACL定義
acl is_api path_beg /api/
acl is_static path_end .css .js .png .jpg .gif .ico
# バックエンド振り分け
use_backend api_servers if is_api
use_backend static_servers if is_static
default_backend web_servers
# Webサーバープール
backend web_servers
balance roundrobin
option httpchk GET /health
http-check expect status 200
server web1 192.168.1.10:80 check
server web2 192.168.1.11:80 check
server web3 192.168.1.12:80 check backup
# APIサーバープール
backend api_servers
balance leastconn
option httpchk GET /api/health
http-check expect string "healthy"
server api1 192.168.1.20:8080 check inter 2s rise 2 fall 3
server api2 192.168.1.21:8080 check inter 2s rise 2 fall 3
server api3 192.168.1.22:8080 check inter 2s rise 2 fall 3
# 静的コンテンツサーバー
backend static_servers
balance uri
hash-type consistent
server static1 192.168.1.30:80 check
server static2 192.168.1.31:80 check
SSL終端とセキュリティ設定
# SSL設定
global
ssl-default-bind-ciphers ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:!aNULL:!SHA1:!AESCCM
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
ssl-default-server-ciphers ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:!aNULL:!SHA1:!AESCCM
ssl-default-server-options ssl-min-ver TLSv1.2 no-tls-tickets
# セキュアフロントエンド
frontend secure_frontend
bind *:443 ssl crt-list /etc/haproxy/certs/crt-list.txt alpn h2,http/1.1
# セキュリティヘッダー
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
http-response set-header X-Frame-Options DENY
http-response set-header X-Content-Type-Options nosniff
http-response set-header X-XSS-Protection "1; mode=block"
http-response set-header Content-Security-Policy "default-src 'self'"
# レート制限
stick-table type ip size 100k expire 30s store http_req_rate(10s)
http-request track-sc0 src
http-request reject if { sc_http_req_rate(0) gt 20 }
# 地理的ブロック
acl blocked_countries src -f /etc/haproxy/blocked_countries.lst
http-request reject if blocked_countries
default_backend secure_backend
backend secure_backend
# バックエンドSSL設定
server secure1 192.168.1.40:443 ssl verify required ca-file /etc/haproxy/ca.crt check
server secure2 192.168.1.41:443 ssl verify required ca-file /etc/haproxy/ca.crt check
ヘルスチェックと高可用性設定
# 高度なヘルスチェック
backend advanced_health_backend
option httpchk GET /api/health/deep
http-check expect status 200
http-check expect header Content-Type application/json
http-check expect string "database_ok"
# サーバー設定
server app1 192.168.1.50:8080 check inter 5s downinter 2s rise 3 fall 2 maxconn 500
server app2 192.168.1.51:8080 check inter 5s downinter 2s rise 3 fall 2 maxconn 500
server app3 192.168.1.52:8080 check inter 5s downinter 2s rise 3 fall 2 maxconn 500 backup
# TCP負荷分散(データベース)
listen mysql_cluster
bind *:3306
mode tcp
balance leastconn
option tcplog
option tcp-check
tcp-check connect
tcp-check send-binary 0e000000
tcp-check send-binary 0a353030302e31302e3337000d00000000000000000000000000000000000000000000000000000000
tcp-check expect binary 0000000a
server mysql1 192.168.1.60:3306 check
server mysql2 192.168.1.61:3306 check backup
# Redis Sentinel
listen redis_sentinel
bind *:26379
mode tcp
balance first
option tcp-check
tcp-check send PING\r\n
tcp-check expect string +PONG
server sentinel1 192.168.1.70:26379 check
server sentinel2 192.168.1.71:26379 check
server sentinel3 192.168.1.72:26379 check
統計と監視設定
# 統計ページ設定
listen stats
bind *:8404
stats enable
stats uri /haproxy/stats
stats realm HAProxy\ Statistics
stats auth admin:SecurePassword123
stats admin if TRUE
stats refresh 30s
stats show-legends
stats show-desc HAProxy Load Balancer Statistics
# Prometheus統計エクスポート
frontend prometheus_exporter
bind *:8405
http-request use-service prometheus-exporter if { path /metrics }
http-request return status 404
# ログ設定
global
log 127.0.0.1:514 local0 info
log-tag haproxy
# アクセスログの詳細化
defaults
option httplog
capture request header Host len 32
capture request header User-Agent len 64
capture response header Content-Type len 32
高度な負荷分散とフェイルオーバー
# 重み付きラウンドロビン
backend weighted_backend
balance roundrobin
server app1 192.168.1.80:8080 weight 100 check
server app2 192.168.1.81:8080 weight 50 check
server app3 192.168.1.82:8080 weight 25 check
# 一貫性ハッシュ(セッション維持)
backend session_backend
balance uri whole
hash-type consistent
cookie SERVERID insert indirect nocache
server web1 192.168.1.90:8080 cookie web1 check
server web2 192.168.1.91:8080 cookie web2 check
server web3 192.168.1.92:8080 cookie web3 check
# マルチゾーン構成
backend multi_zone_backend
balance roundrobin
# Zone A (Primary)
server zone_a_1 10.1.1.10:8080 check
server zone_a_2 10.1.1.11:8080 check
# Zone B (Secondary)
server zone_b_1 10.2.1.10:8080 backup check
server zone_b_2 10.2.1.11:8080 backup check
# Zone C (Disaster Recovery)
server zone_c_1 10.3.1.10:8080 backup check
# A/Bテスト設定
frontend ab_test_frontend
bind *:80
# ユーザーの1%をベータ版に振り分け
acl is_beta_user hdr(Cookie) -m sub beta=true
acl random_beta rand(100) lt 1
use_backend beta_backend if is_beta_user or random_beta
default_backend production_backend
backend production_backend
server prod1 192.168.1.100:8080 check
server prod2 192.168.1.101:8080 check
backend beta_backend
server beta1 192.168.1.110:8080 check
server beta2 192.168.1.111:8080 check
管理とメンテナンス
# HAProxyの動作確認
sudo systemctl status haproxy
# 設定ファイルのテスト
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
# 設定リロード(無停止)
sudo systemctl reload haproxy
# 統計ソケット経由での管理
echo "show stat" | sudo socat stdio /run/haproxy/admin.sock
# サーバーを一時的に無効化
echo "disable server web_servers/web1" | sudo socat stdio /run/haproxy/admin.sock
# サーバーを有効化
echo "enable server web_servers/web1" | sudo socat stdio /run/haproxy/admin.sock
# サーバーの重みを変更
echo "set weight web_servers/web1 50%" | sudo socat stdio /run/haproxy/admin.sock
# 設定の確認
echo "show info" | sudo socat stdio /run/haproxy/admin.sock