クライアントからの通信を受け付け、L4レベルの負荷分散を行うHAProxyの設定を説明します。

本設定を適用するケースは、DMZや社内サーバファームに設置しているサーバに対して、L7レベルのアプリケーションプロキシは行わず、L4レベルのシンプルな負荷分散を想定しています。

前提条件

  • 基本設定が完了している状態から設定を行います。
  • 作業は、root権限を持つユーザで実施します。
  • OSおよびHAProxyは、以下のバージョンで検証しています。
# cat /etc/redhat-release 
CentOS Linux release 8.0.1905 (Core) 
# uname -r
4.18.0-80.el8.x86_64
# haproxy -v
HA-Proxy version 1.8.15 2018/12/13
Copyright 2000-2018 Willy Tarreau 

機能要件

本設定で実現する機能は以下の通りです。

  • クライアントからのHTTPリクエストパケットを、HAProxyが動作するサーバ(以下ロードバランサ)の仮想サーバIPアドレスで受信する
  • ロードバランサは、HTTPリクエストパケットの宛先IPアドレスを書き換え、2台のWebサーバに転送する
  • Webサーバへの負荷分散方式は、ラウンドロビン(順番に振り分け)を使用する
  • WebサーバはクライアントのIPアドレス宛に、HTTPレスポンスパケットを送信する
  • ロードバランサは、Webサーバから受信したHTTPレスポンスパケットの送信元IPアドレスを仮想サーバIPアドレスに書き換え、クライアントへパケットを転送する

事前作業

デフォルト設定ファイルのバックアップ

以下のコマンドを実行し、デフォルトの設定ファイルの名前を変更してバックアップします。

# mv /etc/haproxy/haproxy.cfg{,.`date +%Y%m%d`}

設定手順

デフォルトの設定ファイルは不要な設定項目が多く、いちいちコメントアウトしていくと煩雑であるため、今回は新たに作成します。
viなどのテキストエディタで、HAProxyの設定ファイルを開きます。

# vi /etc/haproxy/haproxy.cfg

globalセクションの設定

HAProxy全体で使用するパラメータを指定するglobalセクションの設定は以下の通りです。
maxconnは、サーバのスペックに合わせて適宜チューニングしてください。

#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # ログ出力先
    log         127.0.0.1 local2
    # HAProxy実行ユーザのchrootディレクトリ
    chroot      /var/lib/haproxy
    # PIDファイル
    pidfile     /var/run/haproxy.pid
    # HAProxy全体の最大同時接続数
    maxconn     4000
    # HAProxyの実行ユーザ、グループ
    user        haproxy
    group       haproxy
    # プロセス常駐モード
    daemon
    # 統計情報ソケットファイル
    stats socket /var/lib/haproxy/stats

resolversセクションの設定

後述するバックエンドで使用する、名前解決先DNSサーバを指定するresolversセクションの設定は以下の通りです。
internal-dnsの箇所には、任意のDNSサーバグループ名を指定します。
ns1 / ns2の部分には、任意のDNSサーバ名を指定します。
10.0.10.10:53 / 10.0.10.11:53の部分には、名前解決先DNSサーバのIPアドレスとポート番号を指定します。

#---------------------------------------------------------------------
# Resolverss settings
#---------------------------------------------------------------------
# 名前解決先DNSサーバグループ
# バックエンドの物理サーバを名前解決する場合に必要
resolvers internal-dns
  nameserver ns1 10.0.10.10:53
  nameserver ns2 10.0.10.11:53

defaultsセクションの設定

後述のフロントエンドやバックエンドの共通パラメータを指定するdefaultsセクションの設定は以下の通りです。
maxconnおよびtimeout 〜は、サーバのスペックに合わせて適宜チューニングしてください。

#---------------------------------------------------------------------
# Defaults settings
#---------------------------------------------------------------------
defaults
    ### フロントエンドに関する共通設定
    # 使用するログ定義
    log                     global
    # フロントエンド単位の最大同時接続数
    maxconn                 3000
    # 最大接続数を超過した場合に滞留した接続キューのタイムアウト時間
    timeout queue           1m
    # クライアントからHAProxyに対するTCPコネクション確立後のタイムアウト時間
    timeout client          1m

    ### バックエンドに関する共通設定
    # HAProxyから物理サーバに対するTCPコネクション接続時のタイムアウト時間
    timeout connect         10s
    # HAProxyから物理サーバに対するTCPコネクション確立後のタイムアウト時間
    timeout server          1m
    # 物理サーバのヘルスチェックタイムアウト時間
    timeout check           10s

frontendセクションの設定

クライアントからの通信を受け付けるパラメータを指定するfrontendセクションの設定は以下の通りです。
今回は、ft-webというWebサーバ用のフロントエンドが1つ定義されているだけですが、フロントエンドは複数定義できます。

#---------------------------------------------------------------------
# Frontend settings
#---------------------------------------------------------------------
frontend ft-web
    # L4モード
    mode tcp
    # 通信を受け付けるIPアドレスとポート番号
    bind *:80
    # 負荷分散先物理サーバグループ
    default_backend bk-web

backendセクションの設定

負荷分散先物理サーバに関するパラメータを指定するbackendセクションの設定は以下の通りです。
今回は、bk-webというWebサーバ用のバックエンドが1つ定義されているだけですが、バックエンドは複数定義できます。
serverは1行が長いですが、以下のようにパラメータを指定します。

server <物理サーバ名> <FQDNまたはIPアドレス>:<TCPポート番号> resolvers <resolvers名> check inter <ヘルスチェック間隔> rise <正常とみなすヘルスチェック連続成功回数> fall <異常とみなすヘルスチェック連続失敗回数>

#---------------------------------------------------------------------
# Backend settings
#---------------------------------------------------------------------
backend bk-web
    # 負荷分散方式
    balance roundrobin
    # 負荷分散先物理サーバの宛先とヘルスチェック設定
    # resolvers: 物理サーバFQDNの名前解決先DNSサーバグループ
    # check: ヘルスチェックの有効化
    # inter: ヘルスチェック間隔
    # rise: 物理サーバが正常と判定するヘルスチェックの連続成功回数
    # fall: 物理サーバが異常と判定するヘルスチェックの連続失敗回数
    server web01 web01.densan-hoshigumi.com:80 resolvers internal-dns check inter 3s rise 5 fall 3
    server web02 web02.densan-hoshigumi.com:80 resolvers internal-dns check inter 3s rise 5 fall 3

ファイアウォールの設定

firewalldが有効な場合は、フロントエンドで設定したポートの通信許可設定を行います。
今回はTCP/80をフロントエンドとして設定したので、firewalldに標準で用意されているhttpサービスを使用します。

# firewall-cmd --permanent --zone=public --add-service=http
success
# firewall-cmd --reload
success

設定内容の確認

以下のコマンドを実行し、設定ファイルの文法に問題がないか確認します。
文法が正しければ、Configuration file is validが表示されます。

# /usr/sbin/haproxy -c -V -f /etc/haproxy/haproxy.cfg 
Configuration file is valid

設定の反映

以下のコマンドを実行し、haproxyサービスを再起動して設定を反映します。

# systemctl restart haproxy

以下のコマンドを実行し、haproxyサービスが起動状態であることを確認します。
Active:の列にactive (running)が表示されていれば、サービスは起動中です。

# systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
   Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2020-01-19 21:33:05 EST; 4s ago
(略)

以上で、HAProxyのL4負荷分散設定は完了です。