<p>I am building a microservices based application and would like to use Consul as service registry. All in all I have three scenarios:</p>

<ul>
<li>All the services run on the host.</li>
<li>All the services run on the host, but Consul runs in Docker.</li>
<li>All the services and Consul run in Docker.</li>
</ul>

<p>Now I have the problem of how to register the services with their IP address, because I need to figure out their IP address so that it is reachable by Consul (e.g., for the health checks):</p>

<ul>
<li>If everything runs on the same host, it's pretty easy: Simply use <code>127.0.0.1</code>, and you're done.</li>
<li>If everything (including Consul) runs in Docker, I could use <code>hostname -i</code> from within the Docker containers to figure out their external IP and hand it over to Consul. This works, but I wonder if there is  a better way to solve this? (Ideally, the solution should also work in the same way on Kubernetes.)</li>
<li>If the services run on the host, but Consul runs in Docker, right now I am missing any idea at all. Basically, Consul requires the host's IP address to be able to talk to the services, but I can only detect this from within the Consul container (by resolving <code>host.docker.internal</code>). But first, this does not work from externally, and second it only works for Docker for Mac / Windows, not e.g. with Kubernetes.</li>
</ul>

<p>How could I solve these issues?</p>

<p>PS: I would like to avoid using a container such as <code>registrator</code> by Gliderlabs, since I have doubts how well this works on Kubernetes, and also it won't help with the mixed Docker / host scenario.</p>

Golo Roden
<p>If you're using Kubernetes, you might start by checking whether its <a href="https://kubernetes.io/docs/concepts/services-networking/service/" rel="nofollow noreferrer">built-in service registry</a> meets your needs.  There's generally not a direct path to reach a pod via its node's host's IP address, so the setup you describe won't really work well.  (I might consider Consul for a key/value store but I wouldn't reach for it as a service registry in Kubernetes land.)</p>

<p>In plain multi-host Docker land, this is one of the few situations I've found where host networking is appropriate.  Start Consul with <code>--net host</code> or an equivalent option in Docker Compose or another orchestration tool.  Then Consul will believe "its" IP address is the host's, and if you have automated TCP probes of well-known ports, you can search every service that's running on the host and discover <em>e.g.</em> a MySQL service on port 3306, whether running in a container or natively on the host.</p>

<p>With this setup, <code>servicename.service.consul</code> will resolve to some physical-host IP address.  If you have a Docker container pointing at its current host for DNS service, then that will route a service to some host, maybe the same one, but this has worked reliably for me in the past.</p>

<p>Note that the relevant hostnames will be different in different environments: <code>servicename.service.consul</code> for a Consul-based setup, <code>servicename.namespacename.svc.cluster.local</code> in Kubernetes, maybe <code>localhost</code> in a developer-desktop environment.  You need to make sure this is configurable, most straightforwardly via an environment variable.</p>
