HAProxy

高性能TCP/HTTPロードバランサー。高可用性、負荷分散、プロキシ機能を提供。毎秒数万の同時接続を処理。詳細な統計とモニタリング機能。

ロードバランサープロキシ高可用性負荷分散SSL終端TCPHTTPヘルスチェック

サーバー

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