Skip to content

Commit

Permalink
Create Hyper-V External Switch (#6264)
Browse files Browse the repository at this point in the history
* Create and manager Hyper-V switch
* Adds new flag for Hyper-V driver
* Move switch creation out of chooseSwitch
Signed-off-by: Zhongcheng Lao <Zhongcheng.Lao@microsoft.com>
  • Loading branch information
laozc authored Feb 8, 2020
1 parent bbc054b commit 239be7e
Show file tree
Hide file tree
Showing 16 changed files with 433 additions and 140 deletions.
172 changes: 89 additions & 83 deletions cmd/minikube/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,59 +73,61 @@ import (
)

const (
isoURL = "iso-url"
memory = "memory"
cpus = "cpus"
humanReadableDiskSize = "disk-size"
nfsSharesRoot = "nfs-shares-root"
nfsShare = "nfs-share"
kubernetesVersion = "kubernetes-version"
hostOnlyCIDR = "host-only-cidr"
containerRuntime = "container-runtime"
criSocket = "cri-socket"
networkPlugin = "network-plugin"
enableDefaultCNI = "enable-default-cni"
hypervVirtualSwitch = "hyperv-virtual-switch"
kvmNetwork = "kvm-network"
kvmQemuURI = "kvm-qemu-uri"
kvmGPU = "kvm-gpu"
kvmHidden = "kvm-hidden"
minikubeEnvPrefix = "MINIKUBE"
defaultMemorySize = "2000mb"
installAddons = "install-addons"
defaultDiskSize = "20000mb"
keepContext = "keep-context"
createMount = "mount"
featureGates = "feature-gates"
apiServerName = "apiserver-name"
apiServerPort = "apiserver-port"
dnsDomain = "dns-domain"
serviceCIDR = "service-cluster-ip-range"
imageRepository = "image-repository"
imageMirrorCountry = "image-mirror-country"
mountString = "mount-string"
disableDriverMounts = "disable-driver-mounts"
cacheImages = "cache-images"
uuid = "uuid"
vpnkitSock = "hyperkit-vpnkit-sock"
vsockPorts = "hyperkit-vsock-ports"
embedCerts = "embed-certs"
noVTXCheck = "no-vtx-check"
downloadOnly = "download-only"
dnsProxy = "dns-proxy"
hostDNSResolver = "host-dns-resolver"
waitUntilHealthy = "wait"
force = "force"
dryRun = "dry-run"
interactive = "interactive"
waitTimeout = "wait-timeout"
nativeSSH = "native-ssh"
minimumMemorySize = "1024mb"
minimumCPUS = 2
minimumDiskSize = "2000mb"
autoUpdate = "auto-update-drivers"
hostOnlyNicType = "host-only-nic-type"
natNicType = "nat-nic-type"
isoURL = "iso-url"
memory = "memory"
cpus = "cpus"
humanReadableDiskSize = "disk-size"
nfsSharesRoot = "nfs-shares-root"
nfsShare = "nfs-share"
kubernetesVersion = "kubernetes-version"
hostOnlyCIDR = "host-only-cidr"
containerRuntime = "container-runtime"
criSocket = "cri-socket"
networkPlugin = "network-plugin"
enableDefaultCNI = "enable-default-cni"
hypervVirtualSwitch = "hyperv-virtual-switch"
hypervUseExternalSwitch = "hyperv-use-external-switch"
hypervExternalAdapter = "hyperv-external-adapter"
kvmNetwork = "kvm-network"
kvmQemuURI = "kvm-qemu-uri"
kvmGPU = "kvm-gpu"
kvmHidden = "kvm-hidden"
minikubeEnvPrefix = "MINIKUBE"
defaultMemorySize = "2000mb"
installAddons = "install-addons"
defaultDiskSize = "20000mb"
keepContext = "keep-context"
createMount = "mount"
featureGates = "feature-gates"
apiServerName = "apiserver-name"
apiServerPort = "apiserver-port"
dnsDomain = "dns-domain"
serviceCIDR = "service-cluster-ip-range"
imageRepository = "image-repository"
imageMirrorCountry = "image-mirror-country"
mountString = "mount-string"
disableDriverMounts = "disable-driver-mounts"
cacheImages = "cache-images"
uuid = "uuid"
vpnkitSock = "hyperkit-vpnkit-sock"
vsockPorts = "hyperkit-vsock-ports"
embedCerts = "embed-certs"
noVTXCheck = "no-vtx-check"
downloadOnly = "download-only"
dnsProxy = "dns-proxy"
hostDNSResolver = "host-dns-resolver"
waitUntilHealthy = "wait"
force = "force"
dryRun = "dry-run"
interactive = "interactive"
waitTimeout = "wait-timeout"
nativeSSH = "native-ssh"
minimumMemorySize = "1024mb"
minimumCPUS = 2
minimumDiskSize = "2000mb"
autoUpdate = "auto-update-drivers"
hostOnlyNicType = "host-only-nic-type"
natNicType = "nat-nic-type"
)

var (
Expand Down Expand Up @@ -227,6 +229,8 @@ func initDriverFlags() {

// hyperv
startCmd.Flags().String(hypervVirtualSwitch, "", "The hyperv virtual switch name. Defaults to first found. (hyperv driver only)")
startCmd.Flags().Bool(hypervUseExternalSwitch, false, "Whether to use external switch over Default Switch if virtual switch not explicitly specified. (hyperv driver only)")
startCmd.Flags().String(hypervExternalAdapter, "", "External Adapter on which external switch will be created if no external switch is found. (hyperv driver only)")
}

// initNetworkingFlags inits the commandline flags for connectivity related flags for start
Expand Down Expand Up @@ -943,36 +947,38 @@ func generateCfgFromFlags(cmd *cobra.Command, k8sVersion string, drvName string)
}

cfg := config.MachineConfig{
Name: viper.GetString(config.MachineProfile),
KeepContext: viper.GetBool(keepContext),
EmbedCerts: viper.GetBool(embedCerts),
MinikubeISO: viper.GetString(isoURL),
Memory: pkgutil.CalculateSizeInMB(viper.GetString(memory)),
CPUs: viper.GetInt(cpus),
DiskSize: pkgutil.CalculateSizeInMB(viper.GetString(humanReadableDiskSize)),
VMDriver: drvName,
HyperkitVpnKitSock: viper.GetString(vpnkitSock),
HyperkitVSockPorts: viper.GetStringSlice(vsockPorts),
NFSShare: viper.GetStringSlice(nfsShare),
NFSSharesRoot: viper.GetString(nfsSharesRoot),
DockerEnv: dockerEnv,
DockerOpt: dockerOpt,
InsecureRegistry: insecureRegistry,
RegistryMirror: registryMirror,
HostOnlyCIDR: viper.GetString(hostOnlyCIDR),
HypervVirtualSwitch: viper.GetString(hypervVirtualSwitch),
KVMNetwork: viper.GetString(kvmNetwork),
KVMQemuURI: viper.GetString(kvmQemuURI),
KVMGPU: viper.GetBool(kvmGPU),
KVMHidden: viper.GetBool(kvmHidden),
Downloader: pkgutil.DefaultDownloader{},
DisableDriverMounts: viper.GetBool(disableDriverMounts),
UUID: viper.GetString(uuid),
NoVTXCheck: viper.GetBool(noVTXCheck),
DNSProxy: viper.GetBool(dnsProxy),
HostDNSResolver: viper.GetBool(hostDNSResolver),
HostOnlyNicType: viper.GetString(hostOnlyNicType),
NatNicType: viper.GetString(natNicType),
Name: viper.GetString(config.MachineProfile),
KeepContext: viper.GetBool(keepContext),
EmbedCerts: viper.GetBool(embedCerts),
MinikubeISO: viper.GetString(isoURL),
Memory: pkgutil.CalculateSizeInMB(viper.GetString(memory)),
CPUs: viper.GetInt(cpus),
DiskSize: pkgutil.CalculateSizeInMB(viper.GetString(humanReadableDiskSize)),
VMDriver: drvName,
HyperkitVpnKitSock: viper.GetString(vpnkitSock),
HyperkitVSockPorts: viper.GetStringSlice(vsockPorts),
NFSShare: viper.GetStringSlice(nfsShare),
NFSSharesRoot: viper.GetString(nfsSharesRoot),
DockerEnv: dockerEnv,
DockerOpt: dockerOpt,
InsecureRegistry: insecureRegistry,
RegistryMirror: registryMirror,
HostOnlyCIDR: viper.GetString(hostOnlyCIDR),
HypervVirtualSwitch: viper.GetString(hypervVirtualSwitch),
HypervUseExternalSwitch: viper.GetBool(hypervUseExternalSwitch),
HypervExternalAdapter: viper.GetString(hypervExternalAdapter),
KVMNetwork: viper.GetString(kvmNetwork),
KVMQemuURI: viper.GetString(kvmQemuURI),
KVMGPU: viper.GetBool(kvmGPU),
KVMHidden: viper.GetBool(kvmHidden),
Downloader: pkgutil.DefaultDownloader{},
DisableDriverMounts: viper.GetBool(disableDriverMounts),
UUID: viper.GetString(uuid),
NoVTXCheck: viper.GetBool(noVTXCheck),
DNSProxy: viper.GetBool(dnsProxy),
HostDNSResolver: viper.GetBool(hostDNSResolver),
HostOnlyNicType: viper.GetString(hostOnlyNicType),
NatNicType: viper.GetString(natNicType),
KubernetesConfig: config.KubernetesConfig{
KubernetesVersion: k8sVersion,
ClusterName: viper.GetString(config.MachineProfile),
Expand Down
4 changes: 2 additions & 2 deletions pkg/minikube/cluster/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ type MockDownloader struct{}
func (d MockDownloader) GetISOFileURI(isoURL string) string { return "" }
func (d MockDownloader) CacheMinikubeISOFromURL(isoURL string) error { return nil }

func createMockDriverHost(c config.MachineConfig) interface{} {
return nil
func createMockDriverHost(c config.MachineConfig) (interface{}, error) {
return nil, nil
}

func RegisterMockDriver(t *testing.T) {
Expand Down
5 changes: 4 additions & 1 deletion pkg/minikube/cluster/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ func createHost(api libmachine.API, cfg config.MachineConfig) (*host.Host, error
if def.Empty() {
return nil, fmt.Errorf("unsupported/missing driver: %s", cfg.VMDriver)
}
dd := def.Config(cfg)
dd, err := def.Config(cfg)
if err != nil {
return nil, errors.Wrap(err, "config")
}
data, err := json.Marshal(dd)
if err != nil {
return nil, errors.Wrap(err, "marshal")
Expand Down
68 changes: 35 additions & 33 deletions pkg/minikube/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,39 +32,41 @@ type Profile struct {

// MachineConfig contains the parameters used to start a cluster.
type MachineConfig struct {
Name string
KeepContext bool // used by start and profile command to or not to switch kubectl's current context
EmbedCerts bool // used by kubeconfig.Setup
MinikubeISO string
Memory int
CPUs int
DiskSize int
VMDriver string
HyperkitVpnKitSock string // Only used by the Hyperkit driver
HyperkitVSockPorts []string // Only used by the Hyperkit driver
DockerEnv []string // Each entry is formatted as KEY=VALUE.
InsecureRegistry []string
RegistryMirror []string
HostOnlyCIDR string // Only used by the virtualbox driver
HypervVirtualSwitch string
KVMNetwork string // Only used by the KVM driver
KVMQemuURI string // Only used by kvm2
KVMGPU bool // Only used by kvm2
KVMHidden bool // Only used by kvm2
Downloader util.ISODownloader `json:"-"`
DockerOpt []string // Each entry is formatted as KEY=VALUE.
DisableDriverMounts bool // Only used by virtualbox
NFSShare []string
NFSSharesRoot string
UUID string // Only used by hyperkit to restore the mac address
NoVTXCheck bool // Only used by virtualbox
DNSProxy bool // Only used by virtualbox
HostDNSResolver bool // Only used by virtualbox
HostOnlyNicType string // Only used by virtualbox
NatNicType string // Only used by virtualbox
KubernetesConfig KubernetesConfig
Nodes []Node
Addons map[string]bool
Name string
KeepContext bool // used by start and profile command to or not to switch kubectl's current context
EmbedCerts bool // used by kubeconfig.Setup
MinikubeISO string
Memory int
CPUs int
DiskSize int
VMDriver string
HyperkitVpnKitSock string // Only used by the Hyperkit driver
HyperkitVSockPorts []string // Only used by the Hyperkit driver
DockerEnv []string // Each entry is formatted as KEY=VALUE.
InsecureRegistry []string
RegistryMirror []string
HostOnlyCIDR string // Only used by the virtualbox driver
HypervVirtualSwitch string
HypervUseExternalSwitch bool
HypervExternalAdapter string
KVMNetwork string // Only used by the KVM driver
KVMQemuURI string // Only used by kvm2
KVMGPU bool // Only used by kvm2
KVMHidden bool // Only used by kvm2
Downloader util.ISODownloader `json:"-"`
DockerOpt []string // Each entry is formatted as KEY=VALUE.
DisableDriverMounts bool // Only used by virtualbox
NFSShare []string
NFSSharesRoot string
UUID string // Only used by hyperkit to restore the mac address
NoVTXCheck bool // Only used by virtualbox
DNSProxy bool // Only used by virtualbox
HostDNSResolver bool // Only used by virtualbox
HostOnlyNicType string // Only used by virtualbox
NatNicType string // Only used by virtualbox
KubernetesConfig KubernetesConfig
Nodes []Node
Addons map[string]bool
}

// KubernetesConfig contains the parameters used to configure the VM Kubernetes.
Expand Down
5 changes: 2 additions & 3 deletions pkg/minikube/registry/drvs/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func init() {
}
}

func configure(mc config.MachineConfig) interface{} {
func configure(mc config.MachineConfig) (interface{}, error) {
return kic.NewDriver(kic.Config{
MachineName: mc.Name,
StorePath: localpath.MiniPath(),
Expand All @@ -52,8 +52,7 @@ func configure(mc config.MachineConfig) interface{} {
Memory: mc.Memory,
OCIBinary: oci.Docker,
APIServerPort: mc.Nodes[0].Port,
})

}), nil
}

func status() registry.State {
Expand Down
4 changes: 2 additions & 2 deletions pkg/minikube/registry/drvs/hyperkit/hyperkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func init() {
}
}

func configure(config cfg.MachineConfig) interface{} {
func configure(config cfg.MachineConfig) (interface{}, error) {
u := config.UUID
if u == "" {
u = uuid.NewUUID().String()
Expand All @@ -79,7 +79,7 @@ func configure(config cfg.MachineConfig) interface{} {
VpnKitSock: config.HyperkitVpnKitSock,
VSockPorts: config.HyperkitVSockPorts,
Cmdline: "loglevel=3 console=ttyS0 console=tty0 noembed nomodeset norestore waitusb=10 systemd.legacy_systemd_cgroup_controller=yes random.trust_cpu=on hw_rng_model=virtio base host=" + config.Name,
}
}, nil
}

func status() registry.State {
Expand Down
23 changes: 20 additions & 3 deletions pkg/minikube/registry/drvs/hyperv/hyperv.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/docker/machine/drivers/hyperv"
"github.com/docker/machine/libmachine/drivers"
"github.com/pkg/errors"

cfg "k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/driver"
Expand All @@ -35,7 +36,8 @@ import (
)

const (
docURL = "https://minikube.sigs.k8s.io/docs/reference/drivers/hyperv/"
docURL = "https://minikube.sigs.k8s.io/docs/reference/drivers/hyperv/"
defaultExternalSwitchName = "minikube"
)

func init() {
Expand All @@ -50,16 +52,31 @@ func init() {
}
}

func configure(config cfg.MachineConfig) interface{} {
func configure(config cfg.MachineConfig) (interface{}, error) {
d := hyperv.NewDriver(config.Name, localpath.MiniPath())
d.Boot2DockerURL = config.Downloader.GetISOFileURI(config.MinikubeISO)
d.VSwitch = config.HypervVirtualSwitch
if d.VSwitch == "" && config.HypervUseExternalSwitch {
switchName, adapter, err := chooseSwitch(config.HypervExternalAdapter)
if err != nil {
return nil, errors.Wrapf(err, "failed to choose switch for Hyper-V driver")
}
if config.HypervExternalAdapter == "" && switchName == "" {
// create a switch on the returned adapter
switchName = defaultExternalSwitchName
err := createVMSwitch(switchName, adapter)
if err != nil {
return "", err
}
}
d.VSwitch = switchName
}
d.MemSize = config.Memory
d.CPU = config.CPUs
d.DiskSize = config.DiskSize
d.SSHUser = "docker"
d.DisableDynamicMemory = true // default to disable dynamic memory as minikube is unlikely to work properly with dynamic memory
return d
return d, nil
}

func status() registry.State {
Expand Down
Loading

0 comments on commit 239be7e

Please sign in to comment.