今までの負荷分散は一意のFQDNへのアクセスに対して、複数のサーバへ負荷分散を行ってきましたが、ユーザーによりURIが指定されている場合、URIの文字列によって対象のサーバを指定する方法を紹介します。
BIG-IPなどでは、iRuleにより実現していましたが、NSXALBだとDataScriptを使用します。
ネットワーク構成
ネットワーク構成は、TerraformでVSを作成したcent71、cent72のサーバを利用します。
hironw.hatenablog.com
VS、Pool、サーバの接続イメージは以下のようになります。
負荷分散対象のサーバ2台に対して、URIに「/test01/」が含まれている場合は「pool_cent71」へ、URIに「/test02/」が含まれている場合は「pool_cent72」へ転送します。
Poolの作成
まずは、Poolとサーバの組み合わせを以下のような構成でPoolを作成します。
Name:pool_cent71
Default Server Port:80
Server Name:192.168.10.71
IP Address:192.168.10.71
Health Monitors:System-HTTP
同様に、pool_cent72のPoolも作成します。
Name:pool_cent72
Default Server Port:80
Server Name:192.168.10.72
IP Address:192.168.10.72
Health Monitors:System-HTTP
VIPの作成
VIPとして192.168.3.72を作成します。
DataScriptの作成
URIによる負荷分散は、DataScripにより実現するため、スクリプトを作成します。
[Templates]-[Scripts]-[DataScripts]から「CREATE」を選択します。
以下の内容で設定を行います。
Name:Test-Datascript
Pools:pool_cent71、pool_cent72
[Events]-[ADD]から「HTTP Request」を選択し、スクリプトを貼り付けます。
POOL_01 = "pool_cent71" POOL_02 = "pool_cent72" PATH_01 = "/test01/" PATH_02 = "/test02/" path = avi.http.get_path() POOL_01_up, POOL_01_total = avi.pool.get_servers(POOL_01) POOL_02_up, POOL_02_total = avi.pool.get_servers(POOL_02) UserAgent = avi.http.get_header("user-agent") -- ---------------------------------------------------------- if string.beginswith(path, "index.html") and UserAgent == "avi/1.0" then if (POOL_01_up >= 1) or (POOL_02_up >= 1)then avi.http.response(200) else avi.http.response(503) end elseif string.contains(path, PATH_01) then avi.vs.log("LOG1: path hit! " .. path) avi.pool.select(POOL_01) elseif string.contains(path, PATH_02) then avi.vs.log("LOG2: path hit! " .. path) avi.pool.select(POOL_02) else avi.vs.log("LOG3: path not hit!" .. path) avi.http.close_conn() end
DataScriptの処理について説明していきます。
最初の「if string.beginswith(path, "index.html") and UserAgent == "avi/1.0"」は、beginswith(path, "index.html")関数で取得したpathが、「index.html」で始まる場合かつ、UserAgentが「avi/1.0」である場合という条件になり、これは、SEからのヘルスチェックが対象になります。
「 if (POOL_01_up >= 1) or (POOL_02_up >= 1)then」は、2台のサーバのいずれかのPoolがUPしていた場合となり、ヘルスチェックの結果を条件としています。
「avi.http.response(200)」は条件にマッチした場合、Response Code 「200」を返し、「avi.http.response(503)」はどちらのPoolもDOWNしていた場合、Response Code 「503」を返します。
「elseif string.contains(path, PATH_01) then」は、ヘルスチェックでないアクセスが来た場合で、「string.contains(path, PATH_01)」関数で取得したpathに、「/test01/」が含まれていた場合という条件になります。
条件にマッチした場合、「avi.vs.log("LOG1: path hit! " .. path)」で指定した文字列をログに出力し、「avi.pool.select(POOL_01)」で「pool_cent71」に転送します。
同様に、「/test02/」が含まれていた場合は、「pool_cent72」に転送します。
いずれの文字列も含んでいなかった場合は、「avi.http.close_conn()」でコネクションをクローズします。
VSの作成
ここまで作成してきた、Pool、VIP、DataScripを組み合わせ、以下のパラメータでVSを作成します。
VSを新規作成し、以下の内容を入力したら、「NEXT」を選択します。
Name:VS_Datascript_URI
VS VIP:vip_192.168.3.72
Services:80
TCP/UDP Profile:System-TCP-Proxy
Application Profile:System-HTTP
[Polices]-[DataScripts]から「Add DataScript」を選択します。
作成した「Test-Datascript」を選択し「NEXT」を選択します。
後は特に変更はせず、「NEXT」→「SAVE」を選択します。
動作確認
ブラウザから「http://192.168.3.72/test01/start.html」にアクセスするとcent71のページが表示され、「http://192.168.3.72/test02/start.html」にアクセスするとcent72のページが表示され、URIにより対象サーバへ転送していることの確認ができました。
DataScriptによる負荷分散の紹介は以上です。