DNS support for Windows#1412
Conversation
| } | ||
|
|
||
| n.startResolver() | ||
|
|
There was a problem hiding this comment.
@msabansal Can a container be connected to only one network in Windows ? Even if that is the case today for nat networks I think we should consider the possibility in future a container can be connected to multiple networks. Hence the resolver instance should be associated with the sandbox and not per network. We already have platform specific files, sandbox_dns_unix.go and sandbox_dns_windows.go to abstract out the implementation details of startResolver.
The name/ip lookup functions are not platform specific and the service DB svcRecords is already keyed by the network ID. So the lookup functions ResolveName etc. can remain in sandbox.go and doesn't have to be refactored.
There was a problem hiding this comment.
The reason we have the resolver associated with the network is we can't distinguish a sandbox based on the request. There is a single resolver listening on the gateway IP of the network. The IP is routable from the container. In windows DNS servers are associated with a network adapter (endpoint). If there are multiple networks we will have multiple endpoints each with it's own list of dns servers (which will be the gateway IP plus any other user supplied dns servers).
There was a problem hiding this comment.
A container connected to multiple networks should be able to resolve the service names in any network its connected to. This is done by walking through all the end-points in resolveName and lookup the service DB of the network to which the EP belongs.
For Windows containers if the query from the container can be associated with only one of the networks (depending on which interface the client sends the query on) is there any way to search the other networks as well ?
There was a problem hiding this comment.
Yes. Windows DNS resolver inside the container would send out a new query for every endpoint the container is connected to so this should not be an issue. Every network connected to the container will get a query and will be able to resolve the name.
|
|
| ep.generic[netlabel.DNSServers] = dns | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
External nameservers are not a property of the endpoints. Since the windows DNS server will only try to resolve the container names and not doing the proxying (ie: forwarding queries to external servers) why is this necessary ?
There was a problem hiding this comment.
We have added this to support the --dns server options. These servers will be passed on to HNS for configuring the container. In windows dns servers are specific to network adapters and are not universal as in linux
There was a problem hiding this comment.
@msabansal its fine to have windows network adapters to have specific dns servers. But from Docker POV, the configuration is per container and this configuration is passed to libnetwork when the sandbox is created. Shouldn't we reuse that and use it per-endpoint instead of adding a new option per endpoint ?
There was a problem hiding this comment.
@mavenugo With the current libnetwork model you can have an endpoint created before the sandbox is created. We don't allow updating endpoints after they have been created. We need the DNS information before endpoint creation and the current model doesn't guarantee it.
|
One of the use cases we have had is to be able to run a DNS server in a container and use that as the resolver for other containers. Can you confirm that it will work for Windows as well ? |
|
If the host is already running a DNS server and using the default config it will bind port 53 on all IPs. In that case setting up the internal DNS on the gateway IP will fail. Will this be a limitation or are there any alternatives ? In Linux we explicitly setup the listener in the container namespace on a random port and do the port translation from port 53 to this random port to not break this use case. |
Yes that is a limitation which can't be avoided. We have no port translation facility available on windows to enable this. |
|
We currently support the concept of container scoped aliases; ie: one container can add an alias for another container's name using I think this can't be supported in Windows because of resolver being at the network level and not per container. This should also be mentioned in the caveats with other limitations we have identified. |
|
@sanimej Incorporated the changes. Not sure why this test is failing: Don't think I have any changes that should impact this. I am trying to figure it out |
|
Yes, this failure is not related to your changes. This has been fixed in the master. If you rebase to the latest master it should pass. |
mavenugo
left a comment
There was a problem hiding this comment.
Overall the code looks simple & clean. 1 minor comment regarding a change to public endpoint API which I think we can avoid.
|
@msabansal can you please rebase & resolve the conflicts ? |
|
@mavenugo Working on it. Getting it done by EOD |
network.go
Outdated
| // ResolveService returns all the backend details about the containers or hosts | ||
| // backing a service. Its purpose is to satisfy an SRV query | ||
| ResolveService(name string) ([]*net.SRV, []net.IP) | ||
|
|
There was a problem hiding this comment.
These Resolve methods are defined in the DNSBackend interface. Please remove it from the Network interface.
Its not necessary in the Sandbox interface either where its currently defined. That can be removed as well.
|
@mavenugo Done. There is one test failing but I don't think its related. I will take a look at the test soon. |
network_windows.go
Outdated
|
|
||
| func (n *network) startResolver() { | ||
| n.resolverOnce.Do(func() { | ||
| log.Warnf("Launching DNS server for network", n.Name()) |
There was a problem hiding this comment.
Accepted. Will fix all the logging related stuff asap.
network_windows.go
Outdated
| for _, subnet := range hnsresponse.Subnets { | ||
| if subnet.GatewayAddress != "" { | ||
| resolver := NewResolver(subnet.GatewayAddress, false, "", n) | ||
| log.Warnf("Binding a resolver on network %s gateway %s", n.Name(), subnet.GatewayAddress) |
|
@msabansal Other than couple of nits the changes LGTM. I will try with the changes to confirm there is no collateral for Linux. Will update by tomorrow morning. |
|
Thanks @msabansal LGTM |
|
Verified on docker master with these changes. Looks ok for the linux name resolution. I think we are good to merge if you can address couple of comments on changing Warn messages to Debug. |
Signed-off-by: msabansal <[email protected]>
Signed-off-by: msabansal <[email protected]>
|
LGTM |
This PR adds support for DNS for windows. In Windows the DNS resolver will listen on the gateway for the network which is routable from each container. If the name can be resolved we reply back with a positive answer. If the name can't be resolved we reply with a negative answer and the dns client in the container takes care of forwarding the queries to other DNS servers
Signed-off-by: msabansal [email protected]