Keepalived + HAProxy を用いた高可用ロードバランシングの構築

現代インターネットアーキテクチャにおいて、高可用性はシステム設計における重要な検討事項です。本稿では、KeepalivedとHAProxyを使用して高可用なロードバランシングクラスタを構築し、サービスの継続性と信頼性を確保する方法について詳細に解説します。

実際の構成部分が検証されていないため、本文の構成はAIによって作成されています

この画像は「タスク計画」というタイトルで、おそらくタスクのスケジュールやリストを示していると思われます。詳細な翻訳のためには画像の具体的な内容を確認する必要がありますが、一般的な表現として以下のように記述できます。

タスク計画 (Tasukku Keikaku) - 任務計画 (Tanmoku Keikaku)

技術概要

Keepalived の概要

Keepalived は、VRRP(Virtual Router Redundancy Protocol)プロトコルを基盤とした高可用性ソリューションであり、主にサーバーのフェイルオーバーとロードバランシングを実現するために使用されます。

主な特徴:

  • VRRP プロトコル対応: 仮想IPアドレスの主/備切り替えの実装
  • 健康チェック: サービスの状態を監視し、自動的に故障トランスファーを実行
  • 設定の簡素化: 設定ファイルのみで複雑な高可用性アーキテクチャを実現
  • 軽量: リソース消費量が少なく、性能に優れている

動作原理: Keepalived は、VRRP プロトコルを通じて複数のサーバー間で仮想IPアドレスを共有します。正常時には、主サーバーが仮想IPアドレスを持ちサービスを提供し、主サーバーが故障した場合、備サーバーが自動的に仮想IPアドレスを接管し、サービスの停止を防ぎます。

HAProxy の概要

HAProxy は、高性能なロードバランサーおよびリバースプロキシサーバーであり、高負荷環境で広く利用されています。 主な機能:

  • ロードバランシング: 複数のロードバランシングアルゴリズムをサポート
  • ヘルスチェック: バックエンドサーバーの状態をリアルタイムに監視
  • SSL終端: HTTPS トラフィックの処理をサポート
  • 統計モニタリング: 詳細な実行状態の統計情報を提供 利用シーン:
  • Web サービス のロードバランシング
  • データベース接続プーリング
  • マイクロサービスゲートウェイ
  • API インターフェース のプロキシ

アーキテクチャ設計

全体アーキテクチャ

                    ┌─────────────────┐
                    │   Client        │
                    └─────────┬───────┘
                              │
                    ┌─────────▼───────┐
                    │  Virtual IP     │
                    │  (VIP)          │
                    └─────────┬───────┘
                              │
              ┌───────────────┼───────────────┐
              │               │               │
    ┌─────────▼───────┐              ┌─────────▼───────┐
    │   HAProxy-1     │              │   HAProxy-2     │
    │  (Master)       │◄────────────►│   (Backup)      │
    │  + Keepalived   │   VRRP       │  + Keepalived   │
    └─────────┬───────┘              └─────────┬───────┘
              │                                │
              └──────────┬─────────────────────┘
                         │
        ┌────────────────┼────────────────┐
        │                │                │
┌───────▼───────┐ ┌──────▼──────┐ ┌───────▼───────┐
│  Web Server 1 │ │ Web Server 2│ │  Web Server 3 │
│   Backend     │ │   Backend   │ │   Backend     │
└───────────────┘ └─────────────┘ └───────────────┘

全体アーキテクチャ

                    ┌─────────────────┐
                    │   クライアント        │
                    └─────────┬───────┘
                              │
                    ┌─────────▼───────┐
                    │  仮想IP (VIP)       │
                    └─────────┬───────┘
                              │
              ┌───────────────┼───────────────┐
              │               │               │
    ┌─────────▼───────┐              ┌─────────▼───────┐
    │   HAProxy-1     │              │   HAProxy-2     │
    │  (マスター)       │◄────────────►│   (バックアップ)      │
    │  + Keepalived   │   VRRP       │  + Keepalived   │
    └─────────┬───────┘              └─────────┬───────┘
              │                                │
              └──────────┬─────────────────────┘
                         │
        ┌────────────────┼────────────────┐
        │                │                │
┌───────▼───────┐ ┌──────▼──────┐ ┌───────▼───────┐
│  Web Server 1 │ │ Web Server 2│ │  Web Server 3 │
│   バックエンド     │ │   バックエンド   │ │   バックエンド     │
└───────────────┘ └─────────────┘ └───────────────┘

コンポーネントの説明

  • 仮想IP (VIP): 顧客がアクセスする統一的なエントリポイント
  • HAProxy 主備ノード: ロードバランシングサービスを提供し、Keepalivedを使用して高可用性を実現します
  • バックエンドサーバー: 実際にサービスを提供するWebサーバー

環境準備

サーバ計画

役割 IPアドレス ホスト名 サービス
HAProxy 主ノード 192.168.1.10 lb-master HAProxy + Keepalived

サーバ計画

役割 IPアドレス ホスト名 サービス
HAProxy 備後端 192.168.1.11 lb-backup HAProxy + Keepalived

サーバー構成

ロール IPアドレス ホスト名 サービス
仮想IP 192.168.1.100 - VIP

サーバー計画

役割 IPアドレス ホスト名 サービス
Webサーバー1 192.168.1.20 web1 Nginx/Apache

サーバー構成

ロール IPアドレス ホスト名 サービス
Webサーバー2 192.168.1.21 web2 Nginx/Apache

サーバー計画

ロール IPアドレス ホスト名 サービス
Webサーバー3 192.168.1.22 web3 Nginx/Apache

ソフトウェアのインストール

HAProxy主備サーバに必要ソフトウェアをインストールします:

# CentOS/RHEL
yum install -y haproxy keepalived

# Ubuntu/Debian
apt-get update
apt-get install -y haproxy keepalived

# サービスを起動時に自動開始にする
systemctl enable haproxy keepalived

Keepalived 設定

主ノード設定 (lb-master)

/etc/keepalived/keepalived.conf ファイルを作成します:

! Configuration File for keepalived

global_defs {
    router_id LB_MASTER
    script_user root
    enable_script_security
}

# HAProxyサービスのステータスを確認するスクリプト
vrrp_script chk_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 2
    weight -2
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass mypassword123
    }

    virtual_ipaddress {
        192.168.1.100/24
    }

    track_script {
        chk_haproxy
    }

    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

備中节点配置 (lb-backup)

/etc/keepalived/keepalived.conf ファイルを作成します:

! keepalived の構成ファイル

global_defs {
    router_id LB_BACKUP
    script_user root
    enable_script_security
}

vrrp_script chk_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 2
    weight -2
    fall 3
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass mypassword123
    }

    virtual_ipaddress {
        192.168.1.100/24
    }

    track_script {
        chk_haproxy
    }

    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

HAProxy健康チェックスクリプト

/etc/keepalived/check_haproxy.shというHAProxyの健康チェックスクリプトを作成します:

#!/bin/bash

# HAProxyプロセスが実行中か確認
if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then
    # HAProxyを起動を試行
    systemctl start haproxy
    sleep 2

    # 再度チェックし、まだ実行されていない場合は終了
    if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then
        exit 1
    fi
fi

# HAProxyポートがリッスン中か確認
if ! netstat -tuln | grep -q ":80 "; then
    exit 1
fi

exit 0

状態通知スクリプト

/etc/keepalived/notify.sh という状態通知スクリプトを作成します:

#!/bin/bash

TYPE=$1
NAME=$2
STATE=$3

case $STATE in
    "MASTER")
        echo "$(date): Became MASTER" >> /var/log/keepalived-state.log
        ;;
    "BACKUP")
        echo "$(date): Became BACKUP" >> /var/log/keepalived-state.log
        ;;
    "FAULT")
        echo "$(date): Fault detected" >> /var/log/keepalived-state.log
        ;;
    *)
        echo "$(date): Unknown state: $STATE" >> /var/log/keepalived-state.log
        ;;
esac

スクリプトの実行権限を設定します:

chmod +x /etc/keepalived/check_haproxy.sh
chmod +x /etc/keepalived/notify.sh

HAProxy 設定

メイン設定ファイル

主備ノード上で同じHAProxyの設定ファイル /etc/haproxy/haproxy.cfg を作成します:

global
    log 127.0.0.1:514 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
    log global
    option httplog
    option dontlognull
    option log-health-checks
    option forwardfor except 127.0.0.0/8
    option redispatch
    retries 3
    timeout http-request 10s
    timeout queue 1m
    timeout connect 10s
    timeout client 1m
    timeout server 1m
    timeout http-keep-alive 10s
    timeout check 10s
    maxconn 3000

# ページ設定の統計
listen stats
    bind *:8080
    stats enable
    stats uri /stats
    stats realm HAProxy\ Statistics
    stats auth admin:password123
    stats refresh 30s

# 前端設定
frontend web_frontend
    bind *:80
    default_backend web_servers

# 後端サーバー設定
backend web_servers
    balance roundrobin
    option httpchk GET /health
    
    server web1 192.168.1.20:80 check inter 2000 rise 2 fall 3
    server web2 192.168.1.21:80 check inter 2000 rise 2 fall 3
    server web3 192.168.1.22:80 check inter 2000 rise 2 fall 3

設定手順

グローバル設定:

  • log: 日志設定
  • chroot: セーフティサンドボックス
  • stats socket: 管理インターフェース
  • daemon: バックグラウンド実行 デフォルト設定:
  • mode http: HTTPモード
  • balance roundrobin: ラウンドロビンバランシング
  • option httpchk: HTTPヘルスチェック
  • timeout: 様々なタイムアウト設定 バックエンドサーバー:
  • check: ヘルスチェックを有効にする
  • inter 2000: チェック間隔2秒
  • rise 2: 連続2回成功した場合に可用とマークする
  • fall 3: 連続3回失敗した場合に不可用とマークする

サービス開始とテスト

サービスの起動

主節点および副節点上でサービスを起動します:

# HAProxyの起動
systemctl start haproxy
systemctl status haproxy

# Keepalivedの起動
systemctl start keepalived
systemctl status keepalived

VIP認証の確認

仮想IPが正しくバインドされているかを確認します:

# 主ノードでIPアドレスを表示
ip addr show

# 以下の様な出力が表示されるはずです:
# eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
#     inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0
#     inet 192.168.1.100/24 scope global secondary eth0:0

機能テスト

1. 負荷分散テスト

# VIPに複数回アクセスし、リクエストの分配状況を監視
for i in {1..10}; do
    curl -s http://192.168.1.100/ | grep "Server"
done

2. フェイルオーバーテスト

# 主ノードでHAProxyサービスを停止する
systemctl stop haproxy

# VIPがバックノードに切り替わるのを監視する
ip addr show

# サービスの正常性を確認する
curl http://192.168.1.100/

3. バックエンドサーバー障害テスト

# 一台のWebサーバーを停止する
# web1サーバーで:
systemctl stop nginx

# HAProxy統計ページを監視する
curl http://192.168.1.100:8080/stats

モニタリングとメンテナンス

ロギング監視

HAProxyログ

# HAProxyログの確認
tail -f /var/log/haproxy.log

# アクセス統計の確認
grep "HTTP/1.1" /var/log/haproxy.log | tail -20

Keepalivedログ

# Keepalivedログの確認
tail -f /var/log/messages | grep keepalived

# 状態変化ログの確認
tail -f /var/log/keepalived-state.log

パフォーマンス監視

統計ページ監視

HAProxyの統計ページへのアクセス: http://192.168.1.100:8080/stats 主要指標:

  • Session Rate: 会話レート
  • Session Total: 総会話数
  • Bytes In/Out: 流量統計
  • Response Time: 応答時間
  • Server Status: サーバー状態

コマンドライン監視

# HAProxyプロセスの状態を確認
ps aux | grep haproxy

# ポートのリスニング状態を確認
netstat -tuln | grep -E "(80|8080)"

# 接続数を確認
ss -ant | grep :80 | wc -l

よくあるトラブルシューティング

1. VIPの切り替え不可

問題現象: 主ノード故障後、VIPがバックアップノードに切り替わらない トラブルシューティング手順:

# Keepalived設定を確認
keepalived -t -f /etc/keepalived/keepalived.conf

# VRRP通信を監視
tcpdump -i eth0 vrrp

# ファイアウォール設定を確認
iptables -L | grep vrrp

解決策:

  • VRRPプロトコル通信が正常であることを確認
  • ネットワークインターフェースの設定を確認
  • 認証パスワードの一致性を検証

2. 健康チェック失敗

問題現象: バックエンドサーバーが利用不可としてマークされている トラブルシューティング手順:

# 手動で健康チェックを実行
curl -I http://192.168.1.20/health

# HAProxyログを確認
grep "Health check" /var/log/haproxy.log

解決策:

  • 健康チェックURLにアクセス可能であることを確認
  • チェック間隔と閾値を調整
  • バックエンドサーバーの状態を確認

3. 負荷分散の不均衡

問題現象: リクエストがバックエンドサーバーに均等に分散されない トラブルシューティング手順:

# 統計ページを確認
curl -s http://192.168.1.100:8080/stats

# アクセスログを分析
awk '{print $6}' /var/log/haproxy.log | sort | uniq -c

解決策:

  • 負荷分散アルゴリズムの設定を確認
  • サーバーの重み設定を検証
  • セッション保持の要件を考慮

オプティマイズの提案

1. パフォーマンス最適化

# システムパラメータの調整
echo 'net.core.somaxconn = 65535' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_max_syn_backlog = 65535' >> /etc/sysctl.conf
sysctl -p

# HAProxy設定の最適化
# maxconn値を増やす
# timeoutパラメータを調整する
# 圧縮機能を有効にする

2. セキュリティ強化

# 統計ページへのアクセス制限
# haproxy.cfg に ACL ルールを追加
acl allowed_ips src 192.168.1.0/24
http-request deny if !allowed_ips

# SSL/TLS の有効化
bind *:443 ssl crt /etc/ssl/certs/server.pem
redirect scheme https if !{ ssl_fc }

3. モニタリングとアラート

# 統合監視システム
# Prometheusによる監視設定
# Grafanaダッシュボードの設定
# アラートルールを設定

結論

KeepalivedとHAProxyの組み合わせにより、高可用性を持つロードバランシングクラスタを構築しました。この構成には以下の利点があります。

  1. 高可用性: VRRPプロトコルによる自動フェイルオーバーを実現
  2. ロードバランシング: スマートなリクエスト分散により、システム性能を向上
  3. 健康チェック: リアルタイムでサービスの状態を監視し、故障ノードを自動的に除外
  4. メンテナンスの容易さ: 設定が簡単で、管理も容易
  5. コスト効率: オープンソースソフトウェアを使用することで、運用コストを削減 本番環境へのデプロイ時には、ネットワークセキュリティ、監視アラート、バックアップとリカバリなどの面での整備が必要であり、システムの安定性と信頼性を確保します。
金融ITプログラマーのいじくり回しと日常のつぶやき
Hugo で構築されています。
テーマ StackJimmy によって設計されています。