GetDockerHost to return host.docker.internal if DfD and local connection (and it's resolvable)

pull/868/head
iwilltry42 3 years ago
parent ebea3387da
commit a580edbe42
No known key found for this signature in database
GPG Key ID: 7BA57AD1CFF16110
  1. 8
      pkg/client/host.go
  2. 35
      pkg/runtimes/docker/docker.go
  3. 18
      pkg/runtimes/docker/util.go

@ -28,10 +28,10 @@ import (
"net" "net"
"regexp" "regexp"
goruntime "runtime" goruntime "runtime"
"strings"
l "github.com/rancher/k3d/v5/pkg/logger" l "github.com/rancher/k3d/v5/pkg/logger"
"github.com/rancher/k3d/v5/pkg/runtimes" "github.com/rancher/k3d/v5/pkg/runtimes"
"github.com/rancher/k3d/v5/pkg/runtimes/docker"
k3d "github.com/rancher/k3d/v5/pkg/types" k3d "github.com/rancher/k3d/v5/pkg/types"
"github.com/rancher/k3d/v5/pkg/util" "github.com/rancher/k3d/v5/pkg/util"
) )
@ -64,15 +64,11 @@ func GetHostIP(ctx context.Context, runtime runtimes.Runtime, cluster *k3d.Clust
l.Log().Tracef("GOOS: %s / Runtime OS: %s (%s)", goruntime.GOOS, rtimeInfo.OSType, rtimeInfo.OS) l.Log().Tracef("GOOS: %s / Runtime OS: %s (%s)", goruntime.GOOS, rtimeInfo.OSType, rtimeInfo.OS)
isDockerDesktop := func(os string) bool {
return strings.ToLower(os) == "docker desktop"
}
// Docker Runtime // Docker Runtime
if runtime == runtimes.Docker { if runtime == runtimes.Docker {
// Docker (for Desktop) on MacOS or Windows // Docker (for Desktop) on MacOS or Windows
if isDockerDesktop(rtimeInfo.OS) { if docker.IsDockerDesktop(rtimeInfo.OS) {
toolsNode, err := EnsureToolsNode(ctx, runtime, cluster) toolsNode, err := EnsureToolsNode(ctx, runtime, cluster)
if err != nil { if err != nil {

@ -23,6 +23,7 @@ THE SOFTWARE.
package docker package docker
import ( import (
"net"
"net/url" "net/url"
"os" "os"
@ -42,13 +43,43 @@ func (d Docker) ID() string {
// GetHost returns the docker daemon host // GetHost returns the docker daemon host
func (d Docker) GetHost() string { func (d Docker) GetHost() string {
// a) DOCKER_HOST env var
dockerHost := os.Getenv("DOCKER_HOST") dockerHost := os.Getenv("DOCKER_HOST")
if dockerHost == "" {
l.Log().Traceln("[Docker] GetHost: DOCKER_HOST empty/unset")
info, err := d.Info()
if err != nil {
l.Log().Errorf("[Docker] error getting runtime information: %v", err)
return ""
}
// b) Docker for Desktop (Win/Mac) and it's a local connection
if IsDockerDesktop(info.OS) && IsLocalConnection(info.Endpoint) {
// b.1) local DfD connection, but inside WSL, where host.docker.internal resolves to an IP, but it's not reachable
if _, ok := os.LookupEnv("WSL_DISTRO_NAME"); ok {
l.Log().Debugln("[Docker] wanted to use 'host.docker.internal' as docker host, but it's not reachable in WSL2")
return ""
}
l.Log().Debugln("[Docker] Local DfD: using 'host.docker.internal'")
dockerHost = "host.docker.internal"
if _, err := net.LookupHost(dockerHost); err != nil {
l.Log().Debugf("[Docker] wanted to use 'host.docker.internal' as docker host, but it's not resolvable locally: %v", err)
return ""
}
}
}
url, err := url.Parse(dockerHost) url, err := url.Parse(dockerHost)
if err != nil { if err != nil {
l.Log().Debugf("[Docker] GetHost: error parsing '%s' as URL: %#v", dockerHost, url)
return "" return ""
} }
l.Log().Debugf("DockerHost: %s", url.Host) dockerHost = url.Host
return url.Host // apparently, host.docker.internal is not parsed as host but
if dockerHost == "" && url.String() != "" {
dockerHost = url.String()
}
l.Log().Debugf("[Docker] DockerHost: '%s' (%+v)", dockerHost, url)
return dockerHost
} }
// GetRuntimePath returns the path of the docker socket // GetRuntimePath returns the path of the docker socket

@ -28,6 +28,8 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"regexp"
"strings"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/flags" "github.com/docker/cli/cli/flags"
@ -42,6 +44,22 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
) )
func IsDockerDesktop(os string) bool {
return strings.ToLower(os) == "docker desktop"
}
/*
* Simple Matching to detect local connection:
* - file (socket): starts with / (absolute path)
* - tcp://(localhost|127.0.0.1)
* - ssh://(localhost|127.0.0.1)
*/
var LocalConnectionRegexp = regexp.MustCompile(`^(/|((tcp|ssh)://(localhost|127\.0\.0\.1))).*`)
func IsLocalConnection(endpoint string) bool {
return LocalConnectionRegexp.Match([]byte(endpoint))
}
// GetDefaultObjectLabelsFilter returns docker type filters created from k3d labels // GetDefaultObjectLabelsFilter returns docker type filters created from k3d labels
func GetDefaultObjectLabelsFilter(clusterName string) filters.Args { func GetDefaultObjectLabelsFilter(clusterName string) filters.Args {
filters := filters.NewArgs() filters := filters.NewArgs()

Loading…
Cancel
Save