鉄板ロードバランサー LVS を10分で構築するCHEFクックブック

# 概要

SOFTLAYER のポータルから利用できるロードバランサーは簡単に利用できるのですが、同時接続数、リンク速度、HA構成によって価格が決められ、システムを設計する上で、頭を痛める原因になったりもします。 一方 Linux Virtual Server (LVS) (1)は、オープンソースでLinuxにバンドルされているロードバランサーのソフトウェアです。さらに、HA (High Availability) 構成を組むことも、10GbpsのNICと組み合わせて利用もできる低価格高性能な鉄板ロードバランサーです。

この鉄板ロードバランサーを利用する場合の唯一の難点は、まとまった情報が少なく、設定がカーネルパラメータの変更やネットワーク設定を伴い、敷居が高いものです。

この課題を解決するために、本クックブックは、CHEFを利用して、鉄板ロードバランサーLVSを自動構築するものです。

# システム構成
このクックブックは、LVSサーバーが単一障害点(SPOF)にならない様に、KeepAlived(2)を利用してHA構成を作ります。マスター状態のLVSサーバーは、VIPを保持して振り分けを実施します。マスター状態のLVSサーバーが居なくなると、スタンバイ状態のLVSサーバーが昇格してVIPを保持して振り分けをおこないます。
![LVS_ActStby.png](https://qiita-image-store.s3.amazonaws.com/0/42829/c8f9e6d7-662e-e8bc-49e3-81608df7015d.png)

クラウドの管理システムから付与されるIPアドレスとダブらない VIP を設定するために、SOFTLAYER のポータブル・サブネット(3)を利用します。


## 要求振分け方式
このクックブックが実装するロードバランシング方式は、DSR(ダイレクト・サーバー・リプライ)です。この方式は、要求をVIPで受け、実サーバーへ要求パケットを転送します。 ウェブサーバーの応答はLVSを経由せずに直接返します。(4)(5)(6)

![dr_load_balance.png](https://qiita-image-store.s3.amazonaws.com/0/42829/87f85fa4-ab64-722c-6155-ae45aa8646a9.png)

DSRを利用する理由は、応答がLVSを通過せず、リアルサーバーから直接返すため、SOFTLAYERの帯域プールを必要とせず通信費が分散され、LVSサーバーの負荷軽減に役立ちます。(15)



## OSファイアウォールの設定
このクックブックでは、次の様なiptablesの設定を行い、ファイアウォール不要を設定にします。 サーバー個別にiptables設定するのは技術スキル的また作業工数として難しい場合は、専用のファイアウォールを導入すれば簡単に解決できます。しかし、数十万人がアクセスする様な高負荷システムでは、ファイアウォールが性能ボトルネックやサービス停止の原因となるリスクを負うことになり、専用ファイアウォールに依存する訳にはいきません。特にLVSの様な、膨大な数のアクセスを裁かなければならない機能では、一層顕著な問題となります。
![iptables.png](https://qiita-image-store.s3.amazonaws.com/0/42829/39e78e7b-58c3-455d-8d81-37b2ad3fd869.png)

## カーネルパラメータの変更

このCookbookはTCPのセッション追跡テーブルのサイズを拡張します。 WEBサーバーでTCPのセッション追跡テーブルが溢れると、dmesgに次の様なメッセージを出してパケットを廃棄してしまいます。この様な状況に陥らない様にテーブルサイズを拡大します。(7)(8)(9)

```
nf_conntrack: table full, dropping packet.
```
トラッキング数をカウント数監視(10)(12)するには、以下のコマンドで行数を数えます。

```
# cat /proc/sys/net/netfilter/nf_conntrack_count
2
```
コネクションテーブルのサイズを増やしておきます。セッションあたりスワップ対象外のメモリを約350バイトを必要(11)(12)とします。以下の設定では、2000000*350/1024/1024 = 668MB となりますから、メモリ量を考慮しながら設定値を決めます。

```
nf_conntrack_max=2000000
```

# 実装の進め方

作業の概要を箇条書きにすると以下の様になります。

1. LVSサーバーのデプロイ
2. リアルサーバー(WEBサーバー)のデプロイ
3. ポータブルサブネットのデプロイ 　Public Subnet x1 
4. リアルサーバー（WEBサーバー)のCHEFによる設定 
  1. クックブックをGitHubから取得
  2. クックブックのアトリビュート設定
  3. Chefコマンドで適用
5. LVSサーバー設定のCHEFを利用した設定
  1. クックブックをGitHubから取得
  2. クックブックのアトリビュート設定
  3. Chefコマンドで適用

### 1. LVSサーバーのデプロイ
SoftLayer カスタマーポータル (https://control.softlayer.com/) で、サーバーをオーダーします。最小構成として、仮想サーバーのCPUコアx1、RAM 1GB、ディスク 25GB です。アクティブ・スタンバイ用に２台準備します。 サーバーをデプロイする際のプロビジョニング・スクリプトが、LVS設定クックブックの前提条件になっているので、Linuxのディストリビューションに合わせて、プロビジョニング・スクリプトを設定します。

### 2. リアルサーバー(WEBサーバー)のデプロイ
ロードバランス対象のWEBサーバーをオーダーします。 NGINX や Apache HTTP Server などの利用を想定しています。こちらもプロビジョニング・スクリプトがLVSリアルサーバーの前提条件になっているので、デプロイの際に前述同様に設定します。

### 3. ポータブルサブネットのデプロイ
ソフトレイヤー活用ガイド第2部「コンフィグレーション・ガイド」4.2 サーバーを替えても同じIPアドレスを継続するには？ https://www.change-makers.jp/post/10345 を参考にして、サブネットを注文します。

### 4. リアルサーバー（WEBサーバー)のCHEFを利用した設定
クックブックのURLは、GitHub https://github.com/takara9/lvs-web01 で、このURLのREADME.md に具体的な利用方法が記載されています。 DRS方式のロードバランスでは、受けたパケットを実サーバーへフォワードするため、リアルサーバーで仮想サーバーのIPアドレス(VIP)のパケットを受信できる様に設定しなければなりません。さらに、FIN_WAITの時間を調整して、iptables のセッション追跡のテーブルが溢れない様にします。iptables のセッション追跡数の上限も引き上げます。

  1. OSファイアウォール設定
  2. パッケージ追加 
  3. VIP用のループバック・インタフェースの追加
  4. カーネルパラメータの設定

このクックブックの基本的な適用方法は、GitHubの前述のURLにある [README.md](https://github.com/takara9/lvs-web01) に記載してあります。

WEBサーバーの処理能力を決定づける要素に、TCPのTIME_WAIT、iptables の conntrack_maxがあります。 conntrack_maxは、iptablesが有効になっている場合、セッション状態をトラッキングするテーブルの行数を指しています。このテーブルが一杯になると、それ以上のセッションを確立することができなくなります。 そして、TCPセッションがクローズする際に、TCPポートを解放するまでの待ち時間があります。 この時間はデフォルトで60秒なのですが、高負荷なシステムでは、TIME_WAIT中のポートで一杯になり、新たなセッションが確立できなくなる事があります。
次の図のTIME_WAITの数は、30000を超えているため、空きポートが枯渇している恐れがあります。空きポートが少なくなるとTCP/IPの動作が不安定になり、通信が出来なくなったります。

![スクリーンショット 2015-12-08 1.00.21.png](https://qiita-image-store.s3.amazonaws.com/0/42829/d51234ab-b056-abb6-8bc7-10278f3b2af3.png)

次のグラフは、/etc/sysctl.confに以下のパラメータを与えて調整した結果になります。

```
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
```
見てすぐに解るとおり、TIME_WAITのタイムアウト時間を短くしたことで、TIME_WAIT状態で塞がっているポート数が劇的に減っている事がわかります。この設定により、安定した通信ができる様になります。

![スクリーンショット 2015-12-08 1.00.43.png](https://qiita-image-store.s3.amazonaws.com/0/42829/a0747522-5506-4026-d338-6660e7d9f6f4.png)

CentOS6 デフォルト設定のグラフと、CentOS6 FIN_TIMEWAIT調整後のグラフで変化が無いものが、conntrack_countの値です。 こちらの対策は、下記のパラメータで最大値を大きくします。 　

```
net.nf_conntrack_max = 1000000
```


### 5. LVSサーバーのCHEFを利用した設定
クックブックのURLは、GitHub https://github.com/takara9/lvs01 です。LVS用にデプロイした二つのサーバーにアクティブ・スタンバイのHA構成ですが、両者に同じ設定をCHEFを適用して構築します。具体的な利用手順は、[README.md](https://github.com/takara9/lvs01) にあります。

  1. OSファイアウォール設定
  2. パッケージ追加 (ipvsadm, keepalived)
  3. KeepAlived 仮想サーバーのIPアドレス(VIP)の設定
  4. KeepAlived リアルサーバーのIPアドレスとポート番号の設定
  4. カーネルパラメータの設定



# 参考資料

1. The Linux Virtual Server Project http://www.linuxvirtualserver.org
2. Keepalived for Linux http://www.keepalived.org/
3. ソフトレイヤー活用ガイド 4.2 サーバーを替えても同じIPアドレスを継続するには？ https://www.change-makers.jp/post/10345
4. LVS-HOWTO http://www.austintek.com/LVS/LVS-HOWTO/HOWTO
5. RedHat Enterprise Linux 6 第3章 Load Balancer Add-On の設定 https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Load_Balancer_Administration/ch-lvs-setup-VSA.html
6. RedHat Enterprise Linux 7 ロードバランサーの管理 https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Load_Balancer_Administration/index.html
7. Resolving “nf_conntrack: table full, dropping packet.” flood message in dmesg Linux kernel log (http://pc-freak.net/blog/resolving-nf_conntrack-table-full-dropping-packet-flood-message-in-dmesg-linux-kernel-log/)
8. あなたの大量配信サーバ、ip_conntrack溢れていませんか？(http://www.e-agency.co.jp/column/20121225.html)
9. DMMツチノコブログ netfilterモジュール (http://tsuchinoko.dmmlabs.com/?p=1016)
10. iptables (http://www.iptables.info/en/connection-state.html)
11. 3.7 ip_conntrack: maximum limit of XXX entries exceeded (http://www.netfilter.org/documentation/FAQ/netfilter-faq-3.html#ss3.7)
12. Kernel Documentation (https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt)
13. ipvsadm(8) -Linux man page http://linux.die.net/man/8/ipvsadm
14. keepalived.conf(5) - Linux man page http://linux.die.net/man/5/keepalived.conf
15. 高トラフィックに対応できるLinuxロードバランサを目指して ～ LVSをNATからDSRへ http://dsas.blog.klab.org/archives/50678999.html