Merge pull request #122907 from sohankunkerkar/prepare-kep-3983-for-beta
[KEP-4419]: promote KubeletConfigDropInDir feature to beta
This commit is contained in:
		| @@ -285,7 +285,7 @@ func (f *KubeletFlags) AddFlags(mainfs *pflag.FlagSet) { | |||||||
| 	f.addOSFlags(fs) | 	f.addOSFlags(fs) | ||||||
|  |  | ||||||
| 	fs.StringVar(&f.KubeletConfigFile, "config", f.KubeletConfigFile, "The Kubelet will load its initial configuration from this file. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Omit this flag to use the built-in default configuration values. Command-line flags override configuration from this file.") | 	fs.StringVar(&f.KubeletConfigFile, "config", f.KubeletConfigFile, "The Kubelet will load its initial configuration from this file. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Omit this flag to use the built-in default configuration values. Command-line flags override configuration from this file.") | ||||||
| 	fs.StringVar(&f.KubeletDropinConfigDirectory, "config-dir", "", "Path to a directory to specify drop-ins, allows the user to optionally specify additional configs to overwrite what is provided by default and in the KubeletConfigFile flag. Note: Set the 'KUBELET_CONFIG_DROPIN_DIR_ALPHA' environment variable to specify the directory. [default='']") | 	fs.StringVar(&f.KubeletDropinConfigDirectory, "config-dir", "", "Path to a directory to specify drop-ins, allows the user to optionally specify additional configs to overwrite what is provided by default and in the KubeletConfigFile flag. [default='']") | ||||||
| 	fs.StringVar(&f.KubeConfig, "kubeconfig", f.KubeConfig, "Path to a kubeconfig file, specifying how to connect to the API server. Providing --kubeconfig enables API server mode, omitting --kubeconfig enables standalone mode.") | 	fs.StringVar(&f.KubeConfig, "kubeconfig", f.KubeConfig, "Path to a kubeconfig file, specifying how to connect to the API server. Providing --kubeconfig enables API server mode, omitting --kubeconfig enables standalone mode.") | ||||||
|  |  | ||||||
| 	fs.StringVar(&f.BootstrapKubeconfig, "bootstrap-kubeconfig", f.BootstrapKubeconfig, "Path to a kubeconfig file that will be used to get client certificate for kubelet. "+ | 	fs.StringVar(&f.BootstrapKubeconfig, "bootstrap-kubeconfig", f.BootstrapKubeconfig, "Path to a kubeconfig file that will be used to get client certificate for kubelet. "+ | ||||||
|   | |||||||
| @@ -214,10 +214,6 @@ is checked every 20 seconds (also configurable with a flag).`, | |||||||
| 			} | 			} | ||||||
| 			// Merge the kubelet configurations if --config-dir is set | 			// Merge the kubelet configurations if --config-dir is set | ||||||
| 			if len(kubeletFlags.KubeletDropinConfigDirectory) > 0 { | 			if len(kubeletFlags.KubeletDropinConfigDirectory) > 0 { | ||||||
| 				_, ok := os.LookupEnv("KUBELET_CONFIG_DROPIN_DIR_ALPHA") |  | ||||||
| 				if !ok { |  | ||||||
| 					return fmt.Errorf("flag %s specified but environment variable KUBELET_CONFIG_DROPIN_DIR_ALPHA not set, cannot start kubelet", kubeletFlags.KubeletDropinConfigDirectory) |  | ||||||
| 				} |  | ||||||
| 				if err := mergeKubeletConfigurations(kubeletConfig, kubeletFlags.KubeletDropinConfigDirectory); err != nil { | 				if err := mergeKubeletConfigurations(kubeletConfig, kubeletFlags.KubeletDropinConfigDirectory); err != nil { | ||||||
| 					return fmt.Errorf("failed to merge kubelet configs: %w", err) | 					return fmt.Errorf("failed to merge kubelet configs: %w", err) | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -70,7 +70,29 @@ readOnlyPort: 10257 | |||||||
| clusterDNS: | clusterDNS: | ||||||
| - 192.168.1.10 | - 192.168.1.10 | ||||||
| systemReserved: | systemReserved: | ||||||
|   memory: 1Gi`) |   memory: 1Gi | ||||||
|  | authorization: | ||||||
|  |   mode: Webhook | ||||||
|  |   webhook: | ||||||
|  |     cacheAuthorizedTTL: "5m" | ||||||
|  |     cacheUnauthorizedTTL: "30s" | ||||||
|  | staticPodURLHeader: | ||||||
|  |   kubelet-api-support: | ||||||
|  |   - "Authorization: 234APSDFA" | ||||||
|  |   - "X-Custom-Header: 123" | ||||||
|  |   custom-static-pod: | ||||||
|  |   - "Authorization: 223EWRWER" | ||||||
|  |   - "X-Custom-Header: 456" | ||||||
|  | shutdownGracePeriodByPodPriority: | ||||||
|  |   - priority: 1 | ||||||
|  |     shutdownGracePeriodSeconds: 60 | ||||||
|  |   - priority: 2 | ||||||
|  |     shutdownGracePeriodSeconds: 45 | ||||||
|  |   - priority: 3 | ||||||
|  |     shutdownGracePeriodSeconds: 30 | ||||||
|  | featureGates: | ||||||
|  |   DisableKubeletCloudCredentialProviders: true | ||||||
|  |   PodAndContainerStatsFromCRI: true`) | ||||||
| 			framework.ExpectNoError(os.WriteFile(filepath.Join(configDir, "10-kubelet.conf"), contents, 0755)) | 			framework.ExpectNoError(os.WriteFile(filepath.Join(configDir, "10-kubelet.conf"), contents, 0755)) | ||||||
| 			contents = []byte(`apiVersion: kubelet.config.k8s.io/v1beta1 | 			contents = []byte(`apiVersion: kubelet.config.k8s.io/v1beta1 | ||||||
| kind: KubeletConfiguration | kind: KubeletConfiguration | ||||||
| @@ -81,7 +103,29 @@ clusterDNS: | |||||||
| port: 8080 | port: 8080 | ||||||
| cpuManagerReconcilePeriod: 0s | cpuManagerReconcilePeriod: 0s | ||||||
| systemReserved: | systemReserved: | ||||||
|   memory: 2Gi`) |   memory: 2Gi | ||||||
|  | authorization: | ||||||
|  |   mode: Webhook | ||||||
|  |   webhook: | ||||||
|  |     cacheAuthorizedTTL: "6m" | ||||||
|  |     cacheUnauthorizedTTL: "40s" | ||||||
|  | staticPodURLHeader: | ||||||
|  |   kubelet-api-support: | ||||||
|  |   - "Authorization: 8945AFSG1" | ||||||
|  |   - "X-Custom-Header: 987" | ||||||
|  |   custom-static-pod: | ||||||
|  |   - "Authorization: 223EWRWER" | ||||||
|  |   - "X-Custom-Header: 345" | ||||||
|  | shutdownGracePeriodByPodPriority: | ||||||
|  |   - priority: 1 | ||||||
|  |     shutdownGracePeriodSeconds: 19 | ||||||
|  |   - priority: 2 | ||||||
|  |     shutdownGracePeriodSeconds: 41 | ||||||
|  |   - priority: 6 | ||||||
|  |     shutdownGracePeriodSeconds: 30 | ||||||
|  | featureGates: | ||||||
|  |   PodAndContainerStatsFromCRI: false | ||||||
|  |   DynamicResourceAllocation: true`) | ||||||
| 			framework.ExpectNoError(os.WriteFile(filepath.Join(configDir, "20-kubelet.conf"), contents, 0755)) | 			framework.ExpectNoError(os.WriteFile(filepath.Join(configDir, "20-kubelet.conf"), contents, 0755)) | ||||||
| 			ginkgo.By("Restarting the kubelet") | 			ginkgo.By("Restarting the kubelet") | ||||||
| 			restartKubelet() | 			restartKubelet() | ||||||
| @@ -105,6 +149,27 @@ systemReserved: | |||||||
| 			// Meanwhile, this value was not explicitly set, but could have been overridden by a "default" of 0 for the type. | 			// Meanwhile, this value was not explicitly set, but could have been overridden by a "default" of 0 for the type. | ||||||
| 			// Ensure the true default persists. | 			// Ensure the true default persists. | ||||||
| 			initialConfig.CPUCFSQuotaPeriod = metav1.Duration{Duration: time.Duration(100000000)} | 			initialConfig.CPUCFSQuotaPeriod = metav1.Duration{Duration: time.Duration(100000000)} | ||||||
|  | 			// This covers the case for a map with the list of values. | ||||||
|  | 			initialConfig.StaticPodURLHeader = map[string][]string{ | ||||||
|  | 				"kubelet-api-support": {"Authorization: 8945AFSG1", "X-Custom-Header: 987"}, | ||||||
|  | 				"custom-static-pod":   {"Authorization: 223EWRWER", "X-Custom-Header: 345"}, | ||||||
|  | 			} | ||||||
|  | 			// This covers the case where the fields within the list of structs are overridden. | ||||||
|  | 			initialConfig.ShutdownGracePeriodByPodPriority = []kubeletconfig.ShutdownGracePeriodByPodPriority{ | ||||||
|  | 				{Priority: 1, ShutdownGracePeriodSeconds: 19}, | ||||||
|  | 				{Priority: 2, ShutdownGracePeriodSeconds: 41}, | ||||||
|  | 				{Priority: 6, ShutdownGracePeriodSeconds: 30}, | ||||||
|  | 			} | ||||||
|  | 			// This covers the case where the fields within the struct are overridden. | ||||||
|  | 			initialConfig.Authorization = kubeletconfig.KubeletAuthorization{ | ||||||
|  | 				Mode: "Webhook", | ||||||
|  | 				Webhook: kubeletconfig.KubeletWebhookAuthorization{ | ||||||
|  | 					CacheAuthorizedTTL:   metav1.Duration{Duration: time.Duration(6 * time.Minute)}, | ||||||
|  | 					CacheUnauthorizedTTL: metav1.Duration{Duration: time.Duration(40 * time.Second)}, | ||||||
|  | 				}, | ||||||
|  | 			} | ||||||
|  | 			// This covers the case where the fields within the map are overridden. | ||||||
|  | 			initialConfig.FeatureGates = map[string]bool{"DisableKubeletCloudCredentialProviders": true, "PodAndContainerStatsFromCRI": false, "DynamicResourceAllocation": true} | ||||||
| 			// Compare the expected config with the merged config | 			// Compare the expected config with the merged config | ||||||
| 			gomega.Expect(initialConfig).To(gomega.BeComparableTo(mergedConfig), "Merged kubelet config does not match the expected configuration.") | 			gomega.Expect(initialConfig).To(gomega.BeComparableTo(mergedConfig), "Merged kubelet config does not match the expected configuration.") | ||||||
| 		}) | 		}) | ||||||
|   | |||||||
| @@ -249,8 +249,6 @@ func (e *E2EServices) startKubelet(featureGates map[string]bool) (*server, error | |||||||
| 		unitName = fmt.Sprintf("kubelet-%s.service", unitTimestamp) | 		unitName = fmt.Sprintf("kubelet-%s.service", unitTimestamp) | ||||||
| 		cmdArgs = append(cmdArgs, | 		cmdArgs = append(cmdArgs, | ||||||
| 			systemdRun, | 			systemdRun, | ||||||
| 			// Set the environment variable to enable kubelet config drop-in directory. |  | ||||||
| 			"--setenv", "KUBELET_CONFIG_DROPIN_DIR_ALPHA=yes", |  | ||||||
| 			"-p", "Delegate=true", | 			"-p", "Delegate=true", | ||||||
| 			"-p", logLocation+framework.TestContext.ReportDir+"/kubelet.log", | 			"-p", logLocation+framework.TestContext.ReportDir+"/kubelet.log", | ||||||
| 			"--unit="+unitName, | 			"--unit="+unitName, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Prow Robot
					Kubernetes Prow Robot