mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
Separate feature gates for dynamic kubelet config vs loading from a file
This commit is contained in:
parent
6f4a15f922
commit
0e25cbd6a0
@ -20,9 +20,6 @@ go_library(
|
|||||||
"//cmd/kubelet/app:go_default_library",
|
"//cmd/kubelet/app:go_default_library",
|
||||||
"//cmd/kubelet/app/options:go_default_library",
|
"//cmd/kubelet/app/options:go_default_library",
|
||||||
"//pkg/client/metrics/prometheus:go_default_library",
|
"//pkg/client/metrics/prometheus:go_default_library",
|
||||||
"//pkg/features:go_default_library",
|
|
||||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
|
||||||
"//pkg/kubelet/kubeletconfig:go_default_library",
|
|
||||||
"//pkg/version/prometheus:go_default_library",
|
"//pkg/version/prometheus:go_default_library",
|
||||||
"//pkg/version/verflag:go_default_library",
|
"//pkg/version/verflag:go_default_library",
|
||||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||||
|
@ -112,6 +112,7 @@ go_library(
|
|||||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1:go_default_library",
|
||||||
|
@ -138,8 +138,8 @@ func ValidateKubeletFlags(f *KubeletFlags) error {
|
|||||||
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 InitConfigDir if the dynamic config feature gate is turned off
|
// ensure that nobody sets InitConfigDir if the dynamic config feature gate is turned off
|
||||||
if f.InitConfigDir.Provided() && !utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) {
|
if f.InitConfigDir.Provided() && !utilfeature.DefaultFeatureGate.Enabled(features.KubeletConfigFile) {
|
||||||
return fmt.Errorf("the DynamicKubeletConfig feature gate must be enabled in order to use the --init-config-dir flag")
|
return fmt.Errorf("the KubeletConfigFile feature gate must be enabled in order to use the --init-config-dir flag")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
"k8s.io/apiserver/pkg/util/flag"
|
||||||
clientgoclientset "k8s.io/client-go/kubernetes"
|
clientgoclientset "k8s.io/client-go/kubernetes"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
@ -766,29 +767,29 @@ func parseResourceList(m kubeletconfiginternal.ConfigurationMap) (v1.ResourceLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BootstrapKubeletConfigController constructs and bootstrap a configuration controller
|
// BootstrapKubeletConfigController constructs and bootstrap a configuration controller
|
||||||
func BootstrapKubeletConfigController(
|
func BootstrapKubeletConfigController(defaultConfig *kubeletconfiginternal.KubeletConfiguration,
|
||||||
flags *options.KubeletFlags,
|
initConfigDirFlag flag.StringFlag,
|
||||||
defaultConfig *kubeletconfiginternal.KubeletConfiguration) (*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
|
||||||
initConfigDir := ""
|
initConfigDir := ""
|
||||||
if flags.InitConfigDir.Provided() {
|
if utilfeature.DefaultFeatureGate.Enabled(features.KubeletConfigFile) && initConfigDirFlag.Provided() {
|
||||||
initConfigDir, err = filepath.Abs(flags.InitConfigDir.Value())
|
initConfigDir, err = filepath.Abs(initConfigDirFlag.Value())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to get absolute path for --init-config-dir")
|
return nil, nil, fmt.Errorf("failed to get absolute path for --init-config-dir")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dynamicConfigDir := ""
|
dynamicConfigDir := ""
|
||||||
if flags.DynamicConfigDir.Provided() {
|
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) && dynamicConfigDirFlag.Provided() {
|
||||||
dynamicConfigDir, err = filepath.Abs(flags.DynamicConfigDir.Value())
|
dynamicConfigDir, err = filepath.Abs(dynamicConfigDirFlag.Value())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to get absolute path for --dynamic-config-dir")
|
return nil, nil, fmt.Errorf("failed to get absolute path for --dynamic-config-dir")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the latest KubeletConfiguration checkpoint from disk, or load the init or default config if no valid checkpoints exist
|
// get the latest KubeletConfiguration checkpoint from disk, or load the init or default config if no valid checkpoints exist
|
||||||
kubeletConfigController, err := kubeletconfig.NewController(initConfigDir, dynamicConfigDir, defaultConfig)
|
kubeletConfigController, err := kubeletconfig.NewController(defaultConfig, initConfigDir, dynamicConfigDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to construct controller, error: %v", err)
|
return nil, nil, fmt.Errorf("failed to construct controller, error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,7 @@ import (
|
|||||||
"k8s.io/kubernetes/cmd/kubelet/app"
|
"k8s.io/kubernetes/cmd/kubelet/app"
|
||||||
"k8s.io/kubernetes/cmd/kubelet/app/options"
|
"k8s.io/kubernetes/cmd/kubelet/app/options"
|
||||||
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
|
||||||
"k8s.io/kubernetes/pkg/features"
|
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
|
||||||
kubeletconfiginternal "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
|
||||||
"k8s.io/kubernetes/pkg/kubelet/kubeletconfig"
|
|
||||||
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
|
|
||||||
"k8s.io/kubernetes/pkg/version/verflag"
|
"k8s.io/kubernetes/pkg/version/verflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -75,17 +72,12 @@ func main() {
|
|||||||
if err := options.ValidateKubeletFlags(kubeletFlags); err != nil {
|
if err := options.ValidateKubeletFlags(kubeletFlags); err != nil {
|
||||||
die(err)
|
die(err)
|
||||||
}
|
}
|
||||||
// if dynamic kubelet config is enabled, bootstrap the kubelet config controller
|
// bootstrap the kubelet config controller, app.BootstrapKubeletConfigController will check
|
||||||
var kubeletConfig *kubeletconfiginternal.KubeletConfiguration
|
// feature gates and only turn on relevant parts of the controller
|
||||||
var kubeletConfigController *kubeletconfig.Controller
|
kubeletConfig, kubeletConfigController, err := app.BootstrapKubeletConfigController(
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) {
|
defaultConfig, kubeletFlags.InitConfigDir, kubeletFlags.DynamicConfigDir)
|
||||||
var err error
|
if err != nil {
|
||||||
kubeletConfig, kubeletConfigController, err = app.BootstrapKubeletConfigController(kubeletFlags, defaultConfig)
|
die(err)
|
||||||
if err != nil {
|
|
||||||
die(err)
|
|
||||||
}
|
|
||||||
} else if kubeletConfig == nil {
|
|
||||||
kubeletConfig = defaultConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct a KubeletServer from kubeletFlags and kubeletConfig
|
// construct a KubeletServer from kubeletFlags and kubeletConfig
|
||||||
|
@ -45,6 +45,10 @@ const (
|
|||||||
// alpha: v1.4
|
// alpha: v1.4
|
||||||
DynamicKubeletConfig utilfeature.Feature = "DynamicKubeletConfig"
|
DynamicKubeletConfig utilfeature.Feature = "DynamicKubeletConfig"
|
||||||
|
|
||||||
|
// owner: @mtaufen
|
||||||
|
// alpha: v1.8
|
||||||
|
KubeletConfigFile utilfeature.Feature = "KubeletConfigFile"
|
||||||
|
|
||||||
// owner: @pweil-
|
// owner: @pweil-
|
||||||
// alpha: v1.5
|
// alpha: v1.5
|
||||||
//
|
//
|
||||||
@ -146,6 +150,7 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
|
|||||||
ExternalTrafficLocalOnly: {Default: true, PreRelease: utilfeature.GA},
|
ExternalTrafficLocalOnly: {Default: true, PreRelease: utilfeature.GA},
|
||||||
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},
|
||||||
DynamicVolumeProvisioning: {Default: true, PreRelease: utilfeature.Alpha},
|
DynamicVolumeProvisioning: {Default: true, PreRelease: utilfeature.Alpha},
|
||||||
ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: utilfeature.Beta},
|
ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: utilfeature.Beta},
|
||||||
ExperimentalCriticalPodAnnotation: {Default: false, PreRelease: utilfeature.Alpha},
|
ExperimentalCriticalPodAnnotation: {Default: false, PreRelease: utilfeature.Alpha},
|
||||||
|
@ -78,9 +78,9 @@ type Controller struct {
|
|||||||
// If the `initConfigDir` is an empty string, skips trying to load the init config.
|
// If the `initConfigDir` is an empty string, skips trying to load the init config.
|
||||||
// If the `dynamicConfigDir` is an empty string, skips trying to load checkpoints or download new config,
|
// If the `dynamicConfigDir` is an empty string, skips trying to load checkpoints or download new config,
|
||||||
// but will still sync the ConfigOK condition if you call StartSync with a non-nil client.
|
// but will still sync the ConfigOK condition if you call StartSync with a non-nil client.
|
||||||
func NewController(initConfigDir string,
|
func NewController(defaultConfig *kubeletconfig.KubeletConfiguration,
|
||||||
dynamicConfigDir string,
|
initConfigDir string,
|
||||||
defaultConfig *kubeletconfig.KubeletConfiguration) (*Controller, error) {
|
dynamicConfigDir string) (*Controller, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
fs := utilfs.DefaultFs{}
|
fs := utilfs.DefaultFs{}
|
||||||
|
Loading…
Reference in New Issue
Block a user