diff --git a/cmd/minikube/cmd/start_flags.go b/cmd/minikube/cmd/start_flags.go index 4cea7ebf8c..85fbd9ff88 100644 --- a/cmd/minikube/cmd/start_flags.go +++ b/cmd/minikube/cmd/start_flags.go @@ -133,6 +133,7 @@ const ( extraDisks = "extra-disks" certExpiration = "cert-expiration" binaryMirror = "binary-mirror" + disableOptimizations = "disable-optimizations" ) var ( @@ -191,6 +192,7 @@ func initMinikubeFlags() { startCmd.Flags().Int(extraDisks, 0, "Number of extra disks created and attached to the minikube VM (currently only implemented for hyperkit and kvm2 drivers)") startCmd.Flags().Duration(certExpiration, constants.DefaultCertExpiration, "Duration until minikube certificate expiration, defaults to three years (26280h).") startCmd.Flags().String(binaryMirror, "", "Location to fetch kubectl, kubelet, & kubeadm binaries from.") + startCmd.Flags().Bool(disableOptimizations, false, "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.") } // initKubernetesFlags inits the commandline flags for Kubernetes related options @@ -379,6 +381,27 @@ func getDiskSize() int { return diskSize } +func getExtraOptions() config.ExtraOptionSlice { + options := []string{} + if detect.IsCloudShell() { + options = append(options, "kubelet.cgroups-per-qos=false", "kubelet.enforce-node-allocatable=\"\"") + } + if !viper.GetBool(disableOptimizations) { + options = append(options, "kubelet.housekeeping-interval=5m") + } + for _, eo := range options { + if config.ExtraOptions.Exists(eo) { + klog.Infof("skipping extra-config %q.", eo) + continue + } + klog.Infof("setting extra-config: %s", eo) + if err := config.ExtraOptions.Set(eo); err != nil { + exit.Error(reason.InternalConfigSet, "failed to set extra option", err) + } + } + return config.ExtraOptions +} + func getRepository(cmd *cobra.Command, k8sVersion string) string { repository := viper.GetString(imageRepository) mirrorCountry := strings.ToLower(viper.GetString(imageMirrorCountry)) @@ -493,6 +516,7 @@ func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, drvName s MountType: viper.GetString(mountTypeFlag), MountUID: viper.GetString(mountUID), BinaryMirror: viper.GetString(binaryMirror), + DisableOptimizations: viper.GetBool(disableOptimizations), KubernetesConfig: config.KubernetesConfig{ KubernetesVersion: k8sVersion, ClusterName: ClusterFlagValue(), @@ -507,7 +531,7 @@ func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, drvName s NetworkPlugin: chosenNetworkPlugin, ServiceCIDR: viper.GetString(serviceCIDR), ImageRepository: getRepository(cmd, k8sVersion), - ExtraOptions: config.ExtraOptions, + ExtraOptions: getExtraOptions(), ShouldLoadCachedImages: viper.GetBool(cacheImages), CNI: getCNIConfig(cmd), NodePort: viper.GetInt(apiServerPort), @@ -519,17 +543,6 @@ func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, drvName s cc.ContainerVolumeMounts = []string{viper.GetString(mountString)} } - if detect.IsCloudShell() { - err := cc.KubernetesConfig.ExtraOptions.Set("kubelet.cgroups-per-qos=false") - if err != nil { - exit.Error(reason.InternalConfigSet, "failed to set cloud shell kubelet config options", err) - } - err = cc.KubernetesConfig.ExtraOptions.Set("kubelet.enforce-node-allocatable=\"\"") - if err != nil { - exit.Error(reason.InternalConfigSet, "failed to set cloud shell kubelet config options", err) - } - } - if driver.IsKIC(drvName) { si, err := oci.CachedDaemonInfo(drvName) if err != nil { @@ -711,13 +724,14 @@ func updateExistingConfigFromFlags(cmd *cobra.Command, existing *config.ClusterC updateStringFromFlag(cmd, &cc.MountType, mountTypeFlag) updateStringFromFlag(cmd, &cc.MountUID, mountUID) updateStringFromFlag(cmd, &cc.BinaryMirror, binaryMirror) + updateBoolFromFlag(cmd, &cc.DisableOptimizations, disableOptimizations) if cmd.Flags().Changed(kubernetesVersion) { cc.KubernetesConfig.KubernetesVersion = getKubernetesVersion(existing) } if cmd.Flags().Changed("extra-config") { - cc.KubernetesConfig.ExtraOptions = config.ExtraOptions + cc.KubernetesConfig.ExtraOptions = getExtraOptions() } if cmd.Flags().Changed(cniFlag) || cmd.Flags().Changed(enableDefaultCNI) { diff --git a/pkg/minikube/config/types.go b/pkg/minikube/config/types.go index 6c78922c6b..63822793c9 100644 --- a/pkg/minikube/config/types.go +++ b/pkg/minikube/config/types.go @@ -96,6 +96,7 @@ type ClusterConfig struct { MountType string MountUID string BinaryMirror string // Mirror location for kube binaries (kubectl, kubelet, & kubeadm) + DisableOptimizations bool } // KubernetesConfig contains the parameters used to configure the VM Kubernetes. diff --git a/pkg/minikube/driver/driver.go b/pkg/minikube/driver/driver.go index 50b8ebcd71..34e277009a 100644 --- a/pkg/minikube/driver/driver.go +++ b/pkg/minikube/driver/driver.go @@ -235,7 +235,7 @@ type FlagHints struct { // FlagDefaults returns suggested defaults based on a driver func FlagDefaults(name string) FlagHints { - fh := FlagHints{ExtraOptions: []string{"kubelet.housekeeping-interval=5m"}} + fh := FlagHints{} if name != None { fh.CacheImages = true return fh diff --git a/pkg/minikube/driver/driver_test.go b/pkg/minikube/driver/driver_test.go index 4a04f45677..021f78c74c 100644 --- a/pkg/minikube/driver/driver_test.go +++ b/pkg/minikube/driver/driver_test.go @@ -85,7 +85,7 @@ func TestMachineType(t *testing.T) { } func TestFlagDefaults(t *testing.T) { - expected := FlagHints{CacheImages: true, ExtraOptions: []string{"kubelet.housekeeping-interval=5m"}} + expected := FlagHints{CacheImages: true} if diff := cmp.Diff(FlagDefaults(VirtualBox), expected); diff != "" { t.Errorf("defaults mismatch (-want +got):\n%s", diff) } @@ -98,7 +98,7 @@ func TestFlagDefaults(t *testing.T) { expected = FlagHints{ CacheImages: false, - ExtraOptions: []string{"kubelet.housekeeping-interval=5m", fmt.Sprintf("kubelet.resolv-conf=%s", tf.Name())}, + ExtraOptions: []string{fmt.Sprintf("kubelet.resolv-conf=%s", tf.Name())}, } systemdResolvConf = tf.Name() if diff := cmp.Diff(FlagDefaults(None), expected); diff != "" { diff --git a/pkg/minikube/node/start.go b/pkg/minikube/node/start.go index 82cbc454f3..278253aa4c 100644 --- a/pkg/minikube/node/start.go +++ b/pkg/minikube/node/start.go @@ -258,9 +258,11 @@ func handleAPIServer(starter Starter, cr cruntime.Manager, hostIP net.IP) (*kube return nil, bs, errors.Wrap(err, "Failed kubeconfig update") } - // Scale down CoreDNS from default 2 to 1 replica. - if err := kapi.ScaleDeployment(starter.Cfg.Name, meta.NamespaceSystem, kconst.CoreDNSDeploymentName, 1); err != nil { - klog.Errorf("Unable to scale down deployment %q in namespace %q to 1 replica: %v", kconst.CoreDNSDeploymentName, meta.NamespaceSystem, err) + if !starter.Cfg.DisableOptimizations { + // Scale down CoreDNS from default 2 to 1 replica. + if err := kapi.ScaleDeployment(starter.Cfg.Name, meta.NamespaceSystem, kconst.CoreDNSDeploymentName, 1); err != nil { + klog.Errorf("Unable to scale down deployment %q in namespace %q to 1 replica: %v", kconst.CoreDNSDeploymentName, meta.NamespaceSystem, err) + } } // Not running this in a Go func can result in DNS answering taking up to 38 seconds, with the Go func it takes 6-10 seconds. diff --git a/site/content/en/docs/commands/start.md b/site/content/en/docs/commands/start.md index a7f6d87ea3..75476d07e0 100644 --- a/site/content/en/docs/commands/start.md +++ b/site/content/en/docs/commands/start.md @@ -36,6 +36,7 @@ minikube start [flags] --cri-socket string The cri socket path to be used. --delete-on-failure If set, delete the current cluster if start fails and try again. Defaults to false. --disable-driver-mounts Disables the filesystem mounts provided by the hypervisors + --disable-optimizations If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false. --disk-size string Disk size allocated to the minikube VM (format: [], where unit = b, k, m or g). (default "20000mb") --dns-domain string The cluster dns domain name used in the Kubernetes cluster (default "cluster.local") --dns-proxy Enable proxy for NAT DNS requests (virtualbox driver only) diff --git a/test/integration/functional_test.go b/test/integration/functional_test.go index 0bdc02f3e5..5072972f57 100644 --- a/test/integration/functional_test.go +++ b/test/integration/functional_test.go @@ -764,7 +764,11 @@ func validateExtraConfig(ctx context.Context, t *testing.T, profile string) { // docs: Make sure the specified `--extra-config` is correctly returned expectedExtraOptions := "apiserver.enable-admission-plugins=NamespaceAutoProvision" + if !strings.Contains(afterCfg.Config.KubernetesConfig.ExtraOptions.String(), expectedExtraOptions) { + t.Errorf("expected ExtraOptions to contain %s but got %s", expectedExtraOptions, afterCfg.Config.KubernetesConfig.ExtraOptions.String()) + } + expectedExtraOptions = "kubelet.housekeeping-interval=5m" if !strings.Contains(afterCfg.Config.KubernetesConfig.ExtraOptions.String(), expectedExtraOptions) { t.Errorf("expected ExtraOptions to contain %s but got %s", expectedExtraOptions, afterCfg.Config.KubernetesConfig.ExtraOptions.String()) } diff --git a/test/integration/guest_env_test.go b/test/integration/guest_env_test.go index f75f1cd6d7..49f9fdcc63 100644 --- a/test/integration/guest_env_test.go +++ b/test/integration/guest_env_test.go @@ -37,11 +37,15 @@ func TestGuestEnvironment(t *testing.T) { defer CleanupWithLogs(t, profile, cancel) t.Run("Setup", func(t *testing.T) { - args := append([]string{"start", "-p", profile, "--install-addons=false", "--memory=2048", "--wait=false"}, StartArgs()...) + args := append([]string{"start", "-p", profile, "--install-addons=false", "--memory=2048", "--wait=false", "--disable-optimizations=true"}, StartArgs()...) rr, err := Run(t, exec.CommandContext(ctx, Target(), args...)) if err != nil { t.Errorf("failed to start minikube: args %q: %v", rr.Command(), err) } + + if strings.Contains(rr.Stderr.String(), "kubelet.housekeeping-interval=5m") { + t.Error("--disable-optimizations=true is not working, optimizations found") + } }) // Run as a group so that our defer doesn't happen as tests are runnings diff --git a/translations/de.json b/translations/de.json index 97e46e64da..31c9eeb96a 100644 --- a/translations/de.json +++ b/translations/de.json @@ -327,6 +327,7 @@ "If present, writes to the provided file instead of stdout.": "Falls gesetzt, wird in die angegebene Datei geschrieben anstatt auf stdout.", "If set, automatically updates drivers to the latest version. Defaults to true.": "Falls gesetzt, werden alle Treiber automatisch auf die aktuellste Version geupdated. Default: true", "If set, delete the current cluster if start fails and try again. Defaults to false.": "Falls gesetzt, lösche den Cluster wenn der Start fehlschlägt und versuche erneut zu starten. Default: false", + "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.": "", "If set, download tarball of preloaded images if available to improve start time. Defaults to true.": "Falls gesetzt, lade einen tarball von vorbereiteten Images herunter, falls vorhanden, um die Startzeit zu verbessern. Default: true", "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.": "Fall gesetzt, zwinge die Container Runtime systemd als cgroup Manager zu verwenden. Default: false", "If set, install addons. Defaults to true.": "Falls gesetzt, werden Addons installiert. Default: true", @@ -894,6 +895,7 @@ "failed to open browser: {{.error}}": "Öffnen des Browsers fehlgeschlagen: {{.error}}", "failed to save config": "Speichern der Konfiguration fehlgeschlagen", "failed to set cloud shell kubelet config options": "Setzen der Cloud Shell Kublet Konfigurations Opetionen fehlgeschlagen", + "failed to set extra option": "", "failed to start node": "Start des Nodes fehlgeschlagen", "fish completion failed": "fish completion fehlgeschlagen", "fish completion.": "fish fehlgeschlagen", diff --git a/translations/es.json b/translations/es.json index c4913e31dc..982d6c0384 100644 --- a/translations/es.json +++ b/translations/es.json @@ -336,6 +336,7 @@ "If present, writes to the provided file instead of stdout.": "", "If set, automatically updates drivers to the latest version. Defaults to true.": "", "If set, delete the current cluster if start fails and try again. Defaults to false.": "", + "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.": "", "If set, download tarball of preloaded images if available to improve start time. Defaults to true.": "", "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.": "", "If set, install addons. Defaults to true.": "", @@ -900,7 +901,7 @@ "failed to add node": "", "failed to open browser: {{.error}}": "", "failed to save config": "", - "failed to set cloud shell kubelet config options": "", + "failed to set extra option": "", "failed to start node": "", "fish completion failed": "", "fish completion.": "", diff --git a/translations/fr.json b/translations/fr.json index a96d6135d1..70fc5e8239 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -317,6 +317,7 @@ "If present, writes to the provided file instead of stdout.": "S'il est présent, écrit dans le fichier fourni au lieu de la sortie standard.", "If set, automatically updates drivers to the latest version. Defaults to true.": "Si défini, met automatiquement à jour les pilotes vers la dernière version. La valeur par défaut est true.", "If set, delete the current cluster if start fails and try again. Defaults to false.": "Si défini, supprime le cluster actuel si le démarrage échoue et réessaye. La valeur par défaut est false.", + "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.": "", "If set, download tarball of preloaded images if available to improve start time. Defaults to true.": "Si défini, télécharge l'archive tar des images préchargées si disponibles pour améliorer le temps de démarrage. La valeur par défaut est true.", "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.": "S'il est défini, force l'environnement d'exécution du conteneur à utiliser systemd comme gestionnaire de groupe de contrôle. La valeur par défaut est false.", "If set, install addons. Defaults to true.": "Si défini, installe les modules. La valeur par défaut est true.", @@ -857,6 +858,7 @@ "failed to open browser: {{.error}}": "échec de l'ouverture du navigateur : {{.error}}", "failed to save config": "échec de l'enregistrement de la configuration", "failed to set cloud shell kubelet config options": "échec de la définition des options de configuration cloud shell kubelet", + "failed to set extra option": "", "failed to start node": "échec du démarrage du nœud", "fish completion failed": "la complétion fish a échoué", "fish completion.": "complétion fish.", diff --git a/translations/ja.json b/translations/ja.json index 09376db0e0..dc380fe4ce 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -324,6 +324,7 @@ "If present, writes to the provided file instead of stdout.": "", "If set, automatically updates drivers to the latest version. Defaults to true.": "", "If set, delete the current cluster if start fails and try again. Defaults to false.": "", + "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.": "", "If set, download tarball of preloaded images if available to improve start time. Defaults to true.": "", "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.": "", "If set, install addons. Defaults to true.": "", @@ -909,6 +910,7 @@ "failed to open browser: {{.error}}": "ブラウザー起動に失敗しました: {{.error}}", "failed to save config": "設定保存に失敗しました", "failed to set cloud shell kubelet config options": "クラウドシェル kubelet 設定オプションの設定に失敗しました", + "failed to set extra option": "", "failed to start node": "ノード開始に失敗しました", "fish completion failed": "fish のコマンド補完に失敗しました", "fish completion.": "fish のコマンド補完です。", diff --git a/translations/ko.json b/translations/ko.json index 14d1c9af73..e49b7d5577 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -354,6 +354,7 @@ "If present, writes to the provided file instead of stdout.": "", "If set, automatically updates drivers to the latest version. Defaults to true.": "", "If set, delete the current cluster if start fails and try again. Defaults to false.": "", + "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.": "", "If set, download tarball of preloaded images if available to improve start time. Defaults to true.": "", "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.": "", "If set, install addons. Defaults to true.": "", @@ -904,7 +905,7 @@ "failed to add node": "", "failed to open browser: {{.error}}": "", "failed to save config": "", - "failed to set cloud shell kubelet config options": "", + "failed to set extra option": "", "failed to start node": "", "fish completion failed": "", "fish completion.": "", diff --git a/translations/pl.json b/translations/pl.json index e85c0b2cbf..c953b643e3 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -340,6 +340,7 @@ "If present, writes to the provided file instead of stdout.": "", "If set, automatically updates drivers to the latest version. Defaults to true.": "", "If set, delete the current cluster if start fails and try again. Defaults to false.": "", + "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.": "", "If set, download tarball of preloaded images if available to improve start time. Defaults to true.": "", "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.": "", "If set, install addons. Defaults to true.": "", @@ -910,7 +911,7 @@ "failed to add node": "", "failed to open browser: {{.error}}": "Nie udało się otworzyć przeglądarki: {{.error}}", "failed to save config": "", - "failed to set cloud shell kubelet config options": "", + "failed to set extra option": "", "failed to start node": "", "fish completion failed": "", "fish completion.": "", diff --git a/translations/ru.json b/translations/ru.json index 261a4e8838..ffa3d3329f 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -308,6 +308,7 @@ "If present, writes to the provided file instead of stdout.": "", "If set, automatically updates drivers to the latest version. Defaults to true.": "", "If set, delete the current cluster if start fails and try again. Defaults to false.": "", + "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.": "", "If set, download tarball of preloaded images if available to improve start time. Defaults to true.": "", "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.": "", "If set, install addons. Defaults to true.": "", @@ -835,7 +836,7 @@ "failed to add node": "", "failed to open browser: {{.error}}": "", "failed to save config": "", - "failed to set cloud shell kubelet config options": "", + "failed to set extra option": "", "failed to start node": "", "fish completion failed": "", "fish completion.": "", diff --git a/translations/strings.txt b/translations/strings.txt index a83f730227..fa0a3ba36d 100644 --- a/translations/strings.txt +++ b/translations/strings.txt @@ -308,6 +308,7 @@ "If present, writes to the provided file instead of stdout.": "", "If set, automatically updates drivers to the latest version. Defaults to true.": "", "If set, delete the current cluster if start fails and try again. Defaults to false.": "", + "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.": "", "If set, download tarball of preloaded images if available to improve start time. Defaults to true.": "", "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.": "", "If set, install addons. Defaults to true.": "", @@ -835,7 +836,7 @@ "failed to add node": "", "failed to open browser: {{.error}}": "", "failed to save config": "", - "failed to set cloud shell kubelet config options": "", + "failed to set extra option": "", "failed to start node": "", "fish completion failed": "", "fish completion.": "", diff --git a/translations/zh-CN.json b/translations/zh-CN.json index 9e6427d23a..c339981ab4 100644 --- a/translations/zh-CN.json +++ b/translations/zh-CN.json @@ -412,6 +412,7 @@ "If present, writes to the provided file instead of stdout.": "", "If set, automatically updates drivers to the latest version. Defaults to true.": "如果设置了,将自动更新驱动到最新版本。默认为 true。", "If set, delete the current cluster if start fails and try again. Defaults to false.": "", + "If set, disables optimizations that are set for local Kubernetes. Including decreasing CoreDNS replicas from 2 to 1 and increasing kubeadm housekeeping-interval from 10s to 5m. Defaults to false.": "", "If set, download tarball of preloaded images if available to improve start time. Defaults to true.": "", "If set, force the container runtime to use systemd as cgroup manager. Defaults to false.": "", "If set, install addons. Defaults to true.": "", @@ -1020,7 +1021,7 @@ "failed to add node": "", "failed to open browser: {{.error}}": "", "failed to save config": "", - "failed to set cloud shell kubelet config options": "", + "failed to set extra option": "", "failed to start node": "", "fish completion failed": "", "fish completion.": "",