diff --git a/cmd/localkube/cmd/options.go b/cmd/localkube/cmd/options.go index 3710b80ce6..5f832aa7ad 100644 --- a/cmd/localkube/cmd/options.go +++ b/cmd/localkube/cmd/options.go @@ -62,6 +62,7 @@ func AddFlags(s *localkube.LocalkubeServer) { flag.BoolVar(&s.ShouldGenerateCerts, "generate-certs", s.ShouldGenerateCerts, "If localkube should generate it's own certificates") flag.BoolVar(&s.ShowVersion, "version", s.ShowVersion, "If localkube should just print the version and exit.") flag.Var(&s.RuntimeConfig, "runtime-config", "A set of key=value pairs that describe runtime configuration that may be passed to apiserver. apis/ key can be used to turn on/off specific api versions. apis// can be used to turn on/off specific resources. api/all and api/legacy are special keys to control all and legacy api versions respectively.") + flag.IPVar(&s.NodeIP, "node-ip", s.NodeIP, "IP address of the node. If set, kubelet will use this IP address for the node.") // These two come from vendor/ packages that use flags. We should hide them flag.CommandLine.MarkHidden("google-json-key") diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index fbce14c2ba..5b129c3e49 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -76,9 +76,6 @@ func runStart(cmd *cobra.Command, args []string) { RegistryMirror: registryMirror, HostOnlyCIDR: viper.GetString(hostOnlyCIDR), } - kubernetesConfig := cluster.KubernetesConfig{ - KubernetesVersion: viper.GetString(kubernetesVersion), - } var host *host.Host start := func() (err error) { @@ -94,6 +91,15 @@ func runStart(cmd *cobra.Command, args []string) { os.Exit(1) } + ip, err := host.Driver.GetIP() + if err != nil { + glog.Errorln("Error starting host: ", err) + os.Exit(1) + } + kubernetesConfig := cluster.KubernetesConfig{ + KubernetesVersion: viper.GetString(kubernetesVersion), + NodeIP: ip, + } if err := cluster.UpdateCluster(host, host.Driver, kubernetesConfig); err != nil { glog.Errorln("Error updating cluster: ", err) os.Exit(1) @@ -104,7 +110,7 @@ func runStart(cmd *cobra.Command, args []string) { os.Exit(1) } - if err := cluster.StartCluster(host); err != nil { + if err := cluster.StartCluster(host, kubernetesConfig); err != nil { glog.Errorln("Error starting cluster: ", err) os.Exit(1) } diff --git a/pkg/localkube/kubelet.go b/pkg/localkube/kubelet.go index 46360616ae..78415739ee 100644 --- a/pkg/localkube/kubelet.go +++ b/pkg/localkube/kubelet.go @@ -41,6 +41,8 @@ func StartKubeletServer(lk LocalkubeServer) func() error { config.ClusterDomain = lk.DNSDomain config.ClusterDNS = lk.DNSIP.String() + config.NodeIP = lk.NodeIP.String() + // Use the host's resolver config if lk.Containerized { config.ResolverConfig = "/rootfs/etc/resolv.conf" diff --git a/pkg/localkube/localkube.go b/pkg/localkube/localkube.go index f29a6731dc..85348a1677 100644 --- a/pkg/localkube/localkube.go +++ b/pkg/localkube/localkube.go @@ -51,6 +51,7 @@ type LocalkubeServer struct { ShouldGenerateCerts bool ShowVersion bool RuntimeConfig config.ConfigurationMap + NodeIP net.IP } func (lk *LocalkubeServer) AddServer(server Server) { diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index f25937fc0b..25a75afc81 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -167,11 +167,12 @@ type MachineConfig struct { // KubernetesConfig contains the parameters used to configure the VM Kubernetes. type KubernetesConfig struct { KubernetesVersion string + NodeIP string } // StartCluster starts a k8s cluster on the specified Host. -func StartCluster(h sshAble) error { - commands := []string{stopCommand, GetStartCommand()} +func StartCluster(h sshAble, kubernetesConfig KubernetesConfig) error { + commands := []string{stopCommand, GetStartCommand(kubernetesConfig)} for _, cmd := range commands { glog.Infoln(cmd) diff --git a/pkg/minikube/cluster/cluster_test.go b/pkg/minikube/cluster/cluster_test.go index 0070d6c9af..ccc4ea15c8 100644 --- a/pkg/minikube/cluster/cluster_test.go +++ b/pkg/minikube/cluster/cluster_test.go @@ -82,12 +82,17 @@ func TestCreateHost(t *testing.T) { func TestStartCluster(t *testing.T) { h := tests.NewMockHost() - err := StartCluster(h) + ip, _ := h.Driver.GetIP() + kubernetesConfig := KubernetesConfig{ + NodeIP: ip, + } + + err := StartCluster(h, kubernetesConfig) if err != nil { t.Fatalf("Error starting cluster: %s", err) } - for _, cmd := range []string{stopCommand, GetStartCommand()} { + for _, cmd := range []string{stopCommand, GetStartCommand(kubernetesConfig)} { if _, ok := h.Commands[cmd]; !ok { t.Fatalf("Expected command not run: %s. Commands run: %s", cmd, h.Commands) } @@ -97,8 +102,12 @@ func TestStartCluster(t *testing.T) { func TestStartClusterError(t *testing.T) { h := tests.NewMockHost() h.Error = "error" + ip, _ := h.Driver.GetIP() + kubernetesConfig := KubernetesConfig{ + NodeIP: ip, + } - err := StartCluster(h) + err := StartCluster(h, kubernetesConfig) if err == nil { t.Fatal("Error not thrown starting cluster.") } diff --git a/pkg/minikube/cluster/commands.go b/pkg/minikube/cluster/commands.go index 063b7861cd..fe093ef2d7 100644 --- a/pkg/minikube/cluster/commands.go +++ b/pkg/minikube/cluster/commands.go @@ -29,11 +29,11 @@ var stopCommand = "sudo killall localkube || true" var startCommandFmtStr = ` # Run with nohup so it stays up. Redirect logs to useful places. -sudo sh -c 'PATH=/usr/local/sbin:$PATH nohup /usr/local/bin/localkube %s --generate-certs=false --logtostderr=true > %s 2> %s < /dev/null &' +sudo sh -c 'PATH=/usr/local/sbin:$PATH nohup /usr/local/bin/localkube %s --generate-certs=false --logtostderr=true --node-ip=%s > %s 2> %s < /dev/null &' ` var logsCommand = fmt.Sprintf("tail -n +1 %s %s", constants.RemoteLocalKubeErrPath, constants.RemoteLocalKubeOutPath) -func GetStartCommand() string { +func GetStartCommand(kubernetesConfig KubernetesConfig) string { flagVals := make([]string, len(constants.LogFlags)) for _, logFlag := range constants.LogFlags { if logVal := gflag.Lookup(logFlag); logVal != nil && logVal.Value.String() != logVal.DefValue { @@ -41,5 +41,5 @@ func GetStartCommand() string { } } flags := strings.Join(flagVals, " ") - return fmt.Sprintf(startCommandFmtStr, flags, constants.RemoteLocalKubeErrPath, constants.RemoteLocalKubeOutPath) + return fmt.Sprintf(startCommandFmtStr, flags, kubernetesConfig.NodeIP, constants.RemoteLocalKubeErrPath, constants.RemoteLocalKubeOutPath) } diff --git a/pkg/minikube/cluster/commands_test.go b/pkg/minikube/cluster/commands_test.go index f0bae62478..a7a6224e97 100644 --- a/pkg/minikube/cluster/commands_test.go +++ b/pkg/minikube/cluster/commands_test.go @@ -29,7 +29,7 @@ func TestGetStartCommandCustomValues(t *testing.T) { "vmodule": "cluster*=5", } flagMapToSetFlags(flagMap) - startCommand := GetStartCommand() + startCommand := GetStartCommand(KubernetesConfig{}) for flag, val := range flagMap { if val != "" { if expectedFlag := getSingleFlagValue(flag, val); !strings.Contains(startCommand, getSingleFlagValue(flag, val)) { diff --git a/pkg/minikube/tests/driver_mock.go b/pkg/minikube/tests/driver_mock.go index 4dc79d1c50..099f715f53 100644 --- a/pkg/minikube/tests/driver_mock.go +++ b/pkg/minikube/tests/driver_mock.go @@ -40,7 +40,7 @@ func (driver *MockDriver) Create() error { } func (driver *MockDriver) GetIP() (string, error) { - return driver.BaseDriver.GetIP() + return "127.0.0.1", nil } // GetCreateFlags returns the flags used to create a MockDriver diff --git a/pkg/minikube/tests/host_mock.go b/pkg/minikube/tests/host_mock.go index f735311022..be9f584027 100644 --- a/pkg/minikube/tests/host_mock.go +++ b/pkg/minikube/tests/host_mock.go @@ -16,7 +16,11 @@ limitations under the License. package tests -import "fmt" +import ( + "fmt" + + "github.com/docker/machine/libmachine/drivers" +) // MockHost used for testing. When commands are run, the output from CommandOutput // is used, if present. Then the output from Error is used, if present. Finally, @@ -25,12 +29,14 @@ type MockHost struct { CommandOutput map[string]string Error string Commands map[string]int + Driver drivers.Driver } func NewMockHost() *MockHost { return &MockHost{ CommandOutput: make(map[string]string), Commands: make(map[string]int), + Driver: &MockDriver{}, } }