Hi Riverbed Gurus,
We have a customer who has to make a load balancing scheme like in the table below.
SteelApp has to listen to requests on several TCP ports. Quantity of TCP ports are more than 30.
Depending from which source ip subnet request was seen by SteelApp and to which TCP port of VIP, SteelApp has to send a request to the active pool according to VIP TCP port. If host in active pool doesn’t work then send request to the backup pool.
Of course I can solve this task by configuring about 80 pools and 30 virtual servers, but it will be difficult to support.
Is it possible to solve this task by TrafficScript? For example by using only one virtual server with the special request rule and for example two pools active and backup?
Any hints are very welcome!
Thanks,
Alex
Solved! Go to Solution.
Hi Alexander,
I solved this problem using an iptables rule like this:
iptables -A PREROUTING -d <<IP of your TIG>>/32 -p tcp -m tcp --dport 6400:6420 -j DNAT --to-destination <<IP of your TIG>>:<<Port of your virtual server>>
and a traffiscript associated to my Virtual Server with:
# Get original request port
$OriginalPort = request.getDestPort();
# log.warn( "Original port is: ".$OriginalPort);
# Route request to right port on node
pool.select( "Pool name", "Node name but is optionally", $OriginalPort);
IPtables rule redirects all connection in a range of ports to a single IPort (MyVirtualServer) but doesn't change the packet, the rule reads the original destination port from the packet and uses it inside pool.select statement.
And it seems to work.
Hope this help you.
Stefano
Edit: in SteelApp 9.8 there's also "Port Mapping Rules" inside "Networking" => "NAT" but I don't try it yet.
Hi Alex,
as far as i know, steelapp needs a virtualserver for each port.
But you can put all nodes into a single-pool and then use trafficscript to decide which node to use
request.getLocalPort() gives you the localport
pool.select( "mypool", "mynode", myport ); let you choose which node should be used
with pool.listfailednodes( Pool ) you see which nodes are failed at the moment (so choose another one from pool.listactivenode(Pool) )
and finally request.getRemoteIP() gives you the ip of the client
This is fine, as long as you have only one node to response to a request, But if you want "real" load-balancing (let steelapp decide which node to use), then you have to group nodes together (and so create different pools), thats easier are "trafficscript-based-load-balancing".
btw, which application are you using that require such a load-balancing-scheme?
-Jochen
Hi Alexander,
I solved this problem using an iptables rule like this:
iptables -A PREROUTING -d <<IP of your TIG>>/32 -p tcp -m tcp --dport 6400:6420 -j DNAT --to-destination <<IP of your TIG>>:<<Port of your virtual server>>
and a traffiscript associated to my Virtual Server with:
# Get original request port
$OriginalPort = request.getDestPort();
# log.warn( "Original port is: ".$OriginalPort);
# Route request to right port on node
pool.select( "Pool name", "Node name but is optionally", $OriginalPort);
IPtables rule redirects all connection in a range of ports to a single IPort (MyVirtualServer) but doesn't change the packet, the rule reads the original destination port from the packet and uses it inside pool.select statement.
And it seems to work.
Hope this help you.
Stefano
Edit: in SteelApp 9.8 there's also "Port Mapping Rules" inside "Networking" => "NAT" but I don't try it yet.
Hi Jochen,
Thanks a lot for your answer!!
Customer is Retail Company and they have several remote points of sale. They need to collect sales statistic from every point of sale. For this purpose they use this app. This application was developed special for this Customer.
Your example very useful, thank you!!
But my task is (according to the table above, it will be more clear)
If client from IP subnet 172.16.10.0/25 is trying to establish connection to 10.10.10.10:15601 , then forward it to 10.0.0.1:17601 (active pool) or to 10.0.0.2:17601 (backup pool) and nowhere else. I mean that in Active pool must be only one host and in Backup pools must be only one host.
Or If client from IP subnet 172.16.20.0/25 is trying to establish connection to 10.10.10.10:15601 , then forward it to 10.0.0.1:13601 (active pool) or to 10.0.0.2:13601 (backup pool) and nowhere else. And so on and so on for each row in the table.
As I understand I have to use two pools – Active, with every active host according to the table. And backup with every backup host according to the table.
Now I have to write correct TrafficSript rule for this task.
Hi Stefano,
Thanks a lot for your answer!!
I think, your example is what I was looking for.
I have configured Virtual Server Port Mapping on SteelApp, and it works. Now all request to VIP TCP ports (15601, 15602,15603…) are mapping to one Virtual Server Port.
So now I have to differentiate from which IP subnet request was seen and to which TCP port and then forward request to appropriate hosts.
I have written the request TrafficScrip rules according to your and Jochen recommendations:
if( string.ipmaskmatch( request.getremoteip(), "172.16.10.0/24" )
|| request.getDestPort() == 15601 ){
pool.use( "Stock_Pool_Active", "10.0.0.1", 17601 );}
else {
pool.use( "Stock_Pool_Active", "10.0.0.2", 17601 );}
if( string.ipmaskmatch( request.getremoteip(), "172.16.10.0/24" )
|| request.getDestPort() == 15602 ){
pool.use( "Stock_Pool_Active", "10.0.0.1", 17602 );}
else {
pool.use( "Stock_Pool_Active", "10.0.0.2", 17602 ); }
...and so on.
I am truly new with TrafficScript and I am not sure that it is correct. Could you check it? Thanks in advance!
For example If I disable the active host then connection with the service is still working, but at the current activity reports I do not see that the traffic start processing by the backup host. In the historical activity reports, I see increasing statistics of Forward Proxy hosts.
Hi Alexander,
I'm happy that what I've suggested to you it's usefull.
About your script, I think that you need to add a "break" statement between the "If...Else" so that the script exits, doesn't check the other cases and forwards the packages faster.
Instead of using a "backup host" (your script don't do this) I prefer use a pool with two nodes and tweak the weight inside "Load Balancing" section fo pool configuration.
What happens if in "pool.use" don't specify a host, using ""?
About "disable", no current connection will be lost, if you don't want to close the active connection you have to use "drain" state.
Stefano
As an aside, using TrafficScript you can determine what IP or port the initial connection was sent to, before it was slurped up in an IPTables rule using the request.getDestIP() and request.getDestPort() functions:
Returns the original IP address that the client attempted to connect to. This will be the same as request.getLocalIP() unless the connection was redirected via firewall rules (e.g. using iptables on Linux)
# Get the local IP address, such as "10.1.4.21" or
# "2001:200::8002:203:47ff:fea5:3085"
$ip = request.getDestIP();
Returns the original network port number that the client attempted to connect to. This will be the same as request.getLocalPort() unless the connection was redirected via firewall rules (e.g. using iptables on Linux)
# Get the port number on the traffic manager,
# such as 80
$port = request.getDestPort();