Merge pull request #41022 from thaJeztah/smarter_resolv

Better selection of DNS server
This commit is contained in:
Akihiro Suda 2020-06-25 21:22:33 +09:00 committed by GitHub
commit 36218123ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 58 additions and 6 deletions

View File

@ -391,13 +391,65 @@ func serviceDiscoveryOnDefaultNetwork() bool {
func (daemon *Daemon) setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error {
var err error
if container.HostConfig.NetworkMode.IsHost() {
// Point to the host files, so that will be copied into the container running in host mode
*sboxOptions = append(*sboxOptions, libnetwork.OptionOriginHostsPath("/etc/hosts"))
}
// Set the correct paths for /etc/hosts and /etc/resolv.conf, based on the
// networking-mode of the container. Note that containers with "container"
// networking are already handled in "initializeNetworking()" before we reach
// this function, so do not have to be accounted for here.
switch {
case container.HostConfig.NetworkMode.IsHost():
// In host-mode networking, the container does not have its own networking
// namespace, so both `/etc/hosts` and `/etc/resolv.conf` should be the same
// as on the host itself. The container gets a copy of these files, but they
// may be symlinked, so resolve the original path first.
etcHosts, err := filepath.EvalSymlinks("/etc/hosts")
if err != nil {
return err
}
resolvConf, err := filepath.EvalSymlinks("/etc/resolv.conf")
if err != nil {
return err
}
// Copy the host's resolv.conf for the container (/etc/resolv.conf or /run/systemd/resolve/resolv.conf)
*sboxOptions = append(*sboxOptions, libnetwork.OptionOriginResolvConfPath(daemon.configStore.GetResolvConf()))
*sboxOptions = append(
*sboxOptions,
libnetwork.OptionOriginHostsPath(etcHosts),
libnetwork.OptionOriginResolvConfPath(resolvConf),
)
case container.HostConfig.NetworkMode.IsUserDefined():
// The container uses a user-defined network. We use the embedded DNS
// server for container name resolution and to act as a DNS forwarder
// for external DNS resolution.
// We parse the DNS server(s) that are defined in /etc/resolv.conf on
// the host, which may be a local DNS server (for example, if DNSMasq or
// systemd-resolvd are in use). The embedded DNS server forwards DNS
// resolution to the DNS server configured on the host, which in itself
// may act as a forwarder for external DNS servers.
// If systemd-resolvd is used, the "upstream" DNS servers can be found in
// /run/systemd/resolve/resolv.conf. We do not query those DNS servers
// directly, as they can be dynamically reconfigured.
resolvConf, err := filepath.EvalSymlinks("/etc/resolv.conf")
if err != nil {
return err
}
*sboxOptions = append(*sboxOptions, libnetwork.OptionOriginResolvConfPath(resolvConf))
default:
// For other situations, such as the default bridge network, container
// discovery / name resolution is handled through /etc/hosts, and no
// embedded DNS server is available. Without the embedded DNS, we
// cannot use local DNS servers on the host (for example, if DNSMasq or
// systemd-resolvd is used). If systemd-resolvd is used, we try to
// determine the external DNS servers that are used on the host.
// This situation is not ideal, because DNS servers configured in the
// container are not updated after the container is created, but the
// DNS servers on the host can be dynamically updated.
//
// Copy the host's resolv.conf for the container (/run/systemd/resolve/resolv.conf or /etc/resolv.conf)
resolvConf, err := filepath.EvalSymlinks(daemon.configStore.GetResolvConf())
if err != nil {
return err
}
*sboxOptions = append(*sboxOptions, libnetwork.OptionOriginResolvConfPath(resolvConf))
}
container.HostsPath, err = container.GetRootResourcePath("hosts")
if err != nil {