FIRST: Get yourself an IP address that can be shared between the two servers. I'll explain why later.
Load balancing a web server involves a few steps:
- Load balancing the requests
- syncing the files
- sharing session data.
We use software called HAProxy to do the load balancing of requests. You can use round robin DNS but you lose fault tolerance. We have network mounted storage that ensures both servers have access to current files. And finally, we use a memached server to store shared session data between Apache HTTPd instances.
With name dropping out of the way, here are your fundamentals:
You want one location to point requests to, an address that points to both web servers. The easiest way to do this is with round robin DNS. RRDNS though, is complicated to set up with fault detection and correction (IE: if server1 goes down, at least half of your requests will be un-servicable). The alternative to RRDNS is a shared (usually virtual) IP Address that is ideally on the same subnet (and your server generally have to be in the same data center, etc...) there are a lot of restrictions. Failing the above two options you get closer to a hardware load balancer. You don't have to go purchase an F5 Load balancer though, you can get away with a third VM, HAProxy, LVS, or something similar. This final option leaves you witha very critical single point of failure though.
Either way, your common entry point sits at the front line and generally proxies requests (A VIP with keepalived skips the proxy but something tells me you may not be [un]fortunate enough to have your two VMs in the same data center with a compatible network. From there, generally speaking, you want the applications involved to have an idea of what its brothers and sisters (Read: PEERS) are doing. Apache HTTPd needs Session data your mail servers can probably act independently but will have to point to shared mailboxes somehow.
Finally, serving the same image file from each server can be challenging depending on your infrastructure. You could do local (subnet) NFS mounts, or tunnel NFS through TLS over the internet (see: HIGH LATENCY) or rsync copies at agreeable intervals, etc. (This is probably the simplest problem to solve).
If you don't need true load balancing and just NEED a fail over solution that will kinda maybe still work (new logins, lost shopping carts, anything stored in session data), you could set a monitoring process and RNDC your DNS records (with a low Time to Live) to reflect the active (working) server. (Expect 10-120 second delays where requests are lost).
Luckily the mail system has redundancy built in. You can spin up another mail server get it all tested and working, and add an MX entry at your desired priority and it should kind of work. (Not dealing with imap/pop3/receiving mail here... just sending is drop dead simple).
I did a project like this as my final project for my undergrad degree. Setup our Central Authentication system in a load balanced, redundant, and fault tolerant environment. It took about a year to go from design to production. (That was one web application). You can probably do it quicker... but this is a MASSIVE undertaking if you are not adept at linux, familiar with networking principles (Can you carry on an intelligent conversation about layer 3 switching and application layer error checking?), and in general, willing to work long hours learning about things you never thought you cared about.