I'm having a slow motion argument with a coworker about a piece of code I maintain. It provides bootstrapping data that nearly all of our code uses in some way. Everything from stats and logging up to user-visible functionality.
Every time I run into a hiccup, he's there asking why I'm not using our telemetry or networking code for the internals. It's true that if you are very, very careful, you can manage circular startup dependencies, but anyone sneezes and your app won't start or worse, drops into an infinite loop. Either you build on simpler building blocks with similar functionality, or you find a different way to organize the code.
If you're feeling lucky, you can also use zetcd  to connect ZK apps to etcd. I've been able to actually run Kafka with it as a toy project a little while ago.
I also personally find configuring and running Java applications confusing AF. Why are the configs seemingly split into different places and environment variables? Does it get clearer after dealing with Java things for a while?
I suppose you end up with Zookeeper running in Kubernetes because the only way to migrate service discovery is to have all machines report to both clusters and then start moving to reading from the new one.
You can’t just bridge two Raft protocols. If the bridge goes down even once, good luck getting consensus again. And based on the benchmarks I can find, it seems the wire protocol is part of the secret sauce for at least etcd.