概要
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を保持して振り分けをおこないます。
クラウドの管理システムから付与されるIPアドレスとダブらない VIP を設定するために、SOFTLAYER のポータブル・サブネット(3)を利用します。
要求振分け方式
このクックブックが実装するロードバランシング方式は、DSR(ダイレクト・サーバー・リプライ)です。この方式は、要求をVIPで受け、実サーバーへ要求パケットを転送します。 ウェブサーバーの応答はLVSを経由せずに直接返します。(4)(5)(6)
DSRを利用する理由は、応答がLVSを通過せず、リアルサーバーから直接返すため、SOFTLAYERの帯域プールを必要とせず通信費が分散され、LVSサーバーの負荷軽減に役立ちます。(15)
OSファイアウォールの設定
このクックブックでは、次の様なiptablesの設定を行い、ファイアウォール不要を設定にします。 サーバー個別にiptables設定するのは技術スキル的また作業工数として難しい場合は、専用のファイアウォールを導入すれば簡単に解決できます。しかし、数十万人がアクセスする様な高負荷システムでは、ファイアウォールが性能ボトルネックやサービス停止の原因となるリスクを負うことになり、専用ファイアウォールに依存する訳にはいきません。特にLVSの様な、膨大な数のアクセスを裁かなければならない機能では、一層顕著な問題となります。
カーネルパラメータの変更
この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
実装の進め方
作業の概要を箇条書きにすると以下の様になります。
- LVSサーバーのデプロイ
- リアルサーバー(WEBサーバー)のデプロイ
- ポータブルサブネットのデプロイ Public Subnet x1
- リアルサーバー(WEBサーバー)のCHEFによる設定
- クックブックをGitHubから取得
- クックブックのアトリビュート設定
- Chefコマンドで適用
- LVSサーバー設定のCHEFを利用した設定
- クックブックをGitHubから取得
- クックブックのアトリビュート設定
- Chefコマンドで適用
1. LVSサーバーのデプロイ
SoftLayer カスタマーポータル (https://control.softlayer.com/) で、サーバーをオーダーします。最小構成として、仮想サーバーのCPUコアx1、RAM 1GB、ディスク 25GB です。アクティブ・スタンバイ用に2台準備します。 サーバーをデプロイする際のプロビジョニング・スクリプトが、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 のセッション追跡数の上限も引き上げます。
- OSファイアウォール設定
- パッケージ追加
- VIP用のループバック・インタフェースの追加
- カーネルパラメータの設定
このクックブックの基本的な適用方法は、GitHubの前述のURLにある README.md に記載してあります。
WEBサーバーの処理能力を決定づける要素に、TCPのTIME_WAIT、iptables の conntrack_maxがあります。 conntrack_maxは、iptablesが有効になっている場合、セッション状態をトラッキングするテーブルの行数を指しています。このテーブルが一杯になると、それ以上のセッションを確立することができなくなります。 そして、TCPセッションがクローズする際に、TCPポートを解放するまでの待ち時間があります。 この時間はデフォルトで60秒なのですが、高負荷なシステムでは、TIME_WAIT中のポートで一杯になり、新たなセッションが確立できなくなる事があります。
次の図のTIME_WAITの数は、30000を超えているため、空きポートが枯渇している恐れがあります。空きポートが少なくなるとTCP/IPの動作が不安定になり、通信が出来なくなったります。
次のグラフは、/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状態で塞がっているポート数が劇的に減っている事がわかります。この設定により、安定した通信ができる様になります。
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 にあります。
- OSファイアウォール設定
- パッケージ追加 (ipvsadm, keepalived)
- KeepAlived 仮想サーバーのIPアドレス(VIP)の設定
- KeepAlived リアルサーバーのIPアドレスとポート番号の設定
- カーネルパラメータの設定
参考資料
- The Linux Virtual Server Project http://www.linuxvirtualserver.org
- Keepalived for Linux http://www.keepalived.org/
- ソフトレイヤー活用ガイド 4.2 サーバーを替えても同じIPアドレスを継続するには? https://www.change-makers.jp/post/10345
- LVS-HOWTO http://www.austintek.com/LVS/LVS-HOWTO/HOWTO
- 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
- RedHat Enterprise Linux 7 ロードバランサーの管理 https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Load_Balancer_Administration/index.html
- 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/)
- あなたの大量配信サーバ、ip_conntrack溢れていませんか?(http://www.e-agency.co.jp/column/20121225.html)
- DMMツチノコブログ netfilterモジュール (http://tsuchinoko.dmmlabs.com/?p=1016)
- iptables (http://www.iptables.info/en/connection-state.html)
- 3.7 ip_conntrack: maximum limit of XXX entries exceeded (http://www.netfilter.org/documentation/FAQ/netfilter-faq-3.html#ss3.7)
- Kernel Documentation (https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt)
- ipvsadm(8) -Linux man page http://linux.die.net/man/8/ipvsadm
- keepalived.conf(5) - Linux man page http://linux.die.net/man/5/keepalived.conf
- 高トラフィックに対応できるLinuxロードバランサを目指して ~ LVSをNATからDSRへ http://dsas.blog.klab.org/archives/50678999.html