冗長構成で負荷を分散する

本設定例は、以下の機種に対応しています。

対応機種: RTX5000 RTX3500 RTX1210 RTX1200

図 冗長構成で負荷を分散する:回復 下矢印:負荷上昇 / 上矢印:回復 図 冗長構成で負荷を分散する:負荷上昇

WAN回線を冗長構成にし、回線の使用状況によって経路を切り替えるLuaスクリプトです。
LAN側のホストをIPアドレスで3つのグループに分け、各グループ毎に経路を指定します。グループ1のPCからのインターネットアクセスを優先するため、回線の受信負荷率によって以下のように各グループの経路を切り替えます。

  • グループ1
    優先度:高。常にISP1を経由してインターネットアクセスを行う。
  • グループ2
    通常はISP1の回線を経由してインターネットアクセスを行う。ISP1の回線使用率が上限閾値を超えたら、ISP2の回線へと経路を切り替える。その後、ISP1の回線使用率が下限閾値より下がったら、ISP1の回線を使用するように経路を元に戻す。
  • グループ3
    常にISP2を経由してインターネットアクセスを行う。

RTX1200の設定例

経路の設定 ip route default gateway pp 1 filter 11 12 gateway pp 2 filter 13
LANの
インタフェースの設定
(LAN1ポートを使用)
ip lan1 address 192.168.0.1/24
WANの
インタフェースの設定
(LAN2ポートを使用)
pp select 1
pp always-on on
pppoe use lan2
pp auth accept pap chap
pp auth myname (ISP1に接続するID) (ISP1に接続するパスワード)
ppp lcp mru on 1454
ppp ipcp ipaddress on
ppp ipcp msext on
ip pp mtu 1454
ip pp nat descriptor 1
pp enable 1
WANの
インタフェースの設定
(LAN3ポートを使用)
pp select 2
pp always-on on
pppoe use lan3
pp auth accept pap chap
pp auth myname (ISP2に接続するID) (ISP2に接続するパスワード)
ppp lcp mru on 1454
ppp ipcp ipaddress on
ppp ipcp msext on
ppp ccp type none
ip pp nat descriptor 1
pp enable 2
NATの設定 nat descriptor type 1 masquerade
DNSの設定 dns server select 1 (ISP1から指定されたDNSサーバーのIPアドレス) any . restrict pp 1
dns server select 2 (ISP2から指定されたDNSサーバーのIPアドレス) any .
dns private address spoof on
フィルタの設定 ip filter 11 pass 192.168.0.0/26 *
ip filter 12 pass 192.168.0.64/26 *
ip filter 13 pass 192.168.0.128/25 *
Luaスクリプトの
スケジュール設定
schedule at 1 startup * lua (Luaスクリプトファイル名)

Luaスクリプト例

設定値

-- 監視間隔 (1-864000 秒)
idle_time = (監視間隔)

-- ISP1回線の受信方向の回線負荷が上がった状態と判断する閾値(1 - 99 %)
th_high = (上限閾値)

-- ISP1回線の受信方向の回線負荷が下がった状態と判断する閾値(1 - 99 %)
th_low = (下限閾値)

-- 出力する SYSLOG のレベル(info, debug, notice)
log_level = "(SYSLOGレベル)"

show status pp コマンドの
実行結果から受信負荷率を求める関数

function pp_load_info(num)
 local rtn, snd, rcv, str, n
 local t = {}
 local cmd = "show status pp " .. tostring(num)
 local ptn = "負荷%:%s+(%d+)%.%d+%%"
 

 rtn, str = rt.command(cmd)
 if (rtn) and (str) then
  n = 1
  for w in string.gmatch(str, ptn) do
   t[n] = w
   n = n + 1
  end

  if (t[1]) then
   rcv = tonumber(t[1])
  end
  if (t[2]) then
   snd = tonumber(t[2])
  end
 end

 return rtn, rcv, snd, str
end

現在の日時を取得する関数

function time_stamp()
 local t

 t = os.date("*t")
 return string.format("%d/%02d/%02d %02d:%02d:%02d",
  t.year, t.month, t.day, t.hour, t.min, t.sec)
end

メインルーチン

local rtn, rcv, snd, str
local high = false

local cmd_high = "ip route default gateway pp 1 filter 11 gateway pp 2 filter 12 13"
local cmd_low = "ip route default gateway pp 1 filter 11 12 gateway pp 2 filter 13"

while (true) do
 while (not high) do
  rtn, rcv, snd, str = pp_load_info(1)
  if (rtn) and (rcv) then
   if (rcv > th_high) then
    rtn, str = rt.command(cmd_high)
    if (rtn) then
     high = true
     rt.syslog(log_level, "route changed. (Luaスクリプトファイル名)")
    else
     rt.syslog(log_level, "change route failed. (Luaスクリプトファイル名)")
    end
   end
  end
  rt.sleep(idle_time)
 end

 while (high) do
  rtn, rcv, snd, str = pp_load_info(1)
  if (rtn) and (rcv) then
   if (rcv < th_low) then
    rtn, str = rt.command(cmd_low)
    if (rtn) then
     high = false
     rt.syslog(log_level, "route restored. (Luaスクリプトファイル名)")
    else
     rt.syslog(log_level, "restore route failed. (Luaスクリプトファイル名)")
    end
   end
  end
  rt.sleep(idle_time)
 end
end