I came across a few posts that deal with issues surrounding multiple Pi-hole instances that my high availability implementation seem to resolve. Instead of hijacking the posts, which I already tried to do, I figured I'd create a new one for my solution.
I use Docker Swarm to replicate the Pi-hole service and MACVLAN routing to ensure proper communication between client and Pi-hole services. To keep settings, lists, etc in sync, I use bind mounts backed by GlusterFS.
The solution is working well for me, even handling the upgrade to 5.0 without issue. The playbook I created might not be the most flexible but it should serve as a good example and get you most of the way there, assuming you have a bit of technical chops.
You may need to smash together the following two resources I created:
Feedback and suggestions welcome!