diff --git a/components/engine/daemon/config_unix.go b/components/engine/daemon/config_unix.go index 55f56f3eb1..e9201fa494 100644 --- a/components/engine/daemon/config_unix.go +++ b/components/engine/daemon/config_unix.go @@ -50,6 +50,7 @@ type bridgeConfig struct { EnableIPForward bool `json:"ip-forward,omitempty"` EnableIPMasq bool `json:"ip-masq,omitempty"` EnableUserlandProxy bool `json:"userland-proxy,omitempty"` + UserlandProxyPath string `json:"userland-proxy-path,omitempty"` DefaultIP net.IP `json:"ip,omitempty"` IP string `json:"bip,omitempty"` FixedCIDRv6 string `json:"fixed-cidr-v6,omitempty"` @@ -84,6 +85,7 @@ func (config *Config) InstallFlags(flags *pflag.FlagSet) { flags.BoolVar(&config.bridgeConfig.InterContainerCommunication, "icc", true, "Enable inter-container communication") flags.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultIP, "0.0.0.0"), "ip", "Default IP when binding container ports") flags.BoolVar(&config.bridgeConfig.EnableUserlandProxy, "userland-proxy", true, "Use userland proxy for loopback traffic") + flags.StringVar(&config.bridgeConfig.UserlandProxyPath, "userland-proxy-path", "", "Path to the userland proxy binary") flags.BoolVar(&config.EnableCors, "api-enable-cors", false, "Enable CORS headers in the remote API, this is deprecated by --api-cors-header") flags.MarkDeprecated("api-enable-cors", "Please use --api-cors-header") flags.StringVar(&config.CgroupParent, "cgroup-parent", "", "Set parent cgroup for all containers") diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go index c35b485aff..22933fddb8 100644 --- a/components/engine/daemon/daemon_unix.go +++ b/components/engine/daemon/daemon_unix.go @@ -651,7 +651,8 @@ func driverOptions(config *Config) []nwconfig.Option { bridgeConfig := options.Generic{ "EnableIPForwarding": config.bridgeConfig.EnableIPForward, "EnableIPTables": config.bridgeConfig.EnableIPTables, - "EnableUserlandProxy": config.bridgeConfig.EnableUserlandProxy} + "EnableUserlandProxy": config.bridgeConfig.EnableUserlandProxy, + "UserlandProxyPath": config.bridgeConfig.UserlandProxyPath} bridgeOption := options.Generic{netlabel.GenericData: bridgeConfig} dOptions := []nwconfig.Option{} diff --git a/components/engine/docs/installation/binaries.md b/components/engine/docs/installation/binaries.md index 2ae4750247..c9bff3844b 100644 --- a/components/engine/docs/installation/binaries.md +++ b/components/engine/docs/installation/binaries.md @@ -146,6 +146,9 @@ For example, to install the binaries in `/usr/bin`: $ mv docker/* /usr/bin/ ``` +> **Note**: Depending on your current setup, you can specify custom paths +> for some of the binaries provided. + > **Note**: If you already have Engine installed on your host, make sure you > stop Engine before installing (`killall docker`), and install the binaries > in the same location. You can find the location of the current installation diff --git a/components/engine/docs/reference/commandline/dockerd.md b/components/engine/docs/reference/commandline/dockerd.md index b558895ea5..d134f6e102 100644 --- a/components/engine/docs/reference/commandline/dockerd.md +++ b/components/engine/docs/reference/commandline/dockerd.md @@ -78,6 +78,7 @@ Options: --tlskey=~/.docker/key.pem Path to TLS key file --tlsverify Use TLS and verify the remote --userland-proxy=true Use userland proxy for loopback traffic + --userland-proxy-path="" Path to the userland proxy binary --userns-remap User/Group setting for user namespaces -v, --version Print version information and quit ``` @@ -1149,6 +1150,7 @@ This is a full example of the allowed configuration options on Linux: "ip-forward": false, "ip-masq": false, "userland-proxy": false, + "userland-proxy-path": "/usr/libexec/docker-proxy", "ip": "0.0.0.0", "bridge": "", "bip": "", diff --git a/components/engine/integration-cli/docker_cli_daemon_test.go b/components/engine/integration-cli/docker_cli_daemon_test.go index b9d3c6c807..d00bdd02ce 100644 --- a/components/engine/integration-cli/docker_cli_daemon_test.go +++ b/components/engine/integration-cli/docker_cli_daemon_test.go @@ -2872,3 +2872,33 @@ func (s *DockerDaemonSuite) TestDaemonBackcompatPre17Volumes(c *check.C) { c.Assert(matched, checker.True, check.Commentf("did find match for %+v", m)) } } + +func (s *DockerDaemonSuite) TestDaemonWithUserlandProxyPath(c *check.C) { + testRequires(c, SameHostDaemon, DaemonIsLinux) + + dockerProxyPath, err := exec.LookPath("docker-proxy") + c.Assert(err, checker.IsNil) + tmpDir, err := ioutil.TempDir("", "test-docker-proxy") + c.Assert(err, checker.IsNil) + + newProxyPath := filepath.Join(tmpDir, "docker-proxy") + cmd := exec.Command("cp", dockerProxyPath, newProxyPath) + c.Assert(cmd.Run(), checker.IsNil) + + // custom one + c.Assert(s.d.StartWithBusybox("--userland-proxy-path", newProxyPath), checker.IsNil) + out, err := s.d.Cmd("run", "-p", "5000:5000", "busybox:latest", "true") + c.Assert(err, checker.IsNil, check.Commentf(out)) + + // try with the original one + c.Assert(s.d.Restart("--userland-proxy-path", dockerProxyPath), checker.IsNil) + out, err = s.d.Cmd("run", "-p", "5000:5000", "busybox:latest", "true") + c.Assert(err, checker.IsNil, check.Commentf(out)) + + // not exist + c.Assert(s.d.Restart("--userland-proxy-path", "/does/not/exist"), checker.IsNil) + out, err = s.d.Cmd("run", "-p", "5000:5000", "busybox:latest", "true") + c.Assert(err, checker.NotNil, check.Commentf(out)) + c.Assert(out, checker.Contains, "driver failed programming external connectivity on endpoint") + c.Assert(out, checker.Contains, "/does/not/exist: no such file or directory") +} diff --git a/components/engine/man/dockerd.8.md b/components/engine/man/dockerd.8.md index 503b76061e..84ae3df6b4 100644 --- a/components/engine/man/dockerd.8.md +++ b/components/engine/man/dockerd.8.md @@ -64,6 +64,7 @@ dockerd - Enable daemon mode [**--tlskey**[=*~/.docker/key.pem*]] [**--tlsverify**] [**--userland-proxy**[=*true*]] +[**--userland-proxy-path**[=*""*]] [**--userns-remap**[=*default*]] # DESCRIPTION @@ -272,6 +273,9 @@ output otherwise. **--userland-proxy**=*true*|*false* Rely on a userland proxy implementation for inter-container and outside-to-container loopback communications. Default is true. +**--userland-proxy-path**="" + Path to the userland proxy binary. + **--userns-remap**=*default*|*uid:gid*|*user:group*|*user*|*uid* Enable user namespaces for containers on the daemon. Specifying "default" will cause a new user and group to be created to handle UID and GID range remapping for the user namespace mappings used for contained processes. Specifying a user (or uid) and optionally a group (or gid) will cause the daemon to lookup the user and group's subordinate ID ranges for use as the user namespace mappings for contained processes.