Using NAT for Server Load Distribution
Problem
You have several application servers and you want to use NAT so that users can connect to them by a single IP address, distributing the load across all of the servers.
Solution
The rotary keyword allows you to do simple NAT-based load balancing of servers:
Router#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#interface FastEthernet0/0
Router(config-if)#ip address 192.168.1.1 255.255.255.0
Router(config-if)#ip nat inside
Router(config-if)#exit
Router(config)#interface FastEthernet0/1
Router(config-if)#ip address 192.168.2.1 255.255.255.0
Router(config-if)#ip nat outside
Router(config-if)#exit
Router(config)#ip nat pool WEBSERVERS 192.168.1.101 192.168.1.105 netmask 255.255.255.0 type rotary
Router(config)#access-list 20 permit host 192.168.1.100
Router(config)#ip nat inside destination list 20 pool WEBSERVERS
Router(config)#end
Router#
Discussion
This example is more applicable to an Intranet than to the public Internet. It shows a simple way of doing load balancing among a group of application servers that all perform the same function. We would like to stress that this load balancing is extremely limited, and if you want a fully featured load-balancing device, you would be much better off with one of Cisco's Content Services Switches, such as the CSS 11500 series. However, we understand that these devices are expensive, so if your requirements are fairly basic, this recipe provides a simpler and more cost effective solution.
We have a set of servers located on the LAN segment attached to the router's FastEthernet0/0 interface. In the example, we define a pool of servers on this segment called WEBSERVERS, which includes the addresses 192.168.1.101 through 192.168.1.105. These are the real physical addresses, the inside local addresses of the servers:
Router(config)#ip nat pool WEBSERVERS 192.168.1.101 192.168.1.105 netmask 255.255.255.0 type rotary
Then we create the actual NAT rule, and use a standard ACL to define the virtual IP address that devices can use to access this group of servers:
Router(config)#access-list 20 permit host 192.168.1.100
Router(config)#ip nat inside destination list 20 pool WEBSERVERS
This NAT rule has a key difference from others that we have looked at so far in this chapter because it is a destination rather than a source rule. All of the previous examples have assumed that the inside device starts the conversation with the outside device, so we have needed to rewrite the source address of the inside device on this essentially outbound conversation. In that scenario, it is appropriate to use an inside source NAT rule. Here, however, the outside device will initiate the conversation with the inside device. So we must use an inside destination NAT rule.
Now we can verify that this configuration behaves as expected by repeatedly connecting to the virtual IP address on the HTTP TCP port (80) several times:
Router#show ip nat translations
Pro Inside global Inside local Outside local Outside global
tcp 192.168.1.100:80 192.168.1.101:80 192.168.2.27:11012 192.168.2.27:11012
tcp 192.168.1.100:80 192.168.1.102:80 192.168.2.27:11013 192.168.2.27:11013
tcp 192.168.1.100:80 192.168.1.103:80 192.168.2.27:11014 192.168.2.27:11014
tcp 192.168.1.100:80 192.168.1.104:80 192.168.2.27:11015 192.168.2.27:11015
tcp 192.168.1.100:80 192.168.1.105:80 192.168.2.27:11016 192.168.2.27:11016
tcp 192.168.1.100:80 192.168.1.101:80 192.168.2.27:11017 192.168.2.27:11017
tcp 192.168.1.100:80 192.168.1.102:80 192.168.2.27:11018 192.168.2.27:11018
Router#
As you can see from the NAT translation table, each successive connection goes to the next address in the pool. It does this on a strict rotation, restarting at the first address in the range once it reaches the end.
Note that although this example uses a common TCP port, there is nothing in the configuration to restrict you to using this method for load balancing web servers. The technique would work equally well for sharing load among nonTCP application servers, such as the UDP-based DNS application.
This recipe shows a simple but effective load-balancer, but it does have several limitations compared to a fully featured load-balancer like the CSS 11500 series. These purpose-built devices are able to monitor all of the devices in the pool and remove any that become unavailable, for example. They also use more sophisticated load balancing algorithms that ensure that no one device in the pool winds up taking an overly large share of the load. Another alternative is the Server Load-Balancing (SLB) IOS feature set, which is currently available only on the 3640, 3660, 7200, and 7301 router platforms.
The method shown in this recipe has neither of these advantages. If any device in the pool becomes temporarily unreachable, or the application stops working, the NAT rule will continue to attempt sending new connections to it each time it comes up in the rotation. The end device will typically have to wait for a TCP connection timeout and reconnect, hopefully getting a different server from the pool.
Then, when the device comes back on line, it will again only receive new connections each time it comes up in the rotation. In most applications, this means that it will take a very long time to rebalance the load