ipvsのthresholdからsorry_serverへ飛ばしたい
ipvsの接続数がthresholdを超えたら「ごめんなさいサーバ」に飛ばせるように試行錯誤中です。
まあ、問題は「ごめんなさいサーバ」をどのように指定してどのように内部で保持するかですかね。
で、なにげに ip_vs_rr.c を眺めててふと思ったんですが、転送先を決定するときは、
・IP_VS_DEST_F_OVERLOADフラグが立っていない
・weightが0より大きい
この両方の条件を満たす転送先を探す訳ですけど、ここを
・IP_VS_DEST_F_OVERLOADフラグが立っていない
・weightが1より大きい
に変えて、weight==1 の転送先を「ごめんなさいサーバ」とみなす事で、構造体に手を加えず
に実現できそうな感じがします。
というわけで、試しに ip_vs_rr.c だけですが、こんな感じで書き換えてみました。
--- linux-2.6.12.6/net/ipv4/ipvs/ip_vs_rr.c 2005-08-30 01:55:27.000000000 +0900 +++ linux-2.6.12.6-sorry/net/ipv4/ipvs/ip_vs_rr.c 2007-03-27 23:19:34.000000000 +0900 @@ -71,11 +71,27 @@ dest = list_entry(q, struct ip_vs_dest, n_list); if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) && - atomic_read(&dest->weight) > 0) + atomic_read(&dest->weight) > 1) /* HIT */ goto out; q = q->next; } while (q != p); + /*----- find w==1 -----*/ + p = (struct list_head *)svc->sched_data; + p = p->next; + q = p; + do { + /* skip list head */ + if (q == &svc->destinations) { + q = q->next; + continue; + } + + dest = list_entry(q, struct ip_vs_dest, n_list); + if( atomic_read(&dest->weight) == 1 ) + goto out; + q = q->next; + } while (q != p); write_unlock(&svc->sched_lock); return NULL;
で、keepalived.confはこんな感じにします。
virtual_server 10.37.129.3 { delay_loop 6 lb_algo rr lb_kind NAT nat_mask 255.255.255.0 persistence_timeout 0 protocol TCP #----- sprry_serverの代わり ----- real_server 127.0.0.4 22 { weight 1 } real_server 127.0.0.2 22 { lthreshold 0 uthreshold 2 weight 2 } real_server 127.0.0.3 22 { lthreshold 0 uthreshold 2 weight 2 } }
そしてkeepalivedを起動して別のマシンから ssh 10.37.129.3 しまくると・・・
# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.37.129.3:22 rr -> 127.0.0.3:22 Local 2 3 0 -> 127.0.0.2:22 Local 2 3 0 -> 127.0.0.4:22 Local 1 0 0
weightが1な127.0.0.4以外の転送先にのみ接続されていることがわかります。
もう一回sshすると、本来はuthresholdいっぱいいっぱいなので蹴られますが、ここでは
127.0.0.4に対して転送されるようになるはずです。
# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.37.129.3:22 rr -> 127.0.0.3:22 Local 2 3 0 -> 127.0.0.2:22 Local 2 3 0 -> 127.0.0.4:22 Local 1 1 0
おお、いいじゃん(笑
これで、接続数がしきい値を超えた場合に「ごめんなさいサーバ」へ飛ばすという目的は達成できました。
ただまあ、このままweightが1な転送先を「ごめんなさいサーバ」とみなすのもいまいち感が漂うのでもう少
しどうにかにしょうかと思います。