diff --git a/cmd/minikube/cmd/start_flags.go b/cmd/minikube/cmd/start_flags.go index 4cea7ebf8c88..85fbd9ff889d 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 6c78922c6b0c..63822793c974 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 50b8ebcd71cd..34e277009af3 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 4a04f4567710..021f78c74c8e 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 a611767d7356..0170da251e45 100644 --- a/pkg/minikube/node/start.go +++ b/pkg/minikube/node/start.go @@ -256,9 +256,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 cc40dacd38b9..c120313287c9 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 80c408af3872..3bc3b25371a1 100644 --- a/test/integration/functional_test.go +++ b/test/integration/functional_test.go @@ -755,7 +755,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 f75f1cd6d754..49f9fdcc63ed 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 97e46e64da7a..31c9eeb96afc 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 c4913e31dc04..982d6c03843e 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 913980c07d8e..c376b6e11e2b 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 09376db0e0b2..dc380fe4cead 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 14d1c9af73c4..e49b7d557791 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 e85c0b2cbfd7..c953b643e3d2 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 261a4e8838a5..ffa3d3329f5b 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 a83f730227f9..fa0a3ba36d57 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 9e6427d23a6b..c339981ab4b6 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.": "",