cluster: add support for vmwarefusion driver
Add support for the vmwarefusion driver which is greatly more stable on OSX. Also, document it in the README as an option.pull/184/head
parent
9d65272511
commit
53ee8642f8
|
@ -11,7 +11,7 @@ a single-node Kubernetes cluster inside a VM on your laptop for users looking
|
||||||
to try out Kubernetes or develop with it day-to-day.
|
to try out Kubernetes or develop with it day-to-day.
|
||||||
|
|
||||||
## Requirements For Running Minikube
|
## Requirements For Running Minikube
|
||||||
* VirtualBox installation
|
* [VirtualBox](https://www.virtualbox.org/wiki/Downloads) or [VMware Fusion](https://www.vmware.com/products/fusion) installation
|
||||||
* VT-x/AMD-v virtualization must be enabled in BIOS
|
* VT-x/AMD-v virtualization must be enabled in BIOS
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
@ -20,6 +20,8 @@ See the installation instructions for the [latest release](https://github.com/ku
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Here's a brief demo of minikube usage. We're using the code from this [Kubernetes tutorial](http://kubernetes.io/docs/hellonode/).
|
Here's a brief demo of minikube usage. We're using the code from this [Kubernetes tutorial](http://kubernetes.io/docs/hellonode/).
|
||||||
|
If you want to change the VM driver to VMware Fusion add the `--vm-driver=vmwarefusion` flag to `minikube start`.
|
||||||
|
|
||||||
Note that the IP below is dynamic and can change. It can be retrieved with `minikube ip`.
|
Note that the IP below is dynamic and can change. It can be retrieved with `minikube ip`.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|
|
@ -34,6 +34,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
minikubeISO string
|
minikubeISO string
|
||||||
|
vmDriver string
|
||||||
)
|
)
|
||||||
|
|
||||||
// startCmd represents the start command
|
// startCmd represents the start command
|
||||||
|
@ -52,6 +53,7 @@ func runStart(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
config := cluster.MachineConfig{
|
config := cluster.MachineConfig{
|
||||||
MinikubeISO: minikubeISO,
|
MinikubeISO: minikubeISO,
|
||||||
|
VMDriver: vmDriver,
|
||||||
}
|
}
|
||||||
|
|
||||||
var host *host.Host
|
var host *host.Host
|
||||||
|
@ -150,5 +152,6 @@ func setupKubeconfig(name, server, certAuth, cliCert, cliKey string) (activeCont
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
startCmd.Flags().StringVarP(&minikubeISO, "iso-url", "", constants.DefaultIsoUrl, "Location of the minikube iso")
|
startCmd.Flags().StringVarP(&minikubeISO, "iso-url", "", constants.DefaultIsoUrl, "Location of the minikube iso")
|
||||||
|
startCmd.Flags().StringVarP(&vmDriver, "vm-driver", "", constants.DefaultVMDriver, fmt.Sprintf("VM driver is one of: %v", constants.SupportedVMDrivers))
|
||||||
RootCmd.AddCommand(startCmd)
|
RootCmd.AddCommand(startCmd)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ minikube start
|
||||||
|
|
||||||
```
|
```
|
||||||
--iso-url="https://storage.googleapis.com/minikube/minikube-0.3.iso": Location of the minikube iso
|
--iso-url="https://storage.googleapis.com/minikube/minikube-0.3.iso": Location of the minikube iso
|
||||||
|
--vm-driver="virtualbox": VM driver is one of: [virtualbox vmwarefusion]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options inherited from parent commands
|
### Options inherited from parent commands
|
||||||
|
|
|
@ -155,6 +155,7 @@ type sshAble interface {
|
||||||
// MachineConfig contains the parameters used to start a cluster.
|
// MachineConfig contains the parameters used to start a cluster.
|
||||||
type MachineConfig struct {
|
type MachineConfig struct {
|
||||||
MinikubeISO string
|
MinikubeISO string
|
||||||
|
VMDriver string
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartCluster starts a k8s cluster on the specified Host.
|
// StartCluster starts a k8s cluster on the specified Host.
|
||||||
|
@ -261,15 +262,25 @@ func SetupCerts(d drivers.Driver) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createHost(api libmachine.API, config MachineConfig) (*host.Host, error) {
|
func createHost(api libmachine.API, config MachineConfig) (*host.Host, error) {
|
||||||
driver := virtualbox.NewDriver(constants.MachineName, constants.Minipath)
|
var driver drivers.Driver
|
||||||
driver.Boot2DockerURL = config.MinikubeISO
|
|
||||||
|
switch config.VMDriver {
|
||||||
|
case "virtualbox":
|
||||||
|
d := virtualbox.NewDriver(constants.MachineName, constants.Minipath)
|
||||||
|
d.Boot2DockerURL = config.MinikubeISO
|
||||||
|
driver = d
|
||||||
|
case "vmwarefusion":
|
||||||
|
driver = createVMwareFusionHost(config)
|
||||||
|
default:
|
||||||
|
glog.Exitf("Unsupported driver: %s\n", config.VMDriver)
|
||||||
|
}
|
||||||
|
|
||||||
data, err := json.Marshal(driver)
|
data, err := json.Marshal(driver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
driverName := "virtualbox"
|
h, err := api.NewHost(config.VMDriver, data)
|
||||||
h, err := api.NewHost(driverName, data)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error creating new host: %s", err)
|
return nil, fmt.Errorf("Error creating new host: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cluster
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/docker/machine/drivers/vmwarefusion"
|
||||||
|
"github.com/docker/machine/libmachine/drivers"
|
||||||
|
"k8s.io/minikube/pkg/minikube/constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createVMwareFusionHost(config MachineConfig) drivers.Driver {
|
||||||
|
d := vmwarefusion.NewDriver(constants.MachineName, constants.Minipath).(*vmwarefusion.Driver)
|
||||||
|
d.Boot2DockerURL = config.MinikubeISO
|
||||||
|
|
||||||
|
// TODO(philips): push these defaults upstream to fixup this driver
|
||||||
|
d.CPU = 1
|
||||||
|
d.SSHPort = 22
|
||||||
|
d.ISO = d.ResolveStorePath("boot2docker.iso")
|
||||||
|
return d
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
// +build !darwin
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cluster
|
||||||
|
|
||||||
|
import "github.com/docker/machine/libmachine/drivers"
|
||||||
|
|
||||||
|
func createVMwareFusionHost(config MachineConfig) drivers.Driver {
|
||||||
|
panic("vmwarefusion not supported")
|
||||||
|
}
|
|
@ -32,6 +32,8 @@ import (
|
||||||
"k8s.io/minikube/pkg/minikube/tests"
|
"k8s.io/minikube/pkg/minikube/tests"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var defaultMachineConfig = MachineConfig{VMDriver: constants.DefaultVMDriver}
|
||||||
|
|
||||||
func TestCreateHost(t *testing.T) {
|
func TestCreateHost(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
|
|
||||||
|
@ -39,7 +41,7 @@ func TestCreateHost(t *testing.T) {
|
||||||
if exists {
|
if exists {
|
||||||
t.Fatal("Machine already exists.")
|
t.Fatal("Machine already exists.")
|
||||||
}
|
}
|
||||||
_, err := createHost(api, MachineConfig{})
|
_, err := createHost(api, defaultMachineConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error creating host: %v", err)
|
t.Fatalf("Error creating host: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -57,8 +59,16 @@ func TestCreateHost(t *testing.T) {
|
||||||
t.Fatalf("Machine is not running. State is: %s", s)
|
t.Fatalf("Machine is not running. State is: %s", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.DriverName != "virtualbox" {
|
found := false
|
||||||
t.Fatalf("Wrong driver name: %v. Should be virtualbox.", h.DriverName)
|
for _, driver := range constants.SupportedVMDrivers {
|
||||||
|
if h.DriverName == driver {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
t.Fatalf("Wrong driver name: %v. Should be virtualbox or vmwarefusion.", h.DriverName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +127,7 @@ func TestStartClusterError(t *testing.T) {
|
||||||
func TestStartHostExists(t *testing.T) {
|
func TestStartHostExists(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
// Create an initial host.
|
// Create an initial host.
|
||||||
_, err := createHost(api, MachineConfig{})
|
_, err := createHost(api, defaultMachineConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error creating host: %v", err)
|
t.Fatalf("Error creating host: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -129,7 +139,7 @@ func TestStartHostExists(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should pass without calling Create because the host exists already.
|
// This should pass without calling Create because the host exists already.
|
||||||
h, err := StartHost(api, MachineConfig{})
|
h, err := StartHost(api, defaultMachineConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Error starting host.")
|
t.Fatal("Error starting host.")
|
||||||
}
|
}
|
||||||
|
@ -144,7 +154,7 @@ func TestStartHostExists(t *testing.T) {
|
||||||
func TestStartStoppedHost(t *testing.T) {
|
func TestStartStoppedHost(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
// Create an initial host.
|
// Create an initial host.
|
||||||
h, err := createHost(api, MachineConfig{})
|
h, err := createHost(api, defaultMachineConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error creating host: %v", err)
|
t.Fatalf("Error creating host: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -152,7 +162,7 @@ func TestStartStoppedHost(t *testing.T) {
|
||||||
h.Driver = &d
|
h.Driver = &d
|
||||||
d.CurrentState = state.Stopped
|
d.CurrentState = state.Stopped
|
||||||
|
|
||||||
h, err = StartHost(api, MachineConfig{})
|
h, err = StartHost(api, defaultMachineConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Error starting host.")
|
t.Fatal("Error starting host.")
|
||||||
}
|
}
|
||||||
|
@ -172,7 +182,7 @@ func TestStartStoppedHost(t *testing.T) {
|
||||||
func TestStartHost(t *testing.T) {
|
func TestStartHost(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
|
|
||||||
h, err := StartHost(api, MachineConfig{})
|
h, err := StartHost(api, defaultMachineConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Error starting host.")
|
t.Fatal("Error starting host.")
|
||||||
}
|
}
|
||||||
|
@ -196,7 +206,7 @@ func TestStopHostError(t *testing.T) {
|
||||||
|
|
||||||
func TestStopHost(t *testing.T) {
|
func TestStopHost(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
h, _ := createHost(api, MachineConfig{})
|
h, _ := createHost(api, defaultMachineConfig)
|
||||||
if err := StopHost(api); err != nil {
|
if err := StopHost(api); err != nil {
|
||||||
t.Fatal("An error should be thrown when stopping non-existing machine.")
|
t.Fatal("An error should be thrown when stopping non-existing machine.")
|
||||||
}
|
}
|
||||||
|
@ -227,7 +237,7 @@ Error 2`
|
||||||
|
|
||||||
func TestDeleteHost(t *testing.T) {
|
func TestDeleteHost(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
createHost(api, MachineConfig{})
|
createHost(api, defaultMachineConfig)
|
||||||
|
|
||||||
if err := DeleteHost(api); err != nil {
|
if err := DeleteHost(api); err != nil {
|
||||||
t.Fatalf("Unexpected error deleting host: %s", err)
|
t.Fatalf("Unexpected error deleting host: %s", err)
|
||||||
|
@ -236,7 +246,7 @@ func TestDeleteHost(t *testing.T) {
|
||||||
|
|
||||||
func TestDeleteHostErrorDeletingVM(t *testing.T) {
|
func TestDeleteHostErrorDeletingVM(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
h, _ := createHost(api, MachineConfig{})
|
h, _ := createHost(api, defaultMachineConfig)
|
||||||
|
|
||||||
d := &tests.MockDriver{RemoveError: true}
|
d := &tests.MockDriver{RemoveError: true}
|
||||||
|
|
||||||
|
@ -250,7 +260,7 @@ func TestDeleteHostErrorDeletingVM(t *testing.T) {
|
||||||
func TestDeleteHostErrorDeletingFiles(t *testing.T) {
|
func TestDeleteHostErrorDeletingFiles(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
api.RemoveError = true
|
api.RemoveError = true
|
||||||
createHost(api, MachineConfig{})
|
createHost(api, defaultMachineConfig)
|
||||||
|
|
||||||
if err := DeleteHost(api); err == nil {
|
if err := DeleteHost(api); err == nil {
|
||||||
t.Fatal("Expected error deleting host.")
|
t.Fatal("Expected error deleting host.")
|
||||||
|
@ -260,7 +270,7 @@ func TestDeleteHostErrorDeletingFiles(t *testing.T) {
|
||||||
func TestDeleteHostMultipleErrors(t *testing.T) {
|
func TestDeleteHostMultipleErrors(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
api.RemoveError = true
|
api.RemoveError = true
|
||||||
h, _ := createHost(api, MachineConfig{})
|
h, _ := createHost(api, defaultMachineConfig)
|
||||||
|
|
||||||
d := &tests.MockDriver{RemoveError: true}
|
d := &tests.MockDriver{RemoveError: true}
|
||||||
|
|
||||||
|
@ -295,7 +305,7 @@ func TestGetHostStatus(t *testing.T) {
|
||||||
|
|
||||||
checkState("Does Not Exist")
|
checkState("Does Not Exist")
|
||||||
|
|
||||||
createHost(api, MachineConfig{})
|
createHost(api, defaultMachineConfig)
|
||||||
checkState(state.Running.String())
|
checkState(state.Running.String())
|
||||||
|
|
||||||
StopHost(api)
|
StopHost(api)
|
||||||
|
@ -335,7 +345,7 @@ func TestSetupCerts(t *testing.T) {
|
||||||
|
|
||||||
func TestGetHostDockerEnv(t *testing.T) {
|
func TestGetHostDockerEnv(t *testing.T) {
|
||||||
api := tests.NewMockAPI()
|
api := tests.NewMockAPI()
|
||||||
h, err := createHost(api, MachineConfig{})
|
h, err := createHost(api, defaultMachineConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error creating host: %v", err)
|
t.Fatalf("Error creating host: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,12 @@ var LogFlags = [...]string{
|
||||||
}
|
}
|
||||||
|
|
||||||
const DefaultIsoUrl = "https://storage.googleapis.com/minikube/minikube-0.3.iso"
|
const DefaultIsoUrl = "https://storage.googleapis.com/minikube/minikube-0.3.iso"
|
||||||
|
const DefaultVMDriver = "virtualbox"
|
||||||
|
|
||||||
|
var SupportedVMDrivers = [...]string{
|
||||||
|
"virtualbox",
|
||||||
|
"vmwarefusion",
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RemoteLocalKubeErrPath = "/var/log/localkube.err"
|
RemoteLocalKubeErrPath = "/var/log/localkube.err"
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/docker/machine/drivers/virtualbox"
|
"github.com/docker/machine/drivers/virtualbox"
|
||||||
|
"github.com/docker/machine/drivers/vmwarefusion"
|
||||||
"github.com/docker/machine/libmachine/drivers/plugin"
|
"github.com/docker/machine/libmachine/drivers/plugin"
|
||||||
"github.com/docker/machine/libmachine/drivers/plugin/localbinary"
|
"github.com/docker/machine/libmachine/drivers/plugin/localbinary"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
@ -32,6 +33,8 @@ func StartDriver() {
|
||||||
switch driverName {
|
switch driverName {
|
||||||
case "virtualbox":
|
case "virtualbox":
|
||||||
plugin.RegisterDriver(virtualbox.NewDriver("", ""))
|
plugin.RegisterDriver(virtualbox.NewDriver("", ""))
|
||||||
|
case "vmwarefusion":
|
||||||
|
plugin.RegisterDriver(vmwarefusion.NewDriver("", ""))
|
||||||
default:
|
default:
|
||||||
glog.Exitf("Unsupported driver: %s\n", driverName)
|
glog.Exitf("Unsupported driver: %s\n", driverName)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue