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"
"regexp"
goruntime "runtime"
"strings"
l "github.com/rancher/k3d/v5/pkg/logger"
"github.com/rancher/k3d/v5/pkg/runtimes"
"github.com/rancher/k3d/v5/pkg/runtimes/docker"
k3d "github.com/rancher/k3d/v5/pkg/types"
"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)
isDockerDesktop := func(os string) bool {
return strings.ToLower(os) == "docker desktop"
}
// Docker Runtime
if runtime == runtimes.Docker {
// Docker (for Desktop) on MacOS or Windows
if isDockerDesktop(rtimeInfo.OS) {
if docker.IsDockerDesktop(rtimeInfo.OS) {
toolsNode, err := EnsureToolsNode(ctx, runtime, cluster)
if err != nil {

@ -23,6 +23,7 @@ THE SOFTWARE.
package docker
import (
"net"
"net/url"
"os"
@ -42,13 +43,43 @@ func (d Docker) ID() string {
// GetHost returns the docker daemon host
func (d Docker) GetHost() string {
// a) DOCKER_HOST env var
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)
if err != nil {
l.Log().Debugf("[Docker] GetHost: error parsing '%s' as URL: %#v", dockerHost, url)
return ""
}
l.Log().Debugf("DockerHost: %s", url.Host)
return url.Host
dockerHost = 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

@ -28,6 +28,8 @@ import (
"fmt"
"io"
"os"
"regexp"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/flags"
@ -42,6 +44,22 @@ import (
"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
func GetDefaultObjectLabelsFilter(clusterName string) filters.Args {
filters := filters.NewArgs()

Loading…
Cancel
Save