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>
| ... | ... |
@@ -75,6 +75,8 @@ type commonBridgeConfig struct {
|
| 75 | 75 |
type NetworkConfig struct {
|
| 76 | 76 |
// Default address pools for docker networks |
| 77 | 77 |
DefaultAddressPools opts.PoolsOpt `json:"default-address-pools,omitempty"` |
| 78 |
+ // NetworkControlPlaneMTU allows to specify the control plane MTU, this will allow to optimize the network use in some components |
|
| 79 |
+ NetworkControlPlaneMTU int `json:"network-control-plane-mtu,omitempty"` |
|
| 78 | 80 |
} |
| 79 | 81 |
|
| 80 | 82 |
// CommonTLSOptions defines TLS configuration for the daemon server. |
| ... | ... |
@@ -192,8 +194,6 @@ type CommonConfig struct {
|
| 192 | 192 |
// Exposed node Generic Resources |
| 193 | 193 |
// e.g: ["orange=red", "orange=green", "orange=blue", "apple=3"] |
| 194 | 194 |
NodeGenericResources []string `json:"node-generic-resources,omitempty"` |
| 195 |
- // NetworkControlPlaneMTU allows to specify the control plane MTU, this will allow to optimize the network use in some components |
|
| 196 |
- NetworkControlPlaneMTU int `json:"network-control-plane-mtu,omitempty"` |
|
| 197 | 195 |
|
| 198 | 196 |
// ContainerAddr is the address used to connect to containerd if we're |
| 199 | 197 |
// not starting it ourselves |
| ... | ... |
@@ -69,3 +69,9 @@ func (conf *Config) GetInitPath() string {
|
| 69 | 69 |
} |
| 70 | 70 |
return DefaultInitBinary |
| 71 | 71 |
} |
| 72 |
+ |
|
| 73 |
+// GetResolvConf returns the appropriate resolv.conf |
|
| 74 |
+// Check setupResolvConf on how this is selected |
|
| 75 |
+func (conf *Config) GetResolvConf() string {
|
|
| 76 |
+ return conf.ResolvConf |
|
| 77 |
+} |
| ... | ... |
@@ -37,6 +37,8 @@ type Config struct {
|
| 37 | 37 |
ShmSize opts.MemBytes `json:"default-shm-size,omitempty"` |
| 38 | 38 |
NoNewPrivileges bool `json:"no-new-privileges,omitempty"` |
| 39 | 39 |
IpcMode string `json:"default-ipc-mode,omitempty"` |
| 40 |
+ // ResolvConf is the path to the configuration of the host resolver |
|
| 41 |
+ ResolvConf string `json:"resolv-conf,omitempty"` |
|
| 40 | 42 |
} |
| 41 | 43 |
|
| 42 | 44 |
// BridgeConfig stores all the bridge driver specific |
| ... | ... |
@@ -63,21 +63,13 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container) ([]lib |
| 63 | 63 |
|
| 64 | 64 |
if container.HostConfig.NetworkMode.IsHost() {
|
| 65 | 65 |
sboxOptions = append(sboxOptions, libnetwork.OptionUseDefaultSandbox()) |
| 66 |
- if len(container.HostConfig.ExtraHosts) == 0 {
|
|
| 67 |
- sboxOptions = append(sboxOptions, libnetwork.OptionOriginHostsPath("/etc/hosts"))
|
|
| 68 |
- } |
|
| 69 |
- if len(container.HostConfig.DNS) == 0 && len(daemon.configStore.DNS) == 0 && |
|
| 70 |
- len(container.HostConfig.DNSSearch) == 0 && len(daemon.configStore.DNSSearch) == 0 && |
|
| 71 |
- len(container.HostConfig.DNSOptions) == 0 && len(daemon.configStore.DNSOptions) == 0 {
|
|
| 72 |
- sboxOptions = append(sboxOptions, libnetwork.OptionOriginResolvConfPath("/etc/resolv.conf"))
|
|
| 73 |
- } |
|
| 74 | 66 |
} else {
|
| 75 | 67 |
// OptionUseExternalKey is mandatory for userns support. |
| 76 | 68 |
// But optional for non-userns support |
| 77 | 69 |
sboxOptions = append(sboxOptions, libnetwork.OptionUseExternalKey()) |
| 78 | 70 |
} |
| 79 | 71 |
|
| 80 |
- if err = setupPathsAndSandboxOptions(container, &sboxOptions); err != nil {
|
|
| 72 |
+ if err = daemon.setupPathsAndSandboxOptions(container, &sboxOptions); err != nil {
|
|
| 81 | 73 |
return nil, err |
| 82 | 74 |
} |
| 83 | 75 |
|
| ... | ... |
@@ -369,9 +369,17 @@ func (daemon *Daemon) isNetworkHotPluggable() bool {
|
| 369 | 369 |
return true |
| 370 | 370 |
} |
| 371 | 371 |
|
| 372 |
-func setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error {
|
|
| 372 |
+func (daemon *Daemon) setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error {
|
|
| 373 | 373 |
var err error |
| 374 | 374 |
|
| 375 |
+ if container.HostConfig.NetworkMode.IsHost() {
|
|
| 376 |
+ // Point to the host files, so that will be copied into the container running in host mode |
|
| 377 |
+ *sboxOptions = append(*sboxOptions, libnetwork.OptionOriginHostsPath("/etc/hosts"))
|
|
| 378 |
+ *sboxOptions = append(*sboxOptions, libnetwork.OptionOriginResolvConfPath("/etc/resolv.conf"))
|
|
| 379 |
+ } else {
|
|
| 380 |
+ *sboxOptions = append(*sboxOptions, libnetwork.OptionOriginResolvConfPath(daemon.configStore.GetResolvConf())) |
|
| 381 |
+ } |
|
| 382 |
+ |
|
| 375 | 383 |
container.HostsPath, err = container.GetRootResourcePath("hosts")
|
| 376 | 384 |
if err != nil {
|
| 377 | 385 |
return err |
| ... | ... |
@@ -155,7 +155,7 @@ func (daemon *Daemon) isNetworkHotPluggable() bool {
|
| 155 | 155 |
return true |
| 156 | 156 |
} |
| 157 | 157 |
|
| 158 |
-func setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error {
|
|
| 158 |
+func (daemon *Daemon) setupPathsAndSandboxOptions(container *container.Container, sboxOptions *[]libnetwork.SandboxOption) error {
|
|
| 159 | 159 |
return nil |
| 160 | 160 |
} |
| 161 | 161 |
|
| ... | ... |
@@ -581,6 +581,9 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe |
| 581 | 581 |
// Do we have a disabled network? |
| 582 | 582 |
config.DisableBridge = isBridgeNetworkDisabled(config) |
| 583 | 583 |
|
| 584 |
+ // Setup the resolv.conf |
|
| 585 |
+ setupResolvConf(config) |
|
| 586 |
+ |
|
| 584 | 587 |
// Verify the platform is supported as a daemon |
| 585 | 588 |
if !platformSupported {
|
| 586 | 589 |
return nil, errSystemNotSupported |
| ... | ... |
@@ -8,12 +8,19 @@ import ( |
| 8 | 8 |
"regexp" |
| 9 | 9 |
"strings" |
| 10 | 10 |
|
| 11 |
+ "github.com/docker/docker/daemon/config" |
|
| 12 |
+ "github.com/docker/docker/internal/procfs" |
|
| 11 | 13 |
"github.com/docker/docker/pkg/fileutils" |
| 12 | 14 |
"github.com/docker/docker/pkg/mount" |
| 13 | 15 |
"github.com/pkg/errors" |
| 14 | 16 |
"github.com/sirupsen/logrus" |
| 15 | 17 |
) |
| 16 | 18 |
|
| 19 |
+const ( |
|
| 20 |
+ defaultResolvConf = "/etc/resolv.conf" |
|
| 21 |
+ alternateResolvConf = "/run/systemd/resolve/resolv.conf" |
|
| 22 |
+) |
|
| 23 |
+ |
|
| 17 | 24 |
// On Linux, plugins use a static path for storing execution state, |
| 18 | 25 |
// instead of deriving path from daemon's exec-root. This is because |
| 19 | 26 |
// plugin socket files are created here and they cannot exceed max |
| ... | ... |
@@ -131,3 +138,30 @@ func shouldUnmountRoot(root string, info *mount.Info) bool {
|
| 131 | 131 |
} |
| 132 | 132 |
return hasMountinfoOption(info.Optional, sharedPropagationOption) |
| 133 | 133 |
} |
| 134 |
+ |
|
| 135 |
+// setupResolvConf sets the appropriate resolv.conf file if not specified |
|
| 136 |
+// When systemd-resolved is running the default /etc/resolv.conf points to |
|
| 137 |
+// localhost. In this case fetch the alternative config file that is in a |
|
| 138 |
+// different path so that containers can use it |
|
| 139 |
+// In all the other cases fallback to the default one |
|
| 140 |
+func setupResolvConf(config *config.Config) {
|
|
| 141 |
+ if config.ResolvConf != "" {
|
|
| 142 |
+ return |
|
| 143 |
+ } |
|
| 144 |
+ |
|
| 145 |
+ config.ResolvConf = defaultResolvConf |
|
| 146 |
+ pids, err := procfs.PidOf("systemd-resolved")
|
|
| 147 |
+ if err != nil {
|
|
| 148 |
+ logrus.Errorf("unable to check systemd-resolved status: %s", err)
|
|
| 149 |
+ return |
|
| 150 |
+ } |
|
| 151 |
+ if len(pids) > 0 && pids[0] > 0 {
|
|
| 152 |
+ _, err := os.Stat(alternateResolvConf) |
|
| 153 |
+ if err == nil {
|
|
| 154 |
+ logrus.Infof("systemd-resolved is running, so using resolvconf: %s", alternateResolvConf)
|
|
| 155 |
+ config.ResolvConf = alternateResolvConf |
|
| 156 |
+ return |
|
| 157 |
+ } |
|
| 158 |
+ logrus.Infof("systemd-resolved is running, but %s is not present, fallback to %s", alternateResolvConf, defaultResolvConf)
|
|
| 159 |
+ } |
|
| 160 |
+} |