minikube start device check(启动时驱动检测)
🎲

minikube start device check(启动时驱动检测)

源码

https://github.com/uos-ljtian/minikube/blob/7a79f70916d69792a4565dc14434ef400cb69b20/cmd/minikube/cmd/start.go

// runStart handles the executes the flow of "minikube start" func runStart(cmd *cobra.Command, _ []string) { // 设置环境变量 register.SetEventLogPath(localpath.EventLog(ClusterFlagValue())) // 设置上下文 ctx := context.Background() // 设置为 json 格式 out.SetJSON(outputFormat == "json") // 设置追踪 if err := pkgtrace.Initialize(viper.GetString(trace)); err != nil { exit.Message(reason.Usage, "error initializing tracing: {{.Error}}", out.V{"Error": err.Error()}) } defer pkgtrace.Cleanup() // 打印版本信息 displayVersion(version.GetVersion()) // 开启线程,清理旧版本的预加载文件 go download.CleanUpOlderPreloads() // Avoid blocking execution on optional HTTP fetches go notify.MaybePrintUpdateTextFromGithub() // 打印环境变量 displayEnviron(os.Environ()) if viper.GetBool(force) { out.WarningT("minikube skips various validations when --force is supplied; this may lead to unexpected behavior") } // if --registry-mirror specified when run minikube start, // take arg precedence over MINIKUBE_REGISTRY_MIRROR // actually this is a hack, because viper 1.0.0 can assign env to variable if StringSliceVar // and i can't update it to 1.4.0, it affects too much code // other types (like String, Bool) of flag works, so imageRepository, imageMirrorCountry // can be configured as MINIKUBE_IMAGE_REPOSITORY and IMAGE_MIRROR_COUNTRY // this should be updated to documentation if len(registryMirror) == 0 { registryMirror = viper.GetStringSlice("registry-mirror") } // 配置文件名称校验 if !config.ProfileNameValid(ClusterFlagValue()) { out.WarningT("Profile name '{{.name}}' is not valid", out.V{"name": ClusterFlagValue()}) exit.Message(reason.Usage, "Only alphanumeric and dashes '-' are permitted. Minimum 2 characters, starting with alphanumeric.") } // 加载配置文件(第一次加载时,路径不存在会返回 nil ) existing, err := config.Load(ClusterFlagValue()) if err != nil && !config.IsNotExist(err) { kind := reason.HostConfigLoad if config.IsPermissionDenied(err) { kind = reason.HostHomePermission } exit.Message(kind, "Unable to load config: {{.error}}", out.V{"error": err}) } // 更新配置文件内容 if existing != nil { upgradeExistingConfig(cmd, existing) } else { validateProfileName() } // 检验出入的驱动 validateSpecifiedDriver(existing) // 版本校验 validateKubernetesVersion(existing) // 检验运行时是否为{“docker”,"crio","cri-o","containerd"}的其中一种, 如果没有设置,直接跳过 validateContainerRuntime(existing) ds, alts, specified := selectDriver(existing) if cmd.Flag(kicBaseImage).Changed { if !isBaseImageApplicable(ds.Name) { exit.Message(reason.Usage, "flag --{{.imgFlag}} is not available for driver '{{.driver}}'. Did you mean to use '{{.docker}}' or '{{.podman}}' driver instead?\n"+ "Please use --{{.isoFlag}} flag to configure VM based drivers", out.V{ "imgFlag": kicBaseImage, "driver": ds.Name, "docker": registry.Docker, "podman": registry.Podman, "isoFlag": isoURL, }, ) } } useForce := viper.GetBool(force) starter, err := provisionWithDriver(cmd, ds, existing) if err != nil { node.ExitIfFatal(err, useForce) machine.MaybeDisplayAdvice(err, ds.Name) if specified { // If the user specified a driver, don't fallback to anything else exitGuestProvision(err) } else { success := false // Walk down the rest of the options for _, alt := range alts { // Skip non-default drivers if !alt.Default { continue } out.WarningT("Startup with {{.old_driver}} driver failed, trying with alternate driver {{.new_driver}}: {{.error}}", out.V{"old_driver": ds.Name, "new_driver": alt.Name, "error": err}) ds = alt // Delete the existing cluster and try again with the next driver on the list profile, err := config.LoadProfile(ClusterFlagValue()) if err != nil { klog.Warningf("%s profile does not exist, trying anyways.", ClusterFlagValue()) } err = deleteProfile(ctx, profile) if err != nil { out.WarningT("Failed to delete cluster {{.name}}, proceeding with retry anyway.", out.V{"name": ClusterFlagValue()}) } starter, err = provisionWithDriver(cmd, ds, existing) if err != nil { continue } // Success! success = true break } if !success { exitGuestProvision(err) } } } validateBuiltImageVersion(starter.Runner, ds.Name) if existing != nil && driver.IsKIC(existing.Driver) { if viper.GetBool(createMount) { old := "" if len(existing.ContainerVolumeMounts) > 0 { old = existing.ContainerVolumeMounts[0] } if mount := viper.GetString(mountString); old != mount { exit.Message(reason.GuestMountConflict, "Sorry, {{.driver}} does not allow mounts to be changed after container creation (previous mount: '{{.old}}', new mount: '{{.new}})'", out.V{ "driver": existing.Driver, "new": mount, "old": old, }) } } } kubeconfig, err := startWithDriver(cmd, starter, existing) if err != nil { node.ExitIfFatal(err, useForce) exit.Error(reason.GuestStart, "failed to start node", err) } if err := showKubectlInfo(kubeconfig, starter.Node.KubernetesVersion, starter.Node.ContainerRuntime, starter.Cfg.Name); err != nil { klog.Errorf("kubectl info: %v", err) } }

https://github.com/uos-ljtian/minikube/blob/7a79f70916d69792a4565dc14434ef400cb69b20/cmd/minikube/cmd/start.go

// returns (current_driver, suggested_drivers, "true, if the driver is set by command line arg or in the config file") // 选择驱动 func selectDriver(existing *config.ClusterConfig) (registry.DriverState, []registry.DriverState, bool) { // Technically unrelated, but important to perform before detection driver.SetLibvirtURI(viper.GetString(kvmQemuURI)) register.Reg.SetStep(register.SelectingDriver) // By default, the driver is whatever we used last time if existing != nil { old := hostDriver(existing) ds := driver.Status(old) out.Step(style.Sparkle, `Using the {{.driver}} driver based on existing profile`, out.V{"driver": ds.String()}) return ds, nil, true } // Default to looking at the new driver parameter if d := viper.GetString("driver"); d != "" { if vmd := viper.GetString("vm-driver"); vmd != "" { // Output a warning warning := `Both driver={{.driver}} and vm-driver={{.vmd}} have been set. Since vm-driver is deprecated, minikube will default to driver={{.driver}}. If vm-driver is set in the global config, please run "minikube config unset vm-driver" to resolve this warning. ` out.WarningT(warning, out.V{"driver": d, "vmd": vmd}) } ds := driver.Status(d) if ds.Name == "" { exit.Message(reason.DrvUnsupportedOS, "The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}", out.V{"driver": d, "os": runtime.GOOS, "arch": runtime.GOARCH}) } out.Step(style.Sparkle, `Using the {{.driver}} driver based on user configuration`, out.V{"driver": ds.String()}) return ds, nil, true } // Fallback to old driver parameter if d := viper.GetString("vm-driver"); d != "" { ds := driver.Status(viper.GetString("vm-driver")) if ds.Name == "" { exit.Message(reason.DrvUnsupportedOS, "The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}", out.V{"driver": d, "os": runtime.GOOS, "arch": runtime.GOARCH}) } out.Step(style.Sparkle, `Using the {{.driver}} driver based on user configuration`, out.V{"driver": ds.String()}) return ds, nil, true } // 返回本机所有的驱动 choices := driver.Choices(viper.GetBool("vm")) // 推荐出,可使用的驱动(根据是否安装、是否健康、是否是默认、优先级是否大于4 进行推荐),分别返回: 首选、可用列表、不可用列表 pick, alts, rejects := driver.Suggest(choices) if pick.Name == "" { out.Step(style.ThumbsDown, "Unable to pick a default driver. Here is what was considered, in preference order:") sort.Slice(rejects, func(i, j int) bool { if rejects[i].Priority == rejects[j].Priority { return rejects[i].Preference > rejects[j].Preference } return rejects[i].Priority > rejects[j].Priority }) // Display the issue for installed drivers for _, r := range rejects { if r.Default && r.State.Installed { out.Infof("{{ .name }}: {{ .rejection }}", out.V{"name": r.Name, "rejection": r.Rejection}) if r.Suggestion != "" { out.Infof("{{ .name }}: Suggestion: {{ .suggestion}}", out.V{"name": r.Name, "suggestion": r.Suggestion}) } } } // Display the other drivers users can install out.Step(style.Tip, "Alternatively you could install one of these drivers:") for _, r := range rejects { if !r.Default || r.State.Installed { continue } out.Infof("{{ .name }}: {{ .rejection }}", out.V{"name": r.Name, "rejection": r.Rejection}) if r.Suggestion != "" { out.Infof("{{ .name }}: Suggestion: {{ .suggestion}}", out.V{"name": r.Name, "suggestion": r.Suggestion}) } } foundStoppedDocker := false foundUnhealthy := false for _, reject := range rejects { if reject.Name == driver.Docker && reject.State.Installed && !reject.State.Running { foundStoppedDocker = true break } else if reject.State.Installed && !reject.State.Healthy { foundUnhealthy = true break } } if foundStoppedDocker { exit.Message(reason.DrvDockerNotRunning, "Found docker, but the docker service isn't running. Try restarting the docker service.") } else if foundUnhealthy { exit.Message(reason.DrvNotHealthy, "Found driver(s) but none were healthy. See above for suggestions how to fix installed drivers.") } else { exit.Message(reason.DrvNotDetected, "No possible driver was detected. Try specifying --driver, or see https://minikube.sigs.k8s.io/docs/start/") } } if len(alts) > 1 { altNames := []string{} for _, a := range alts { altNames = append(altNames, a.String()) } out.Step(style.Sparkle, `Automatically selected the {{.driver}} driver. Other choices: {{.alternates}}`, out.V{"driver": pick.Name, "alternates": strings.Join(altNames, ", ")}) } else { out.Step(style.Sparkle, `Automatically selected the {{.driver}} driver`, out.V{"driver": pick.String()}) } return pick, alts, false }