HAProxyをロードバランサーにしてメンテナンスポートも付けてみた

ありがちな感じですが、HAProxyをロードバランサーにしてみました。
メンテナンスのためにコンソールから操作できるようにし、個別サーバーへのメンテナンス用のポートも設定します。

# 1. 構成
ざっくりとこんな感じですが、個別サーバー用のメンテナンスポートはそれなりにわかりやすい連番が確保できれば何番でも大丈夫です。

| ホスト名 | 内部IP | URL | 説明 |
| -------- | ---------- | -------- | -------- |
| lb | 192.168.10.1 | http://10.0.10.1/ | HAProxyで作ったLB |
| web-01 | 192.168.100.1 | http://10.0.10.1:11001/ | LB対象のWEBサーバー |
| web-02 | 192.168.100.2 | http://10.0.10.1:11002/ | LB対象のWEBサーバー |

# 2. コンソールからの操作
コンソールからの操作をするために、socatコマンドを利用しますのであらかじめインストールしておいてください。
CentOSの場合、EPELからインストールすることが出来ます。

# 3. haproxy.cfg
最低限の設定ですが、ロードバランサー用のwebルールはヘルスチェックをしますが、メンテナンス用のdirect-01/02ルールはステータスが200以外でもHAProxy側で遮断しないようにヘルスチェックはしていません。

```
global
    log              127.0.0.1 local2
    chroot           /var/lib/haproxy
    pidfile          /var/run/haproxy.pid
    maxconn          4000
    user             haproxy
    group            haproxy
    daemon
    stats socket     /tmp/haproxy-cli.sock user root group wheel level admin
    stats maxconn    1
    stats timeout    120s

defaults
    mode             http
    log              global
    option           httplog
    timeout connect  10s
    timeout client   1m
    timeout server   1m

frontend web *:80
    default_backend  web

backend web
    balance          roundrobin
    server           web-01 192.168.100.1:80 check
    server           web-02 192.168.100.2:80 check

listen direct-01
    bind             *:11001
    server           web-01 192.168.100.1:80

listen direct-02
    bind             *:11002
    server           web-02 192.168.100.2:80
````

# 4. アクセスの確認
web-01/02のどちらかが変わるようにドキュメントルートの index.html にそれぞれのホスト名が表示されるように書いておくとわかりやすいです。

| URL | 表示内容 |
| ---- | ---- | 
| http://10.0.10.1/ | web-01/02 を交互に表示| 
| http://10.0.10.1:11001/ | web-01 を表示 | 
| http://10.0.10.1:11002/ | web-02 を表示 | 

# 5. 障害時の動き

web-01のウェブサーバーを停止してアクセスしてみます。

| URL | 表示内容 |
| ---- | ---- | 
| http://10.0.10.1/ | web-02 のみを表示 | 
| http://10.0.10.1:11001/ | 503エラーを表示 | 
| http://10.0.10.1:11002/ | web-02 を表示 | 

web-01のウェブサーバーを起動すると、正常にアクセスできるようになり、障害時/復旧時にHAProxyが適切に処理してくれていることが判ります。

なお、socatでステータスを確認するには、`show stat` コマンドを使い、以下のように実行します
（わかりやすいように一部のパラメータのみ表示させています）。

web-01が落ちているときは、web,web-01のステータスが **DOWN** になって、チェックステータスも **L4CON** に変わっているのがわかります。

```` bash
$ echo "show stat" | sudo socat stdio /tmp/haproxy-cli.sock | cut -d, -f1,2,18,37,57
# pxname,svname,status,check_status,last_chk
web,FRONTEND,OPEN,,
web,web-01,DOWN,L4CON,Connection refused
web,web-02,UP,L4OK,
web,BACKEND,UP,,
direct-01,FRONTEND,OPEN,,
direct-01,web-01,no check,,
direct-01,BACKEND,UP,,
direct-02,FRONTEND,OPEN,,
direct-02,web-02,no check,,
direct-02,BACKEND,UP,,
````

# 6. メンテナンス作業の手順
メンテナンス作業の場合、HAProxyをコマンドラインから操作し、一時的に片側サーバーの表示のみをするようにします。

一時的にサーバーへの接続を無効にするコマンドは `disable server {pxname}/{svname}` です。
今回はweb-01のメンテナンスを行うため以下のようにコマンドを実行し、web-01 を切り離します。

この場合は、web,web-01 のステータスは **MAINT** ですが、疎通は出来ているのでチェックステータスは **L4OK** のままです。

```` bash
$ echo "disable server web/web-01" | sudo socat stdio /tmp/haproxy-cli.sock
$ echo "show stat" | sudo socat stdio /tmp/haproxy-cli.sock | cut -d, -f1,2,18,37,57
# pxname,svname,status,check_status,last_chk
web,FRONTEND,OPEN,,
web,web-01,MAINT,L4OK,
web,web-02,UP,L4OK,
web,BACKEND,UP,,
direct-01,FRONTEND,OPEN,,
direct-01,web-01,no check,,
direct-01,BACKEND,UP,,
direct-02,FRONTEND,OPEN,,
direct-02,web-02,no check,,
direct-02,BACKEND,UP,,
````

この状態では、web-01は稼働していますがLBからは切り離されていますので、各URLの表示は以下のようになります。
障害時と違い、web-01は正常に表示できます。

| URL | 表示内容 |
| ---- | ---- | 
| http://10.0.10.1/ | web-02 のみを表示 | 
| http://10.0.10.1:11001/ | web-01 を表示（エラーにならない） | 
| http://10.0.10.1:11002/ | web-02 を表示 | 

この状態で、web-01 のメンテナンスを行い、web-01用のURL http://10.0.10.1:11001/ で動作確認を行ってください。

問題がなければ、元の状態に戻します。
切り離していたweb-01を組み込むためのコマンドは `enable server {pxname}/{svname}` ですので、
先ほどと同じように、以下のようにコマンドを実行します。

web,web-01のステータスが **UP** になれば、復旧です。

```` bash
$ echo "enable server web/web-01" | sudo socat stdio /tmp/haproxy-cli.sock
$ echo "show stat" | sudo socat stdio /tmp/haproxy-cli.sock | cut -d, -f1,2,18,37,57
# pxname,svname,status,check_status,last_chk
web,FRONTEND,OPEN,,
web,web-01,UP,L4OK,
web,web-02,UP,L4OK,
web,BACKEND,UP,,
direct-01,FRONTEND,OPEN,,
direct-01,web-01,no check,,
direct-01,BACKEND,UP,,
direct-02,FRONTEND,OPEN,,
direct-02,web-02,no check,,
direct-02,BACKEND,UP,,
````

次に、web-02に対しても同じように作業をすることで、ウェブの表示の中断なしでメンテナンスをすることが可能になります。

# 7. おわりに

非常にざっくりと最低限の内容ですが、メンテナンスポートを作っておくと何かと便利です。

また、ソケットを利用したHAProxyの制御も非常に便利ですので、最低限のコマンドは覚えておくといいと思います。