Removal of KubeletConfigFile feature gate: Step 1

This feature gate was redundant with the `--config` flag, which already
enables/disables loading Kubelet config from a file.

Since the gate guarded an alpha feature, removing it is not a violation
of our API guidelines.

Some stuff in `kubernetes/test-infra` currently sets the gate,
so removing will be a 3 step process:
1. This PR, which makes the gate a no-op.
2. Stop setting the gate in `kubernetes/test-infra`.
3. Completely remove the gate.
This commit is contained in:
Michael Taufen 2018-01-24 09:28:40 -08:00
parent 47d61ef472
commit 6443b6f543
11 changed files with 14 additions and 21 deletions

View File

@ -105,8 +105,7 @@ type KubeletFlags struct {
// The Kubelet will load its initial configuration from this file. // The Kubelet will load its initial configuration from this file.
// The path may be absolute or relative; relative paths are under the Kubelet's current working directory. // The path may be absolute or relative; relative paths are under the Kubelet's current working directory.
// Omit this flag to use the combination of built-in default configuration values and flags. // Omit this flag to use the combination of built-in default configuration values and flags.
// To use this flag, the KubeletConfigFile feature gate must be enabled. KubeletConfigFile string
KubeletConfigFile flag.StringFlag
// registerNode enables automatic registration with the apiserver. // registerNode enables automatic registration with the apiserver.
RegisterNode bool RegisterNode bool
@ -246,10 +245,6 @@ func ValidateKubeletFlags(f *KubeletFlags) error {
if f.DynamicConfigDir.Provided() && !utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) { if f.DynamicConfigDir.Provided() && !utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) {
return fmt.Errorf("the DynamicKubeletConfig feature gate must be enabled in order to use the --dynamic-config-dir flag") return fmt.Errorf("the DynamicKubeletConfig feature gate must be enabled in order to use the --dynamic-config-dir flag")
} }
// ensure that nobody sets KubeletConfigFile if the KubeletConfigFile feature gate is turned off
if f.KubeletConfigFile.Provided() && !utilfeature.DefaultFeatureGate.Enabled(features.KubeletConfigFile) {
return fmt.Errorf("the KubeletConfigFile feature gate must be enabled in order to use the --config flag")
}
return nil return nil
} }
@ -342,13 +337,13 @@ func (f *KubeletFlags) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&f.RootDirectory, "root-dir", f.RootDirectory, "Directory path for managing kubelet files (volume mounts,etc).") fs.StringVar(&f.RootDirectory, "root-dir", f.RootDirectory, "Directory path for managing kubelet files (volume mounts,etc).")
fs.Var(&f.DynamicConfigDir, "dynamic-config-dir", "The Kubelet will use this directory for checkpointing downloaded configurations and tracking configuration health. The Kubelet will create this directory if it does not already exist. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Providing this flag enables dynamic Kubelet configuration. Presently, you must also enable the DynamicKubeletConfig feature gate to pass this flag.") fs.Var(&f.DynamicConfigDir, "dynamic-config-dir", "The Kubelet will use this directory for checkpointing downloaded configurations and tracking configuration health. The Kubelet will create this directory if it does not already exist. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Providing this flag enables dynamic Kubelet configuration. Presently, you must also enable the DynamicKubeletConfig feature gate to pass this flag.")
fs.Var(&f.KubeletConfigFile, "config", "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. You must also enable the KubeletConfigFile feature gate to pass this flag.")
fs.BoolVar(&f.RegisterNode, "register-node", f.RegisterNode, "Register the node with the apiserver. If --kubeconfig is not provided, this flag is irrelevant, as the Kubelet won't have an apiserver to register with. Default=true.") fs.BoolVar(&f.RegisterNode, "register-node", f.RegisterNode, "Register the node with the apiserver. If --kubeconfig is not provided, this flag is irrelevant, as the Kubelet won't have an apiserver to register with. Default=true.")
fs.Var(utiltaints.NewTaintsVar(&f.RegisterWithTaints), "register-with-taints", "Register the node with the given list of taints (comma separated \"<key>=<value>:<effect>\"). No-op if register-node is false.") fs.Var(utiltaints.NewTaintsVar(&f.RegisterWithTaints), "register-with-taints", "Register the node with the given list of taints (comma separated \"<key>=<value>:<effect>\"). No-op if register-node is false.")
fs.BoolVar(&f.Containerized, "containerized", f.Containerized, "Running kubelet in a container.") fs.BoolVar(&f.Containerized, "containerized", f.Containerized, "Running kubelet in a container.")
// EXPERIMENTAL FLAGS // EXPERIMENTAL FLAGS
fs.StringVar(&f.KubeletConfigFile, "config", f.KubeletConfigFile, "<Warning: Alpha feature> 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. Note that the format of the config file is still Alpha.")
fs.StringVar(&f.ExperimentalMounterPath, "experimental-mounter-path", f.ExperimentalMounterPath, "[Experimental] Path of mounter binary. Leave empty to use the default mount.") fs.StringVar(&f.ExperimentalMounterPath, "experimental-mounter-path", f.ExperimentalMounterPath, "[Experimental] Path of mounter binary. Leave empty to use the default mount.")
fs.StringSliceVar(&f.AllowedUnsafeSysctls, "experimental-allowed-unsafe-sysctls", f.AllowedUnsafeSysctls, "Comma-separated whitelist of unsafe sysctls or unsafe sysctl patterns (ending in *). Use these at your own risk.") fs.StringSliceVar(&f.AllowedUnsafeSysctls, "experimental-allowed-unsafe-sysctls", f.AllowedUnsafeSysctls, "Comma-separated whitelist of unsafe sysctls or unsafe sysctl patterns (ending in *). Use these at your own risk.")
fs.BoolVar(&f.ExperimentalKernelMemcgNotification, "experimental-kernel-memcg-notification", f.ExperimentalKernelMemcgNotification, "If enabled, the kubelet will integrate with the kernel memcg notification to determine if memory eviction thresholds are crossed rather than polling.") fs.BoolVar(&f.ExperimentalKernelMemcgNotification, "experimental-kernel-memcg-notification", f.ExperimentalKernelMemcgNotification, "If enabled, the kubelet will integrate with the kernel memcg notification to determine if memory eviction thresholds are crossed rather than polling.")

View File

@ -38,7 +38,6 @@ func newKubeletServerOrDie() *KubeletServer {
func cleanFlags(s *KubeletServer) { func cleanFlags(s *KubeletServer) {
s.KubeConfig = utilflag.NewStringFlag(s.KubeConfig.Value()) s.KubeConfig = utilflag.NewStringFlag(s.KubeConfig.Value())
s.DynamicConfigDir = utilflag.NewStringFlag(s.DynamicConfigDir.Value()) s.DynamicConfigDir = utilflag.NewStringFlag(s.DynamicConfigDir.Value())
s.KubeletConfigFile = utilflag.NewStringFlag(s.KubeletConfigFile.Value())
} }
// TestRoundTrip ensures that flag values from the Kubelet can be serialized // TestRoundTrip ensures that flag values from the Kubelet can be serialized

View File

@ -929,14 +929,13 @@ func parseResourceList(m map[string]string) (v1.ResourceList, error) {
// BootstrapKubeletConfigController constructs and bootstrap a configuration controller // BootstrapKubeletConfigController constructs and bootstrap a configuration controller
func BootstrapKubeletConfigController(defaultConfig *kubeletconfiginternal.KubeletConfiguration, func BootstrapKubeletConfigController(defaultConfig *kubeletconfiginternal.KubeletConfiguration,
kubeletConfigFileFlag flag.StringFlag, kubeletConfigFile string,
dynamicConfigDirFlag flag.StringFlag) (*kubeletconfiginternal.KubeletConfiguration, *kubeletconfig.Controller, error) { dynamicConfigDirFlag flag.StringFlag) (*kubeletconfiginternal.KubeletConfiguration, *kubeletconfig.Controller, error) {
var err error var err error
// Alpha Dynamic Configuration Implementation; this section only loads config from disk, it does not contact the API server // Alpha Dynamic Configuration Implementation; this section only loads config from disk, it does not contact the API server
// compute absolute paths based on current working dir // compute absolute paths based on current working dir
kubeletConfigFile := "" if len(kubeletConfigFile) > 0 {
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletConfigFile) && kubeletConfigFileFlag.Provided() { kubeletConfigFile, err = filepath.Abs(kubeletConfigFile)
kubeletConfigFile, err = filepath.Abs(kubeletConfigFileFlag.Value())
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("failed to get absolute path for --config") return nil, nil, fmt.Errorf("failed to get absolute path for --config")
} }

View File

@ -39,6 +39,7 @@ const (
// owner: @mtaufen // owner: @mtaufen
// alpha: v1.8 // alpha: v1.8
// This gate is now a no-op. It will be removed shortly.
KubeletConfigFile utilfeature.Feature = "KubeletConfigFile" KubeletConfigFile utilfeature.Feature = "KubeletConfigFile"
// owner: @pweil- // owner: @pweil-
@ -228,7 +229,7 @@ func init() {
var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureSpec{ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureSpec{
AppArmor: {Default: true, PreRelease: utilfeature.Beta}, AppArmor: {Default: true, PreRelease: utilfeature.Beta},
DynamicKubeletConfig: {Default: false, PreRelease: utilfeature.Alpha}, DynamicKubeletConfig: {Default: false, PreRelease: utilfeature.Alpha},
KubeletConfigFile: {Default: false, PreRelease: utilfeature.Alpha}, KubeletConfigFile: {Default: false, PreRelease: utilfeature.Alpha}, // KubeletConfigFile is now a no-op gate on the path to removal.
ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: utilfeature.Beta}, ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: utilfeature.Beta},
ExperimentalCriticalPodAnnotation: {Default: false, PreRelease: utilfeature.Alpha}, ExperimentalCriticalPodAnnotation: {Default: false, PreRelease: utilfeature.Alpha},
Accelerators: {Default: false, PreRelease: utilfeature.Alpha}, Accelerators: {Default: false, PreRelease: utilfeature.Alpha},

View File

@ -6,7 +6,7 @@ GCE_ZONE=us-central1-f
GCE_PROJECT=k8s-jkns-ubuntu-node GCE_PROJECT=k8s-jkns-ubuntu-node
CLEANUP=true CLEANUP=true
GINKGO_FLAGS='--skip="\[Flaky\]|\[Serial\]"' GINKGO_FLAGS='--skip="\[Flaky\]|\[Serial\]"'
TEST_ARGS='--feature-gates=KubeletConfigFile=true --generate-kubelet-config-file=true' TEST_ARGS='--generate-kubelet-config-file=true'
KUBELET_ARGS='' KUBELET_ARGS=''
TIMEOUT=1h TIMEOUT=1h
# Use the system spec defined in test/e2e_node/system/specs/gke.yaml. # Use the system spec defined in test/e2e_node/system/specs/gke.yaml.

View File

@ -4,6 +4,6 @@ GCE_ZONE=us-central1-f
GCE_PROJECT=k8s-jkns-ci-node-e2e GCE_PROJECT=k8s-jkns-ci-node-e2e
CLEANUP=true CLEANUP=true
GINKGO_FLAGS='--skip="\[Flaky\]|\[Serial\]"' GINKGO_FLAGS='--skip="\[Flaky\]|\[Serial\]"'
TEST_ARGS='--feature-gates=KubeletConfigFile=true --generate-kubelet-config-file=true' TEST_ARGS='--generate-kubelet-config-file=true'
KUBELET_ARGS='' KUBELET_ARGS=''
TIMEOUT=1h TIMEOUT=1h

View File

@ -4,7 +4,7 @@ GCE_ZONE=us-central1-f
GCE_PROJECT=k8s-jkns-ci-node-e2e GCE_PROJECT=k8s-jkns-ci-node-e2e
CLEANUP=true CLEANUP=true
GINKGO_FLAGS='--focus="\[Flaky\]"' GINKGO_FLAGS='--focus="\[Flaky\]"'
TEST_ARGS='--feature-gates=DynamicKubeletConfig=true,LocalStorageCapacityIsolation=true,PodPriority=true,KubeletConfigFile=true --generate-kubelet-config-file=true' TEST_ARGS='--feature-gates=DynamicKubeletConfig=true,LocalStorageCapacityIsolation=true,PodPriority=true --generate-kubelet-config-file=true'
KUBELET_ARGS='' KUBELET_ARGS=''
PARALLELISM=1 PARALLELISM=1
TIMEOUT=3h TIMEOUT=3h

View File

@ -4,6 +4,6 @@ GCE_ZONE=us-central1-f
GCE_PROJECT=k8s-jkns-pr-node-e2e GCE_PROJECT=k8s-jkns-pr-node-e2e
CLEANUP=true CLEANUP=true
GINKGO_FLAGS='--skip="\[Flaky\]|\[Slow\]|\[Serial\]" --flakeAttempts=2' GINKGO_FLAGS='--skip="\[Flaky\]|\[Slow\]|\[Serial\]" --flakeAttempts=2'
TEST_ARGS='--feature-gates=KubeletConfigFile=true --generate-kubelet-config-file=true' TEST_ARGS='--generate-kubelet-config-file=true'
KUBELET_ARGS='' KUBELET_ARGS=''

View File

@ -6,7 +6,7 @@ GCE_ZONE=us-central1-f
GCE_PROJECT=k8s-jkns-ubuntu-node-serial GCE_PROJECT=k8s-jkns-ubuntu-node-serial
CLEANUP=true CLEANUP=true
GINKGO_FLAGS='--focus="\[Serial\]" --skip="\[Flaky\]|\[Benchmark\]"' GINKGO_FLAGS='--focus="\[Serial\]" --skip="\[Flaky\]|\[Benchmark\]"'
TEST_ARGS='--feature-gates=DynamicKubeletConfig=true,KubeletConfigFile=true --generate-kubelet-config-file=true' TEST_ARGS='--feature-gates=DynamicKubeletConfig=true --generate-kubelet-config-file=true'
KUBELET_ARGS='' KUBELET_ARGS=''
PARALLELISM=1 PARALLELISM=1
TIMEOUT=3h TIMEOUT=3h

View File

@ -4,7 +4,7 @@ GCE_ZONE=us-west1-b
GCE_PROJECT=k8s-jkns-ci-node-e2e GCE_PROJECT=k8s-jkns-ci-node-e2e
CLEANUP=true CLEANUP=true
GINKGO_FLAGS='--focus="\[Serial\]" --skip="\[Flaky\]|\[Benchmark\]"' GINKGO_FLAGS='--focus="\[Serial\]" --skip="\[Flaky\]|\[Benchmark\]"'
TEST_ARGS='--feature-gates=DynamicKubeletConfig=true,KubeletConfigFile=true --generate-kubelet-config-file=true' TEST_ARGS='--feature-gates=DynamicKubeletConfig=true --generate-kubelet-config-file=true'
KUBELET_ARGS='' KUBELET_ARGS=''
PARALLELISM=1 PARALLELISM=1
TIMEOUT=3h TIMEOUT=3h

View File

@ -77,8 +77,7 @@ func init() {
flag.Var(&kubeletArgs, "kubelet-flags", "Kubelet flags passed to kubelet, this will override default kubelet flags in the test. Flags specified in multiple kubelet-flags will be concatenate.") flag.Var(&kubeletArgs, "kubelet-flags", "Kubelet flags passed to kubelet, this will override default kubelet flags in the test. Flags specified in multiple kubelet-flags will be concatenate.")
flag.BoolVar(&kubeletContainerized, "kubelet-containerized", false, "Run kubelet in a docker container") flag.BoolVar(&kubeletContainerized, "kubelet-containerized", false, "Run kubelet in a docker container")
flag.StringVar(&hyperkubeImage, "hyperkube-image", "", "Docker image with containerized kubelet") flag.StringVar(&hyperkubeImage, "hyperkube-image", "", "Docker image with containerized kubelet")
flag.BoolVar(&genKubeletConfigFile, "generate-kubelet-config-file", false, "The test runner will generate a Kubelet config file containing test defaults instead of passing default flags to the Kubelet. "+ flag.BoolVar(&genKubeletConfigFile, "generate-kubelet-config-file", false, "The test runner will generate a Kubelet config file containing test defaults instead of passing default flags to the Kubelet.")
"If you use this test framework feature, ensure that the KubeletConfigFile feature gate is enabled.")
} }
// RunKubelet starts kubelet and waits for termination signal. Once receives the // RunKubelet starts kubelet and waits for termination signal. Once receives the