Can't access service using Consul without port

I’ve successfully got a couple services running in Nomad and registering with Consul, but the one thing I am not getting is how to pass in the port for one service to communicate with another.

Nomad gives each service a different port every time its run, and I so far can only get it working if I run one, then manually get the port Nomad chose, then give that port to another job definition and run that.

Is there some way to just tell it to use the port Nomad gave?

If you put a “port” entry in the “service” stanza of your job then Nomad should register that for you in Consul; this should have the same label as a port in the “network” stanza to link the two together.

I’m doing that, and I can see the port is registered if I visit Consul UI. However, if I try using curl or making a request to http://myservice.service.consul via my program, it doesn’t work because it is assuming I mean port 80. I still have to give it the port.

Sure; if you’re just doing a ‘regular’ DNS name lookup that’s just going to give you the host name (the A record). If you do a SRV lookup, you’ll get back the host and the port.

It’s documented here.

Thanks! That sounds like what I want, but it’s still not working for me.

I have one service using an env var to get the RabbitMQ address like in the docs you sent me:

env {
	AMQP_ADDR = "amqp://admin:admin@_rabbitmq._amqp.service.consul/%2f"
	...
      }

and RabbitMQ’s job definition has this:

service {
        name = "rabbitmq"
        tags = ["amqp", "rabbitmq"]
	port = "amqp"

        check {
	  name     = "alive"
	  type     = "tcp"
	  port     = "ui"
          interval = "30s"
          timeout  = "2s"
        }
      }

This is my first foray into working more closely with DNS, so am I misunderstanding something? Should I be able to use a normal language HTTP client to request amqp://admin:admin@_mq._amqp.service.consul/%2f and it should work without a port because Consul will return a port?

> curl _rabbitmq._amqp.service.consul
curl: (7) Failed to connect to _rabbitmq._amqp.service.consul port 80: Connection refused

It’s still trying post 80.

It’s implementation-dependent; different software may or may not implement resolution of SRV records to both hostname and port, and it’s probably a fairly niche feature.

curl doesn’t do so; it’s on the list of nice-to-have todo items.

It looks like the standard Java RabbitMQ library might do so.

Gotcha, thank you! Is there a recommended way to handle this if it doesn’t implement this? Should I use the HTTP interface for Consul and then make a follow up request after I get the address and port?

Either that or make the port assignment static so that Nomad won’t assign one dynamically.

I suppose, if you’re looking at the logical conclusion, you could also use Consul Connect and proxy the connection. The client side just connects to the proxy locally on a port discoverable through the environment, and the Consul takes care of routing etc. for you.

2 Likes