Open lburgazzoli opened 8 years ago
👍
:+1:
We've talked about doing SRV (and TXT). I know we didn't have a pressing need for it, but we were including it in the design. @zhangkun83, do you know the status of that stuff?
I don't think anything has been done about it.
What exactly would such a resolver do? Take "dns+srv:///_etcd-server._tcp.example.com"
for example, would it fetch the SRV recrod for "example.com"
and hand over the target etcd:///<resolved-target>
to an etcd NameResolver?
I would return a list of IPs and ports associated to _etcd-server._tcp.example.com, i.e.:
$ dig +noall +answer SRV _etcd-server._tcp.example.com
_etcd-server._tcp.example.com. 300 IN SRV 0 0 2380 infra0.example.com.
_etcd-server._tcp.example.com. 300 IN SRV 0 0 2380 infra1.example.com.
_etcd-server._tcp.example.com. 300 IN SRV 0 0 2380 infra2.example.com.
So you know that you have 3 etcd servers you can use for load balancing:
infra0.example.com
are host names, not IPs. They will need a second resolution to become IPs. Under the current NameResolver
interface, if we get N SRV records, we will need to create N DnsNameResolvers to resolve these host names. It's doable.
I was concerned at first because I thought the NameResolver would also need to act as an etcd client. Now I guess it's not the case. If we changed the example to "dns+srv:///_foo-server._tcp.example.com"
it would be less confusing. So the final product of name resolution is a bunch of socket addresses to foo servers. We probably should treat the IP addresses resolved from a SRV target as equivalent addresses, and LoadBalancer may choose to round-robin throughout these SRV targets.
Ah yep sorry, I've used etcd because I'm working on it so it was the first example I had in mind. The srv record may use IPs instead of host names and may provide a priority too.
If there are no SRV records, then we should probably contact example.com. It may make sense to use dns:///example.com?service=foo-server
.
I'm unsure about that as if you do not have any record it would mean you do not have any service registered (i.e. in a kubernetes cluster) or a configuration issue (i.e. in a standard environment) and that would indicate a problem.
I would prefer to fail here and maybe have an optional retry strategy that would force a new resolution if no hosts are returned.
Before we discuss too much more, I wanted to mention that this will probably need some agreement from the other languages.
I was going for the recommendation in RFC2782:
A SRV-cognizant client SHOULD use this procedure to locate a list of servers and connect to the preferred one:
Do a lookup for QNAME=_service._protocol.target, QCLASS=IN, QTYPE=SRV. If the reply is NOERROR, ANCOUNT>0 and there is at least one SRV RR which specifies the requested Service and Protocol in the reply: <snip> else Do a lookup for QNAME=target, QCLASS=IN, QTYPE=A
But I admit it was written before SRV saw widespread use and also writes:
- Future protocols could be designed to use SRV RR lookups as the means by which clients locate their servers.
There are probably different users of grpc that would want each behavior. So we may need a way to distinguish between them.
Looking at this more, since "service" in SRV is actually the same as /etc/services and the port, then we really don't need a different syntax: dns:///example.com:etcd-server
.
That host:service syntax is supported by applications using getaddrinfo (which allows things like curl https://example.com:https/
), but it is a bit weird for Java which doesn't provide a service name → port number lookup. It would work fine in all the other implementations though, including Go.
I could understand concern for looking up SRV records all the time, thus I could understand having dns+srv:///example.com:etcd-server
to signal SRV querying. A query parameter could disable/enable fallback. I don't know if it should fallback to normal DNS resolution by default though.
SRV example for myself:
import javax.naming.directory.Attribute;
import javax.naming.directory.InitialDirContext;
public class Srv {
public static void main(String[] args) throws Exception {
InitialDirContext ctx = new InitialDirContext();
Attribute attr = ctx.getAttributes("dns:///_xmpp-server._tcp.google.com", new String[] {"SRV"})
.get("SRV");
for (int i = 0; i < attr.size(); i++) {
String s = (String) attr.get(i);
System.out.println(s);
}
}
}
@ejona86
I'm quite fine with the syntax dns:///example.com:etcd-server
, best would be as you said if the dns resolver could support both queries by setting up appropriate parameter (same thing for fallback).
However I would like to support also the form of _service._protocol.target
as this info may be provided from an external source (i.e. an environment variable) so a DnsSrvNameResolverprovider could be created whose goal is to create a DnsNameResover properly configured to do srv lookup.
Make sense ?
any progress on this ?
@lburgazzoli no progress so far. This doesn't seem to be a high priority so we have been working on more urgent stuff.
TXT (and maybe SRV) is needed for service config, so this should be a higher priority.
Service config in DNS is proposed in https://github.com/grpc/proposal/pull/5
I see that there is currently a dns name resolver and I'm wondering if a dns+srv resolver would make sense for the project:
So you would be able to resolve a target like: