mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #40007 from arkodg/add-host-docker-internal
Support host.docker.internal in dockerd on Linux
This commit is contained in:
commit
ca20bc4214
8 changed files with 95 additions and 5 deletions
|
@ -64,6 +64,7 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) error {
|
|||
flags.Var(opts.NewListOptsRef(&conf.DNS, opts.ValidateIPAddress), "dns", "DNS server to use")
|
||||
flags.Var(opts.NewNamedListOptsRef("dns-opts", &conf.DNSOptions, nil), "dns-opt", "DNS options to use")
|
||||
flags.Var(opts.NewListOptsRef(&conf.DNSSearch, opts.ValidateDNSSearch), "dns-search", "DNS search domains to use")
|
||||
flags.Var(opts.NewIPOpt(&conf.HostGatewayIP, ""), "host-gateway-ip", "IP address that the special 'host-gateway' string in --add-host resolves to. Defaults to the IP address of the default bridge")
|
||||
flags.Var(opts.NewNamedListOptsRef("labels", &conf.Labels, opts.ValidateLabel), "label", "Set key=value labels to the daemon")
|
||||
flags.StringVar(&conf.LogConfig.Type, "log-driver", "json-file", "Default driver for container logs")
|
||||
flags.Var(opts.NewNamedMapOpts("log-opts", conf.LogConfig.Config, nil), "log-opt", "Default log driver options for containers")
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
@ -118,6 +119,7 @@ type DNSConfig struct {
|
|||
DNS []string `json:"dns,omitempty"`
|
||||
DNSOptions []string `json:"dns-opts,omitempty"`
|
||||
DNSSearch []string `json:"dns-search,omitempty"`
|
||||
HostGatewayIP net.IP `json:"host-gateway-ip,omitempty"`
|
||||
}
|
||||
|
||||
// CommonConfig defines the configuration of a docker daemon which is
|
||||
|
|
|
@ -115,6 +115,16 @@ func (daemon *Daemon) buildSandboxOptions(container *container.Container) ([]lib
|
|||
return nil, err
|
||||
}
|
||||
parts := strings.SplitN(extraHost, ":", 2)
|
||||
// If the IP Address is a string called "host-gateway", replace this
|
||||
// value with the IP address stored in the daemon level HostGatewayIP
|
||||
// config variable
|
||||
if parts[1] == network.HostGatewayName {
|
||||
gateway := daemon.configStore.HostGatewayIP.String()
|
||||
if gateway == "" {
|
||||
return nil, fmt.Errorf("unable to derive the IP value for host-gateway")
|
||||
}
|
||||
parts[1] = gateway
|
||||
}
|
||||
sboxOptions = append(sboxOptions, libnetwork.OptionExtraHost(parts[0], parts[1]))
|
||||
}
|
||||
|
||||
|
|
|
@ -932,6 +932,19 @@ func (daemon *Daemon) initNetworkController(config *config.Config, activeSandbox
|
|||
removeDefaultBridgeInterface()
|
||||
}
|
||||
|
||||
// Set HostGatewayIP to the default bridge's IP if it is empty
|
||||
if daemon.configStore.HostGatewayIP == nil && controller != nil {
|
||||
if n, err := controller.NetworkByName("bridge"); err == nil {
|
||||
v4Info, v6Info := n.Info().IpamInfo()
|
||||
var gateway net.IP
|
||||
if len(v4Info) > 0 {
|
||||
gateway = v4Info[0].Gateway.IP
|
||||
} else if len(v6Info) > 0 {
|
||||
gateway = v6Info[0].Gateway.IP
|
||||
}
|
||||
daemon.configStore.HostGatewayIP = gateway
|
||||
}
|
||||
}
|
||||
return controller, nil
|
||||
}
|
||||
|
||||
|
|
8
daemon/network/constants.go
Normal file
8
daemon/network/constants.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package network
|
||||
|
||||
const (
|
||||
// HostGatewayName is the string value that can be passed
|
||||
// to the IPAddr section in --add-host that is replaced by
|
||||
// the value of HostGatewayIP daemon config value
|
||||
HostGatewayName = "host-gateway"
|
||||
)
|
|
@ -120,3 +120,47 @@ func TestDaemonRestartIpcMode(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(string(inspect.HostConfig.IpcMode), "shareable"))
|
||||
}
|
||||
|
||||
// TestDaemonHostGatewayIP verifies that when a magic string "host-gateway" is passed
|
||||
// to ExtraHosts (--add-host) instead of an IP address, its value is set to
|
||||
// 1. Daemon config flag value specified by host-gateway-ip or
|
||||
// 2. IP of the default bridge network
|
||||
// and is added to the /etc/hosts file
|
||||
func TestDaemonHostGatewayIP(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRemoteDaemon)
|
||||
skip.If(t, testEnv.DaemonInfo.OSType == "windows")
|
||||
t.Parallel()
|
||||
|
||||
// Verify the IP in /etc/hosts is same as host-gateway-ip
|
||||
d := daemon.New(t)
|
||||
// Verify the IP in /etc/hosts is same as the default bridge's IP
|
||||
d.StartWithBusybox(t)
|
||||
c := d.NewClientT(t)
|
||||
ctx := context.Background()
|
||||
cID := container.Run(ctx, t, c,
|
||||
container.WithExtraHost("host.docker.internal:host-gateway"),
|
||||
)
|
||||
res, err := container.Exec(ctx, c, cID, []string{"cat", "/etc/hosts"})
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, is.Len(res.Stderr(), 0))
|
||||
assert.Equal(t, 0, res.ExitCode)
|
||||
inspect, err := c.NetworkInspect(ctx, "bridge", types.NetworkInspectOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Contains(res.Stdout(), inspect.IPAM.Config[0].Gateway))
|
||||
c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true})
|
||||
d.Stop(t)
|
||||
|
||||
// Verify the IP in /etc/hosts is same as host-gateway-ip
|
||||
d.StartWithBusybox(t, "--host-gateway-ip=6.7.8.9")
|
||||
cID = container.Run(ctx, t, c,
|
||||
container.WithExtraHost("host.docker.internal:host-gateway"),
|
||||
)
|
||||
res, err = container.Exec(ctx, c, cID, []string{"cat", "/etc/hosts"})
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, is.Len(res.Stderr(), 0))
|
||||
assert.Equal(t, 0, res.ExitCode)
|
||||
assert.Check(t, is.Contains(res.Stdout(), "6.7.8.9"))
|
||||
c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true})
|
||||
d.Stop(t)
|
||||
|
||||
}
|
||||
|
|
|
@ -180,3 +180,11 @@ func WithCgroupnsMode(mode string) func(*TestContainerConfig) {
|
|||
c.HostConfig.CgroupnsMode = containertypes.CgroupnsMode(mode)
|
||||
}
|
||||
}
|
||||
|
||||
// WithExtraHost sets the user defined IP:Host mappings in the container's
|
||||
// /etc/hosts file
|
||||
func WithExtraHost(extraHost string) func(*TestContainerConfig) {
|
||||
return func(c *TestContainerConfig) {
|
||||
c.HostConfig.ExtraHosts = append(c.HostConfig.ExtraHosts, extraHost)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/daemon/network"
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
)
|
||||
|
||||
|
@ -169,8 +170,11 @@ func ValidateExtraHost(val string) (string, error) {
|
|||
if len(arr) != 2 || len(arr[0]) == 0 {
|
||||
return "", fmt.Errorf("bad format for add-host: %q", val)
|
||||
}
|
||||
// Skip IPaddr validation for special "host-gateway" string
|
||||
if arr[1] != network.HostGatewayName {
|
||||
if _, err := ValidateIPAddress(arr[1]); err != nil {
|
||||
return "", fmt.Errorf("invalid IP address in add-host: %q", arr[1])
|
||||
}
|
||||
}
|
||||
return val, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue