Fixes for resolv.conf

Handle the case of systemd-resolved, and if in place
use a different resolv.conf source.
Set appropriately the option on libnetwork.
Move unix specific code to container_operation_unix

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
This commit is contained in:
Flavio Crisciani 2018-07-17 12:11:38 -07:00
parent 0fc52ca6dd
commit e353e7e3f0
No known key found for this signature in database
GPG Key ID: 28CAFCE754CF3A48
10 changed files with 65 additions and 13 deletions

View File

@ -75,6 +75,8 @@ type commonBridgeConfig struct {
type NetworkConfig struct { type NetworkConfig struct {
// Default address pools for docker networks // Default address pools for docker networks
DefaultAddressPools opts.PoolsOpt `json:"default-address-pools,omitempty"` DefaultAddressPools opts.PoolsOpt `json:"default-address-pools,omitempty"`
// NetworkControlPlaneMTU allows to specify the control plane MTU, this will allow to optimize the network use in some components
NetworkControlPlaneMTU int `json:"network-control-plane-mtu,omitempty"`
} }
// CommonTLSOptions defines TLS configuration for the daemon server. // CommonTLSOptions defines TLS configuration for the daemon server.
@ -192,8 +194,6 @@ type CommonConfig struct {
// Exposed node Generic Resources // Exposed node Generic Resources
// e.g: ["orange=red", "orange=green", "orange=blue", "apple=3"] // e.g: ["orange=red", "orange=green", "orange=blue", "apple=3"]
NodeGenericResources []string `json:"node-generic-resources,omitempty"` NodeGenericResources []string `json:"node-generic-resources,omitempty"`
// NetworkControlPlaneMTU allows to specify the control plane MTU, this will allow to optimize the network use in some components
NetworkControlPlaneMTU int `json:"network-control-plane-mtu,omitempty"`
// ContainerAddr is the address used to connect to containerd if we're // ContainerAddr is the address used to connect to containerd if we're
// not starting it ourselves // not starting it ourselves

View File

@ -69,3 +69,9 @@ func (conf *Config) GetInitPath() string {
} }
return DefaultInitBinary return DefaultInitBinary
} }
// GetResolvConf returns the appropriate resolv.conf
// Check setupResolvConf on how this is selected
func (conf *Config) GetResolvConf() string {
return conf.ResolvConf
}

View File

@ -37,6 +37,8 @@ type Config struct {
ShmSize opts.MemBytes `json:"default-shm-size,omitempty"` ShmSize opts.MemBytes `json:"default-shm-size,omitempty"`
NoNewPrivileges bool `json:"no-new-privileges,omitempty"` NoNewPrivileges bool `json:"no-new-privileges,omitempty"`
IpcMode string `json:"default-ipc-mode,omitempty"` IpcMode string `json:"default-ipc-mode,omitempty"`
// ResolvConf is the path to the configuration of the host resolver
ResolvConf string `json:"resolv-conf,omitempty"`
} }
// BridgeConfig stores all the bridge driver specific // BridgeConfig stores all the bridge driver specific

View File

@ -63,21 +63,13 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container) ([]lib
if container.HostConfig.NetworkMode.IsHost() { if container.HostConfig.NetworkMode.IsHost() {
sboxOptions = append(sboxOptions, libnetwork.OptionUseDefaultSandbox()) sboxOptions = append(sboxOptions, libnetwork.OptionUseDefaultSandbox())
if len(container.HostConfig.ExtraHosts) == 0 {
sboxOptions = append(sboxOptions, libnetwork.OptionOriginHostsPath("/etc/hosts"))
}
if len(container.HostConfig.DNS) == 0 && len(daemon.configStore.DNS) == 0 &&
len(container.HostConfig.DNSSearch) == 0 && len(daemon.configStore.DNSSearch) == 0 &&
len(container.HostConfig.DNSOptions) == 0 && len(daemon.configStore.DNSOptions) == 0 {
sboxOptions = append(sboxOptions, libnetwork.OptionOriginResolvConfPath("/etc/resolv.conf"))
}
} else { } else {
// OptionUseExternalKey is mandatory for userns support. // OptionUseExternalKey is mandatory for userns support.
// But optional for non-userns support // But optional for non-userns support
sboxOptions = append(sboxOptions, libnetwork.OptionUseExternalKey()) sboxOptions = append(sboxOptions, libnetwork.OptionUseExternalKey())
} }
if err = setupPathsAndSandboxOptions(container, &sboxOptions); err != nil { if err = daemon.setupPathsAndSandboxOptions(container, &sboxOptions); err != nil {
return nil, err return nil, err
} }

View File

@ -369,9 +369,17 @@ func (daemon *Daemon) isNetworkHotPluggable() bool {
return true return true
} }
func setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error { func (daemon *Daemon) setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error {
var err 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"))
*sboxOptions = append(*sboxOptions, libnetwork.OptionOriginResolvConfPath("/etc/resolv.conf"))
} else {
*sboxOptions = append(*sboxOptions, libnetwork.OptionOriginResolvConfPath(daemon.configStore.GetResolvConf()))
}
container.HostsPath, err = container.GetRootResourcePath("hosts") container.HostsPath, err = container.GetRootResourcePath("hosts")
if err != nil { if err != nil {
return err return err

View File

@ -155,7 +155,7 @@ func (daemon *Daemon) isNetworkHotPluggable() bool {
return true return true
} }
func setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error { func (daemon *Daemon) setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error {
return nil return nil
} }

View File

@ -581,6 +581,9 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe
// Do we have a disabled network? // Do we have a disabled network?
config.DisableBridge = isBridgeNetworkDisabled(config) config.DisableBridge = isBridgeNetworkDisabled(config)
// Setup the resolv.conf
setupResolvConf(config)
// Verify the platform is supported as a daemon // Verify the platform is supported as a daemon
if !platformSupported { if !platformSupported {
return nil, errSystemNotSupported return nil, errSystemNotSupported

View File

@ -8,12 +8,19 @@ import (
"regexp" "regexp"
"strings" "strings"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/internal/procfs"
"github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/fileutils"
"github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/mount"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
const (
defaultResolvConf = "/etc/resolv.conf"
alternateResolvConf = "/run/systemd/resolve/resolv.conf"
)
// On Linux, plugins use a static path for storing execution state, // On Linux, plugins use a static path for storing execution state,
// instead of deriving path from daemon's exec-root. This is because // instead of deriving path from daemon's exec-root. This is because
// plugin socket files are created here and they cannot exceed max // plugin socket files are created here and they cannot exceed max
@ -131,3 +138,30 @@ func shouldUnmountRoot(root string, info *mount.Info) bool {
} }
return hasMountinfoOption(info.Optional, sharedPropagationOption) return hasMountinfoOption(info.Optional, sharedPropagationOption)
} }
// setupResolvConf sets the appropriate resolv.conf file if not specified
// When systemd-resolved is running the default /etc/resolv.conf points to
// localhost. In this case fetch the alternative config file that is in a
// different path so that containers can use it
// In all the other cases fallback to the default one
func setupResolvConf(config *config.Config) {
if config.ResolvConf != "" {
return
}
config.ResolvConf = defaultResolvConf
pids, err := procfs.PidOf("systemd-resolved")
if err != nil {
logrus.Errorf("unable to check systemd-resolved status: %s", err)
return
}
if len(pids) > 0 && pids[0] > 0 {
_, err := os.Stat(alternateResolvConf)
if err == nil {
logrus.Infof("systemd-resolved is running, so using resolvconf: %s", alternateResolvConf)
config.ResolvConf = alternateResolvConf
return
}
logrus.Infof("systemd-resolved is running, but %s is not present, fallback to %s", alternateResolvConf, defaultResolvConf)
}
}

View File

@ -1,5 +1,9 @@
// +build !linux,!freebsd,!windows // +build !linux,!freebsd,!windows
package daemon // import "github.com/docker/docker/daemon" package daemon // import "github.com/docker/docker/daemon"
import "github.com/docker/docker/daemon/config"
const platformSupported = false const platformSupported = false
func setupResolvConf(config *config.Config) {
}

View File

@ -653,3 +653,6 @@ func (daemon *Daemon) loadRuntimes() error {
func (daemon *Daemon) initRuntimes(_ map[string]types.Runtime) error { func (daemon *Daemon) initRuntimes(_ map[string]types.Runtime) error {
return nil return nil
} }
func setupResolvConf(config *config.Config) {
}