Consul: make the node optional when querying the consul DNS interface for a A record

Created on 5 May 2014  路  15Comments  路  Source: hashicorp/consul

It could make sense to have the "node" part optional and keep "service" for performance and disambiguation

dig node.node.datacenter.domain
dig tag.service.service.datacenter.domain

When not provided, defaults to "node", just like defaults to the local dc if not specified

Ref : https://groups.google.com/d/topic/consul-tool/W6hEojI85Z0/discussion

thinking

Most helpful comment

I vote for a little bit flexible dns discovery description. I don't think it's a good idea to pass on (at least for me) important feature, because someone _can_ misconfigure it.

My use case is to provide DNS for node/host discovery in docker containers itself. Service discovery in a swarm cluster and with overlay network works perfectly fine.

Because I already use Consul, it would be nice to get rid of dnsmasq or like and use just Consul. Sure, there some limitations, but they don't matter much. A and SRV entries are enough for microservices.

I think it would be nice to provide something like regexp (as @matthewvalimaki already says) with parameter -discovery-service-regexp, which defaults to something like

^(?:(?P<tag>[^.]+)\.)?(?P<service>[^.]+)\.service\.(?:(?P<dc>[^.]+)\.)?(?P<domain>consul)$

for services (click on green GO button, to play with it) and similar for nodes with -discovery-node-regexp.

Maybe it should be possible to define an order, if there is an ambiguity, like -discovery-order="node,service,file:/etc/hosts,dns:8.8.8.8". Just an example.

Domain should be also optional.

@XavM would be able just define:

-discovery-node-regexp "^(?P<node>[^.]+\.)(?:node\.|[^service])(?:(?P<dc>[^.]+)\.)?(?P<domain>domain)$"

or better:

-discovery-order="service,node,file:/etc/hosts,dns:8.8.8.8"
-discovery-node-regexp "^(?P<node>[^.]+\.)(?:node\.)?(?:(?P<dc>[^.]+)\.)?(?P<domain>domain)$"

to get desired results.

It's any chance to get it? Unfortunately, go isn't language in which I can code qualified pull requests...

All 15 comments

On thinking about this more, it actually does make the lookup ambiguous. I like that the current format is evident and never ambiguous. Take this example: "a.b.consul"

That could either be a node lookup for "a" in "b" datacenter, or it could be the "a.b" node in the current datacenter. There is no way to disambiguate that. However, that would either be "a.b.node.consul" or "a.node.b.consul" in the current system, which is clear.

@armon -- I know this is closed but I stumbled over this as well. And I think there could be a better solution: Two domains could be specified, one for node's one for service's. Default would just prefix a singular domain with .node and .service as before.

This would vastly simplify non-greenfield integrations -- especially if a _new_ environment is connected to the _legacy_ (seen that a few times) world and naming for nodes _connected_ needs to follow some archaic internal DNS-guideline.

Hi @LeDominik that's an interesting approach - I'll kick this back open so we can give that some thought.

:+1:

:+1:

I would prefer having both service and node as part of the name in order to better support SSL certificates. For example: [tag.]<service>-service[.datacenter].<domain>.

Use case: there's an application that I want to resolve to a service using Consul. I also want to use SSL. The way I configure this is: http.connect('https://auth-service.mydomain.com') and this would resolve, using Consul, to the appropriate service.

Today this can be achieved with -domain flag and getting a wildcard certificate for *.service/node.mydomain.com but I would much prefer *.mydomain.com.

I do acknowledge that tags and datacenters would complicate my example even more. I have not looked at the code for this piece, but couldn't we have configurable regexp allowing any kind of combinations. It is a simple string after all. For example why couldn't I do: v1-authservice-dc1.mydomain.com where v1 is a tag, authservice (without space, dash or anything) would equal auth and service and so on. Of course deciding how to decode this would be my responsibility and Consul should default to the existing implementation.

@matthewvalimaki Wow, that makes it even _more_ complicated. We've solved that quite easily because we have a wildcard SSL certificate for *.service.datacenter.domain per datacenter and that's all that _our_ services use per convention. However we'd of course need another set of wildcard-certificates if we want to address the nodes...

@LeDominik sorry, do you mean regexp makes it more complicated? Sure it is easy to buy wildcards but not cheap and not practical if tags are used.

@matthewvalimaki no, I just wanted to point out that the current pattern is _very_ straightforward, albeit quite rigid. Maybe a configurable regex is the right idea because it truly becomes totally impractical with tags + SSL, we're currently not using them, but they are tempting.

As our services are only reachable internally (external exposure through reverse proxy / firewalls / api manager) we just generate the certificates internally so no cost associated. But getting a wildcard _per_ service (to support tags) is truly a lot of work.

@LeDominik thank you for the clarifications.

But getting a wildcard per service (to support tags) is truly a lot of work.

No doubt. You should be able to solve this partially with wildcard SNI.

For Consul developers it might be easier to offer hard-coded option where same FQDN structure is kept but with dashes instead of dots.

I vote for a little bit flexible dns discovery description. I don't think it's a good idea to pass on (at least for me) important feature, because someone _can_ misconfigure it.

My use case is to provide DNS for node/host discovery in docker containers itself. Service discovery in a swarm cluster and with overlay network works perfectly fine.

Because I already use Consul, it would be nice to get rid of dnsmasq or like and use just Consul. Sure, there some limitations, but they don't matter much. A and SRV entries are enough for microservices.

I think it would be nice to provide something like regexp (as @matthewvalimaki already says) with parameter -discovery-service-regexp, which defaults to something like

^(?:(?P<tag>[^.]+)\.)?(?P<service>[^.]+)\.service\.(?:(?P<dc>[^.]+)\.)?(?P<domain>consul)$

for services (click on green GO button, to play with it) and similar for nodes with -discovery-node-regexp.

Maybe it should be possible to define an order, if there is an ambiguity, like -discovery-order="node,service,file:/etc/hosts,dns:8.8.8.8". Just an example.

Domain should be also optional.

@XavM would be able just define:

-discovery-node-regexp "^(?P<node>[^.]+\.)(?:node\.|[^service])(?:(?P<dc>[^.]+)\.)?(?P<domain>domain)$"

or better:

-discovery-order="service,node,file:/etc/hosts,dns:8.8.8.8"
-discovery-node-regexp "^(?P<node>[^.]+\.)(?:node\.)?(?:(?P<dc>[^.]+)\.)?(?P<domain>domain)$"

to get desired results.

It's any chance to get it? Unfortunately, go isn't language in which I can code qualified pull requests...

@armon @slackpad
Before I try to dig into the code, would you like to accept pull requests? May be I have some time in two or three month.

EDIT: my proposal fixes #215. It's not really broken, but it gives @darron ability to work around his problem.

@Bessonov have you taken a look at https://www.consul.io/docs/agent/http/query.html#templates? This might help get you some of what you need already.

@slackpad I don't used it before, but I can give it a try. Hopefully this year. Thank you!

Hey all,

We talked about this today, and this is something we are not going to implement on our own. We think the current naming scheme provides clarity and consistency. Sorry!

Was this page helpful?
0 / 5 - 0 ratings