Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement multi-node cluster capabilities #6787

Merged
merged 50 commits into from
Mar 21, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
8536fb7
changes and things
sharifelgamal Feb 19, 2020
ec19111
let's move some start code around
sharifelgamal Feb 21, 2020
7853387
add new setup cluster file
sharifelgamal Feb 22, 2020
4af8291
Merge branch 'master' of github.com:kubernetes/minikube into m2
sharifelgamal Feb 23, 2020
f22efd8
mostly moving code around and adding UpdateNode
sharifelgamal Feb 24, 2020
9a3ecab
fixed more stuff
sharifelgamal Feb 24, 2020
be9c5f4
pass in the node object into add
sharifelgamal Feb 24, 2020
f0ca34b
fix unit tests
sharifelgamal Feb 25, 2020
b2ba874
SaveNode is simpler yeah
sharifelgamal Feb 25, 2020
f5bdba6
fix kvm2 configurator
sharifelgamal Feb 25, 2020
feaa9fc
hyperv and none drivers needed fixing too
sharifelgamal Feb 25, 2020
3d72152
fixing lint and other random incorrect stuff
sharifelgamal Feb 25, 2020
39f03bc
prepareNone was in the wrong spot
sharifelgamal Feb 25, 2020
0fadf91
i think it works?
sharifelgamal Feb 26, 2020
e3826a5
fix ip command
sharifelgamal Feb 26, 2020
676588f
refactor machine name creation into a function
sharifelgamal Feb 26, 2020
d7df027
fix delete and stop
sharifelgamal Feb 26, 2020
e7f8abc
fix waitfornode
sharifelgamal Feb 26, 2020
9f82d68
actually cache images on cluster startup
sharifelgamal Feb 26, 2020
2bf3b9a
move caching code to cluster
sharifelgamal Feb 27, 2020
0cc0a25
passing correct machine name around
sharifelgamal Feb 27, 2020
a349b86
correct machine name for selectDriver
sharifelgamal Feb 27, 2020
64ca925
Merge branch 'master' of github.com:kubernetes/minikube into m2
sharifelgamal Mar 9, 2020
05116ab
more fallout for the merge-pocalypse
sharifelgamal Mar 10, 2020
ef93b29
fix build failures
sharifelgamal Mar 10, 2020
e3227a2
Merge branch 'master' of github.com:kubernetes/minikube into m2
sharifelgamal Mar 10, 2020
3ed818c
cosmetic fixes
sharifelgamal Mar 12, 2020
b6ab293
run all necessary steps on all nodes
sharifelgamal Mar 13, 2020
a9b73b8
fixing up minikube start path
sharifelgamal Mar 13, 2020
3608903
Merge branch 'master' of github.com:kubernetes/minikube into m2
sharifelgamal Mar 13, 2020
d98ebcf
lint
sharifelgamal Mar 13, 2020
c3b56b6
let's rearrange a bunch of code
sharifelgamal Mar 14, 2020
74b1f34
Merge branch 'master' of github.com:kubernetes/minikube into m2
sharifelgamal Mar 16, 2020
577dfa3
it works again
sharifelgamal Mar 16, 2020
c1c2653
fix unit tests
sharifelgamal Mar 16, 2020
376111b
fix unit tests pt 2
sharifelgamal Mar 16, 2020
f387032
Merge branch 'master' of github.com:kubernetes/minikube into m2
sharifelgamal Mar 16, 2020
f99d335
fix docker driver
sharifelgamal Mar 16, 2020
84939da
fix docker driver again
sharifelgamal Mar 17, 2020
66a6f4e
fix docker status
sharifelgamal Mar 17, 2020
a24aa5d
dramatically simplify start code path
sharifelgamal Mar 18, 2020
add1c8f
missing file
sharifelgamal Mar 18, 2020
efac79e
account for hyphens in profile name
sharifelgamal Mar 19, 2020
fa97a5b
fix machine name creation
sharifelgamal Mar 19, 2020
f9b38dc
clean up status output and have multinode survive cluster restarts
sharifelgamal Mar 19, 2020
6a6b77a
Merge branch 'master' of github.com:kubernetes/minikube into m2
sharifelgamal Mar 20, 2020
4c00ae0
Merge branch 'master' of github.com:kubernetes/minikube into m2
sharifelgamal Mar 20, 2020
35aec77
code comments
sharifelgamal Mar 20, 2020
a09aa62
delete admin.conf before running kubedm init
sharifelgamal Mar 20, 2020
05814cc
only apply kic networking overlay to control plane
sharifelgamal Mar 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions cmd/minikube/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,20 @@ func deleteProfile(profile *pkg_config.Profile) error {
}

if err == nil && driver.BareMetal(cc.Driver) {
if err := uninstallKubernetes(api, profile.Name, cc.KubernetesConfig, viper.GetString(cmdcfg.Bootstrapper)); err != nil {
deletionError, ok := err.(DeletionError)
if ok {
delErr := profileDeletionErr(profile.Name, fmt.Sprintf("%v", err))
deletionError.Err = delErr
return deletionError
var e error
for _, n := range cc.Nodes {
if err := uninstallKubernetes(api, profile.Name, cc.KubernetesConfig, viper.GetString(cmdcfg.Bootstrapper), n.Name); err != nil {
deletionError, ok := err.(DeletionError)
if ok {
delErr := profileDeletionErr(profile.Name, fmt.Sprintf("%v", err))
deletionError.Err = delErr
e = deletionError
}
e = err
}
return err
}
if e != nil {
return e
}
}

Expand Down Expand Up @@ -302,9 +308,9 @@ func profileDeletionErr(profileName string, additionalInfo string) error {
return fmt.Errorf("error deleting profile \"%s\": %s", profileName, additionalInfo)
}

func uninstallKubernetes(api libmachine.API, profile string, kc pkg_config.KubernetesConfig, bsName string) error {
func uninstallKubernetes(api libmachine.API, profile string, kc pkg_config.KubernetesConfig, bsName string, nodeName string) error {
out.T(out.Resetting, "Uninstalling Kubernetes {{.kubernetes_version}} using {{.bootstrapper_name}} ...", out.V{"kubernetes_version": kc.KubernetesVersion, "bootstrapper_name": bsName})
clusterBootstrapper, err := cluster.Bootstrapper(api, bsName)
clusterBootstrapper, err := cluster.Bootstrapper(api, bsName, nodeName)
if err != nil {
return DeletionError{Err: fmt.Errorf("unable to get bootstrapper: %v", err), Errtype: Fatal}
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/minikube/cmd/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ var logsCmd = &cobra.Command{
if err != nil {
exit.WithError("command runner", err)
}
bs, err := cluster.Bootstrapper(api, viper.GetString(cmdcfg.Bootstrapper))
bs, err := cluster.Bootstrapper(api, viper.GetString(cmdcfg.Bootstrapper), viper.GetString(config.MachineProfile))
if err != nil {
exit.WithError("Error getting cluster bootstrapper", err)
}
Expand Down
7 changes: 3 additions & 4 deletions cmd/minikube/cmd/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ import (

// nodeCmd represents the set of node subcommands
var nodeCmd = &cobra.Command{
Use: "node",
Short: "Node operations",
Long: "Operations on nodes",
Hidden: true, // This won't be fully functional and thus should not be documented yet
Use: "node",
Short: "Node operations",
Long: "Operations on nodes",
Run: func(cmd *cobra.Command, args []string) {
exit.UsageT("Usage: minikube node [add|start|stop|delete]")
},
Expand Down
17 changes: 12 additions & 5 deletions cmd/minikube/cmd/node_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,23 @@ var nodeAddCmd = &cobra.Command{
if nodeName == "" {
name = profile + strconv.Itoa(len(mc.Nodes)+1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while we are at it, why not rename all mc to cc and make sure we call it cc everywhere in the code

}
_, _, err = node.Retrieve(mc, name)
if err == nil {
exit.WithCodeT(100, "{{.nodeName}} already exists in cluster {{.cluster}}. Choose a different name.", out.V{"nodeName": name, "cluster": mc.Name})
}
out.T(out.Happy, "Adding node {{.name}} to cluster {{.cluster}}", out.V{"name": name, "cluster": profile})

n, err := node.Add(mc, name, cp, worker, "", profile)
if err != nil {
exit.WithError("Error adding node to cluster", err)
// TODO: Deal with parameters better. Ideally we should be able to acceot any node-specific minikube start params here.
n := config.Node{
Name: name,
Worker: worker,
ControlPlane: cp,
KubernetesVersion: mc.KubernetesConfig.KubernetesVersion,
}

_, err = node.Start(*mc, *n, false, nil)
err = node.Add(mc, n)
if err != nil {
exit.WithError("Error starting node", err)
exit.WithError("Error adding node to cluster", err)
}

out.T(out.Ready, "Successfully added {{.name}} to {{.cluster}}!", out.V{"name": name, "cluster": profile})
Expand Down
2 changes: 1 addition & 1 deletion cmd/minikube/cmd/node_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var nodeDeleteCmd = &cobra.Command{

err = node.Delete(*cc, name)
if err != nil {
out.FatalT("Failed to delete node {{.name}}", out.V{"name": name})
exit.WithError("deleting node", err)
tstromberg marked this conversation as resolved.
Show resolved Hide resolved
}

out.T(out.Deleted, "Node {{.name}} was successfully deleted.", out.V{"name": name})
Expand Down
2 changes: 1 addition & 1 deletion cmd/minikube/cmd/node_start.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ var nodeStartCmd = &cobra.Command{
}

// Start it up baby
_, err = node.Start(*cc, *n, false, nil)
err = node.Start(*cc, *n, nil)
if err != nil {
out.FatalT("Failed to start node {{.name}}", out.V{"name": name})
}
Expand Down
45 changes: 34 additions & 11 deletions cmd/minikube/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ const (
autoUpdate = "auto-update-drivers"
hostOnlyNicType = "host-only-nic-type"
natNicType = "nat-nic-type"
nodes = "nodes"
)

var (
Expand Down Expand Up @@ -160,7 +161,7 @@ func initMinikubeFlags() {
startCmd.Flags().String(containerRuntime, "docker", "The container runtime to be used (docker, crio, containerd).")
startCmd.Flags().Bool(createMount, false, "This will start the mount daemon and automatically mount files into minikube.")
startCmd.Flags().String(mountString, constants.DefaultMountDir+":/minikube-host", "The argument to pass the minikube mount command on start.")
startCmd.Flags().StringArrayVar(&node.AddonList, "addons", nil, "Enable addons. see `minikube addons list` for a list of valid addon names.")
startCmd.Flags().StringArrayVar(&config.AddonList, "addons", nil, "Enable addons. see `minikube addons list` for a list of valid addon names.")
startCmd.Flags().String(criSocket, "", "The cri socket path to be used.")
startCmd.Flags().String(networkPlugin, "", "The name of the network plugin.")
startCmd.Flags().Bool(enableDefaultCNI, false, "Enable the default CNI plugin (/etc/cni/net.d/k8s.conf). Used in conjunction with \"--network-plugin=cni\".")
Expand All @@ -169,12 +170,13 @@ func initMinikubeFlags() {
startCmd.Flags().Bool(nativeSSH, true, "Use native Golang SSH client (default true). Set to 'false' to use the command line 'ssh' command when accessing the docker machine. Useful for the machine drivers when they will not start with 'Waiting for SSH'.")
startCmd.Flags().Bool(autoUpdate, true, "If set, automatically updates drivers to the latest version. Defaults to true.")
startCmd.Flags().Bool(installAddons, true, "If set, install addons. Defaults to true.")
startCmd.Flags().IntP(nodes, "n", 1, "The number of nodes to spin up. Defaults to 1.")
}

// initKubernetesFlags inits the commandline flags for kubernetes related options
func initKubernetesFlags() {
startCmd.Flags().String(kubernetesVersion, "", "The kubernetes version that the minikube VM will use (ex: v1.2.3)")
startCmd.Flags().Var(&node.ExtraOptions, "extra-config",
startCmd.Flags().Var(&config.ExtraOptions, "extra-config",
`A set of key=value pairs that describe configuration that may be passed to different components.
The key should be '.' separated, and the first part before the dot is the component to apply the configuration to.
Valid components are: kubelet, kubeadm, apiserver, controller-manager, etcd, proxy, scheduler
Expand Down Expand Up @@ -226,8 +228,8 @@ func initNetworkingFlags() {
startCmd.Flags().String(imageRepository, "", "Alternative image repository to pull docker images from. This can be used when you have limited access to gcr.io. Set it to \"auto\" to let minikube decide one for you. For Chinese mainland users, you may use local gcr.io mirrors such as registry.cn-hangzhou.aliyuncs.com/google_containers")
startCmd.Flags().String(imageMirrorCountry, "", "Country code of the image mirror to be used. Leave empty to use the global one. For Chinese mainland users, set it to cn.")
startCmd.Flags().String(serviceCIDR, constants.DefaultServiceCIDR, "The CIDR to be used for service cluster IPs.")
startCmd.Flags().StringArrayVar(&node.DockerEnv, "docker-env", nil, "Environment variables to pass to the Docker daemon. (format: key=value)")
startCmd.Flags().StringArrayVar(&node.DockerOpt, "docker-opt", nil, "Specify arbitrary flags to pass to the Docker daemon. (format: key=value)")
startCmd.Flags().StringArrayVar(&config.DockerEnv, "docker-env", nil, "Environment variables to pass to the Docker daemon. (format: key=value)")
startCmd.Flags().StringArrayVar(&config.DockerOpt, "docker-opt", nil, "Specify arbitrary flags to pass to the Docker daemon. (format: key=value)")
}

// startCmd represents the start command
Expand Down Expand Up @@ -335,14 +337,35 @@ func runStart(cmd *cobra.Command, args []string) {
existingAddons = existing.Addons
}
}
kubeconfig, err := node.Start(mc, n, true, existingAddons)

// Abstraction leakage alert: startHost requires the config to be saved, to satistfy pkg/provision/buildroot.
// Hence, saveConfig must be called before startHost, and again afterwards when we know the IP.
if err := config.SaveProfile(viper.GetString(config.MachineProfile), &mc); err != nil {
exit.WithError("Failed to save config", err)
}

kubeconfig, err := cluster.InitialSetup(mc, n, existingAddons)
if err != nil {
exit.WithError("Starting node", err)
}

if err := showKubectlInfo(kubeconfig, k8sVersion, mc.Name); err != nil {
glog.Errorf("kubectl info: %v", err)
}

numNodes := viper.GetInt(nodes)
if numNodes > 1 {
for i := 0; i < numNodes-1; i++ {
nodeName := fmt.Sprintf("%s%d", n.Name, i+1)
n := config.Node{
Name: nodeName,
Worker: true,
ControlPlane: false,
KubernetesVersion: mc.KubernetesConfig.KubernetesVersion,
}
node.Add(&mc, n)
}
}
}

func updateDriver(driverName string) {
Expand Down Expand Up @@ -691,7 +714,7 @@ func validateFlags(cmd *cobra.Command, drvName string) {
validateCPUCount(driver.BareMetal(drvName))

// check that kubeadm extra args contain only whitelisted parameters
for param := range node.ExtraOptions.AsMap().Get(bsutil.Kubeadm) {
for param := range config.ExtraOptions.AsMap().Get(bsutil.Kubeadm) {
if !config.ContainsParam(bsutil.KubeadmExtraArgsWhitelist[bsutil.KubeadmCmdParam], param) &&
!config.ContainsParam(bsutil.KubeadmExtraArgsWhitelist[bsutil.KubeadmConfigParam], param) {
exit.UsageT("Sorry, the kubeadm.{{.parameter_name}} parameter is currently not supported by --extra-config", out.V{"parameter_name": param})
Expand Down Expand Up @@ -791,8 +814,8 @@ func generateCfgFromFlags(cmd *cobra.Command, k8sVersion string, drvName string)
HyperkitVSockPorts: viper.GetStringSlice(vsockPorts),
NFSShare: viper.GetStringSlice(nfsShare),
NFSSharesRoot: viper.GetString(nfsSharesRoot),
DockerEnv: node.DockerEnv,
DockerOpt: node.DockerOpt,
DockerEnv: config.DockerEnv,
DockerOpt: config.DockerOpt,
InsecureRegistry: insecureRegistry,
RegistryMirror: registryMirror,
HostOnlyCIDR: viper.GetString(hostOnlyCIDR),
Expand Down Expand Up @@ -824,7 +847,7 @@ func generateCfgFromFlags(cmd *cobra.Command, k8sVersion string, drvName string)
NetworkPlugin: selectedNetworkPlugin,
ServiceCIDR: viper.GetString(serviceCIDR),
ImageRepository: repository,
ExtraOptions: node.ExtraOptions,
ExtraOptions: config.ExtraOptions,
ShouldLoadCachedImages: viper.GetBool(cacheImages),
EnableDefaultCNI: selectedEnableDefaultCNI,
},
Expand All @@ -846,7 +869,7 @@ func setDockerProxy() {
continue
}
}
node.DockerEnv = append(node.DockerEnv, fmt.Sprintf("%s=%s", k, v))
config.DockerEnv = append(config.DockerEnv, fmt.Sprintf("%s=%s", k, v))
}
}
}
Expand All @@ -858,7 +881,7 @@ func autoSetDriverOptions(cmd *cobra.Command, drvName string) (err error) {
if !cmd.Flags().Changed("extra-config") && len(hints.ExtraOptions) > 0 {
for _, eo := range hints.ExtraOptions {
glog.Infof("auto setting extra-config to %q.", eo)
err = node.ExtraOptions.Set(eo)
err = config.ExtraOptions.Set(eo)
if err != nil {
err = errors.Wrapf(err, "setting extra option %s", eo)
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/drivers/hyperkit/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ type Driver struct {
UUID string
VpnKitSock string
VSockPorts []string
ClusterName string
}

// NewDriver creates a new driver for a host
Expand Down Expand Up @@ -199,7 +200,7 @@ func (d *Driver) Restart() error {
}

func (d *Driver) createHost() (*hyperkit.HyperKit, error) {
stateDir := filepath.Join(d.StorePath, "machines", d.MachineName)
stateDir := filepath.Join(d.StorePath, "machines", d.ClusterName, d.MachineName)
h, err := hyperkit.New("", d.VpnKitSock, stateDir)
if err != nil {
return nil, errors.Wrap(err, "new-ing Hyperkit")
Expand Down Expand Up @@ -519,6 +520,7 @@ func (d *Driver) sendSignal(s os.Signal) error {
func (d *Driver) getPid() int {
pidPath := d.ResolveStorePath(machineFileName)

log.Debugf("PIDPATH=%s", pidPath)
f, err := os.Open(pidPath)
if err != nil {
log.Warnf("Error reading pid file: %v", err)
Expand Down
4 changes: 4 additions & 0 deletions pkg/minikube/bootstrapper/bootstrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"k8s.io/minikube/pkg/minikube/bootstrapper/images"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/cruntime"
)

// LogOptions are options to be passed to LogCommands
Expand All @@ -39,6 +40,9 @@ type Bootstrapper interface {
UpdateCluster(config.ClusterConfig) error
DeleteCluster(config.KubernetesConfig) error
WaitForCluster(config.ClusterConfig, time.Duration) error
JoinCluster(config.ClusterConfig, config.Node, string) error
UpdateNode(config.ClusterConfig, config.Node, cruntime.Manager) error
GenerateToken(config.KubernetesConfig) (string, error)
// LogCommands returns a map of log type to a command which will display that log.
LogCommands(LogOptions) map[string]string
SetupCerts(config.KubernetesConfig, config.Node) error
Expand Down
2 changes: 1 addition & 1 deletion pkg/minikube/bootstrapper/bsutil/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func AdjustResourceLimits(c command.Runner) error {
return nil
}

// ExistingConfig checks if there are config files from possible previous kubernets cluster
// ExistingConfig checks if there are config files from possible previous kubernetes cluster
func ExistingConfig(c command.Runner) error {
args := append([]string{"ls"}, expectedRemoteArtifacts...)
_, err := c.RunCmd(exec.Command("sudo", args...))
Expand Down
6 changes: 4 additions & 2 deletions pkg/minikube/bootstrapper/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,10 @@ func SetupCerts(cmd command.Runner, k8s config.KubernetesConfig, n config.Node)
return errors.Wrap(err, "encoding kubeconfig")
}

kubeCfgFile := assets.NewMemoryAsset(data, vmpath.GuestPersistentDir, "kubeconfig", "0644")
copyableFiles = append(copyableFiles, kubeCfgFile)
if n.ControlPlane {
kubeCfgFile := assets.NewMemoryAsset(data, vmpath.GuestPersistentDir, "kubeconfig", "0644")
copyableFiles = append(copyableFiles, kubeCfgFile)
}

for _, f := range copyableFiles {
if err := cmd.Copy(f); err != nil {
Expand Down
Loading