It's been a few years since I used keepalived so my knowledge might be outdated.
You are correct that the VMs should be in different servers. To test around you can set up on the same, but this shouldn't be done in production environments, if you lose the host, you lose the service.
Keepalived will make sure your service is available in an IP. To say, you have two (it can be configured for more than two) servers with (A) 192.168.0.2 and (B) 192.168.0.3 which provide the service you want to provide. With Keepalived you'll configure a common IP for both of them, let's say 192.168.0.4
While working, server A will be available at 192.168.0.2 and 192.168.0.4 while server B will be available at 192.168.0.3. If server A fails keepalived will "move" 192.168.0.4 to server B, so 192.168.0.2 will not be available and server B will be available at 192.168.0.3 and 192.168.0.4.
No matter which server is up / primary, your service will always be available at 192.168.0.4
For the mirroring part, you need to solve it in another step outside from keepalived. For example, MariaDB provides multimaster replication "out of the box" with galera (the recommendation is at least 3 nodes)
For files, depending on your filesystem you should have to rsync, use some shared units, distribute filesystem (Ceph), ...