There are several options for software load-balancing. You can go all out and use heartbeat, or you can use something like varnish/pound - both of those will work as a reverse proxy to route traffic to N backend servers.
I wrote about migrating to a cluster here:
http://www.debian-administration.org/article/683/Redeploying....
In brief I used "ucarp" to have a virtual IP which was always up on one of four hosts, then on that virtual IP I have pound listening for SSL, and varnish for HTTP. Pound forwards to Varnish, varnish does some caching and works as a load-balancer to the Apache back-ends.
I've had a couple of outages where two webservers died, and it was 100% transparent.