From de6e845abdd1f1853d80ee46c85df768bcade274 Mon Sep 17 00:00:00 2001 From: Andy Zhou Date: Wed, 29 May 2019 08:12:32 -0700 Subject: [PATCH 1/2] Support docker machine for kubeconfig.yaml The kubeconfig.yaml generated by K3S uses local host as the host name by default. It won't work when running with docker machine. This patch detects if the docker environment is set up with docker machine. If it is, then replace the host name to the IP address of the docker machine. --- cli/cluster.go | 20 ++++++++++++++++++-- cli/docker-machine.go | 26 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 cli/docker-machine.go diff --git a/cli/cluster.go b/cli/cluster.go index 68151fc2..96e544d0 100644 --- a/cli/cluster.go +++ b/cli/cluster.go @@ -9,6 +9,7 @@ import ( "os" "path" "strconv" + "strings" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" @@ -139,8 +140,23 @@ func createKubeConfigFile(cluster string) error { } defer kubeconfigfile.Close() - // write to file, skipping the first 512 bytes which contain file metadata and trimming any NULL characters - _, err = kubeconfigfile.Write(bytes.Trim(readBytes[512:], "\x00")) + // write to file, skipping the first 512 bytes which contain file metadata + // and trimming any NULL characters + trimBytes := bytes.Trim(readBytes[512:], "\x00") + + // If running on a docker machine, replace localhost with + // docker machine's IP + dockerMachineIp, err := getDockerMachineIp() + if err != nil { + return err + } + + if dockerMachineIp != "" { + s := string(trimBytes) + s = strings.Replace(s, "localhost", dockerMachineIp, 1) + trimBytes = []byte(s) + } + _, err = kubeconfigfile.Write(trimBytes) if err != nil { return fmt.Errorf("ERROR: couldn't write to kubeconfig.yaml\n%+v", err) } diff --git a/cli/docker-machine.go b/cli/docker-machine.go new file mode 100644 index 00000000..f0d243cf --- /dev/null +++ b/cli/docker-machine.go @@ -0,0 +1,26 @@ +package run + +import ( + "os" + "os/exec" + "strings" +) + +func getDockerMachineIp() (string, error) { + machine := os.ExpandEnv("$DOCKER_MACHINE_NAME") + + if machine == "" { + return "", nil + } + + dockerMachinePath, err := exec.LookPath("docker-machine") + if err != nil { + return "", err + } + + out, err := exec.Command(dockerMachinePath, "ip").Output() + + ipStr := strings.TrimSuffix(string(out), "\n") + ipStr = strings.TrimSuffix(ipStr, "\r") + return ipStr, err +} From f3ec16941487104195a88c9a18d3e59744e30b8b Mon Sep 17 00:00:00 2001 From: Andy Zhou Date: Wed, 29 May 2019 09:03:30 -0700 Subject: [PATCH 2/2] Add docker machine IP to SAN When running on a docker machine, the default X598 certificate does not allow access via docker machine's IP. This patch fixes this by adding "--tls-san " to the K3S server argument list. --- cli/commands.go | 7 +++++++ cli/docker-machine.go | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cli/commands.go b/cli/commands.go index 3fe64c26..b499cadd 100644 --- a/cli/commands.go +++ b/cli/commands.go @@ -106,6 +106,13 @@ func CreateCluster(c *cli.Context) error { log.Println("INFO: As of v2.0.0 --port will be used for arbitrary port mapping. Please use --api-port/-a instead for configuring the Api Port") } k3sServerArgs := []string{"--https-listen-port", c.String("api-port")} + if ip, err := getDockerMachineIp(); ip != "" || err != nil { + if err != nil { + return err + } + log.Printf("Add TLS SAN for %s", ip) + k3sServerArgs = append(k3sServerArgs, "--tls-san", ip) + } if c.IsSet("server-arg") || c.IsSet("x") { k3sServerArgs = append(k3sServerArgs, c.StringSlice("server-arg")...) } diff --git a/cli/docker-machine.go b/cli/docker-machine.go index f0d243cf..b263d93e 100644 --- a/cli/docker-machine.go +++ b/cli/docker-machine.go @@ -18,7 +18,7 @@ func getDockerMachineIp() (string, error) { return "", err } - out, err := exec.Command(dockerMachinePath, "ip").Output() + out, err := exec.Command(dockerMachinePath, "ip", machine).Output() ipStr := strings.TrimSuffix(string(out), "\n") ipStr = strings.TrimSuffix(ipStr, "\r")