朝日ネットでのインフラ設計・構築を担当しているラピー・ステファンです。 前回の構成説明に続き、今回は「CARP+VMware冗長設計の欠点の回避策」について紹介します。
CARP+VMware冗長設計の欠点
前回で説明しました様に、CARPを仮想基盤上で利用するに当たり、 管理上の手間(VHIDグループの把握、ファイヤーウオールのルール)と必要以上に上がる負荷の問題が発生します。
なお、アクティブ・スタンドバイ構成のため、実質稼働するpfSenseノードは常に1台のみになりますので、 高可用性が担保されていても、スケーラビリティーは担保されません。 なお、HAproxyで行う処理はレイヤー7で行われるため、CARPマスターとスレーブの入れ替わりが発生した場合、 TCP/SSLセッションがまず切断されます。
また、意図せず切り替わった場合を考慮しない又は対応出来ないアプリケーションですと、 その状態まで失われ不具合に発展する恐れがあります。
アプリケーションによっては、バックエンドで状態維持が出来る機能もありますが、 ロードバランサーの切り替えが発生しても、使うバックエンドが変わらない状態が一番望ましいので、 その維持方法を具体的に紹介いたします。
代案の要件
下記3つの要件を満たす代案の設計をまず説明いたします:
- 仮想基盤上のCARPの管理と負荷の問題を回避する
- 高可用性を維持する
- 構成変更をより簡単にして、拡張性を保証する
CARPを使わない冗長設計
一言で説明しますと、仮想基盤上でCARPを使わず、その冗長機能を専用ハードウエアに任せます。
利点の説明
つまり、pfSenseの前に更にもう一段階設けて、レイヤー4で専用のロードバランサー装置にトラフィックを処理させます。 レイヤー4の単純な「左から右へパケットを送り、右から左へパケットを戻す」という処理は専用ハードウエアで行うと:
- レイヤー7と比べて軽微で、専用のプロセッサーを搭載したASIC等で処理が補助されている場合が多い
- つまり、より多くトラフィックを受けられる
- 冗長機能はハードウエアで担保するため、仮想基盤への悪影響・管理の手間が発生しない
- 冗長クラスターの間のセッション状態の共有は容易なので、切り替わりが発生しても、同じpfSense装置に処理されることは保証出来る
- そうすることによって、レイヤー4の切り替えがあっても、TCP/SSLセッションの切断が発生しない
- レイヤー7で処理するpfSense仮想マシンは、性能的に逼迫されても、横にまた展開していけばいい
- 2号機から3号機に同期設定を定義すればいい
- レイヤー4装置の性能が逼迫されても、あるいは移行が必要になった時、今度はもう一組みレイヤー4装置のクラスターを作って、向き先に同じレイヤー7装置を指定する
- そして、サービス公開のホスト名に複数のIPアドレスを持たす様にしておけば、今度はラウンドロビンで入り口でアクセスの分散も出来る様になる
- 設定が同じにすることで、利用するレイヤー7のノード又はバックエンドも維持できる
- そして、サービス公開のホスト名に複数のIPアドレスを持たす様にしておけば、今度はラウンドロビンで入り口でアクセスの分散も出来る様になる
なお、一つの装置にまとめず、レイヤー4の処理とレイヤー7の処理を分ける設計の意図は、 「サービス窓口の冗長化の機能」をレイヤー4に任せ、「アプリケーション側の負荷分散」をレイヤー7に任せることにあります。
レイヤー4・7を一括するハードウエアアプライアンスですと、更新やメンテナンス、追加機能、撤去機能はその装置の配下の全サービスに及ぶため、 事前の検証及び影響のコントロールが難しくなります。
レイヤー7やSSLに対応したベンダー製品は機能が高度になればなるほど、メーカーごとに提供している機能のばらつきが激しく、 ファームウエア更新リリースの間隔の問題や更新時のクセもありますので、その点を特に意識しました。
とにかく、業務ロジック等は特定のフリーソフトウェアにロックインされるにしても、ベンダー製品にロックインされるよりは負債が小さく済みます。
注意事項とその対応
ゲートウエイの指定について
前段にレイヤー4ロードバランサーからトラフィックを受ける場合、戻りトラフィックも同じゲートウエイを経由しなければなりません。 その辺りをゲートウエイの定義やインターフェースのアップストリームゲートウエイの定義で十分考慮する必要があります。
アクティブ・アクティブ構成
レイヤー4ロードバランサーで設定した負荷分散方法次第ではありますが、 あるソースIPアドレスからアクセスして、レイヤー7のpfSense1号機にアクセスしても、 別のアドレスからは2号機を経由することになります。
そうなった時、いずれかのノードの接続性が失われたら、 見えないところでサービスが利用出来ない状況に発展し兼ねません。
例えば、1台だけ戻りトラフィックのゲートウエイの指定が間違っていると、 正常に見えているが、通信が成り立たない、気づきにくいパターンの障害に発展します。
ヘルスチェックの実装
それに対応するために、HAproxyのロードバランサーが自分の通信状況を把握出来て、ヘルスチェックの結果として上流装置に還元する形が一番望ましいです。 HAproxyでは、「monitor-uri 」と「monitor fail 」というコマンドがあります:
- monitor fail で機能不全の状態を指す条件を指定する(例: monitor fail if { nbsrv(Service1_ipvANY) lt 1 } or { nbsrv(Service2_ipvANY) lt 1 } )
- monitor-uri で、その状態を返すURIを定義する(例: monitor-uri /healthcheck )
その設定を例えばポート80のフロントエンドに入れることで:
- 通常時は、「GET /healthcheck」を送ったら、下記の返答文が返ってきます:
HTTP/1.0 200 OK Cache-Control: no-cache Connection: close Content-Type: text/html <html><body><h1>200 OK</h1> Service ready. </body></html>
- バックエンドService1_ipvANYが残りサーバー1台を切ったら、又はService2_ipvANYがそうなったら、下記の返答文が返ってきます:
HTTP/1.0 503 Service Unavailable Cache-Control: no-cache Connection: close Content-Type: text/html <html><body><h1>503 Service Unavailable</h1> No server is available to handle this request. </body></html>
これにより、上流装置のレイヤー4ロードバランサーのサービス定義で、ヘルスチェックとして「GET /healthcheck」の結果を見てもらい、 サービス要件に合った明確な状態に基づいて判断することが出来ます:
- 200なら、正常と判断し、トラフィックを割り振る
それ以外なら、トラフィックを割り振らない これにより:
特定のレイヤー7pfSenseノードのメンテナンス作業をしたい時、HAproxyを落とすか、必要なサーバーを全てメンテナンスモードにすれば、強制的にダウンに出来ます。
- 特定のバックエンドサーバ−を切り離すことも可能だが、これは必ず全てのレイヤー7pfSenseノードで実施しなければりません。
次回予告
今回、仮想化されたHAproxyをベースに拡張性・柔軟性・自己修復機能のある設計を紹介いたしました。 次回は以下のような具体的な便利設定に触れつつ、特殊構成とその対応の仕方を紹介したいと思います。
- ログでSSLバージョン、HTTPリファラー、HTTPブラウザーエイジェントを取得する
- 好きなヘッダーをキャプチャーして、ログで識別情報として出す
- Cookie IDを定義することで、クライアントから見た最終的なサーバーを決め打ち出来るようにする(L4/L7 LB障害への耐久性)
- transparent IPを使うと、TCP主体のアプリケーションも対応可能で、ハードウエアSSL暗号化装置の置き換えが出来る
採用情報
朝日ネットでは新卒採用・キャリア採用を行っております。