From bd3440d111c15435787e16baa6ddbb28b79d6638 Mon Sep 17 00:00:00 2001 From: Omer Aplatony Date: Fri, 27 Sep 2024 14:28:24 +0300 Subject: [PATCH] Common flags across VPA components Signed-off-by: Omer Aplatony --- vertical-pod-autoscaler/common/flags.go | 67 +++++++++++++++++ .../pkg/admission-controller/main.go | 41 +++++----- .../pkg/recommender/main.go | 75 +++++++++---------- vertical-pod-autoscaler/pkg/updater/main.go | 41 ++++------ 4 files changed, 136 insertions(+), 88 deletions(-) create mode 100644 vertical-pod-autoscaler/common/flags.go diff --git a/vertical-pod-autoscaler/common/flags.go b/vertical-pod-autoscaler/common/flags.go new file mode 100644 index 000000000000..73beaa7f1623 --- /dev/null +++ b/vertical-pod-autoscaler/common/flags.go @@ -0,0 +1,67 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package flags - common code for flags of all 3 VPA components + +package common + +import ( + "flag" + "time" + + apiv1 "k8s.io/api/core/v1" + "k8s.io/klog/v2" +) + +// CommonFlags contains flag definitions common to all VPA components +type CommonFlags struct { + KubeConfig string + KubeApiQps float64 + KubeApiBurst float64 + MetricsAddress string + EnableProfiling bool + VpaObjectNamespace string + IgnoredVpaObjectNamespaces string + Interval time.Duration +} + +// InitCommonFlags initializes the common flags +func InitCommonFlags() *CommonFlags { + cf := &CommonFlags{} + flag.StringVar(&cf.KubeConfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.") + flag.Float64Var(&cf.KubeApiQps, "kube-api-qps", 5.0, "QPS limit when making requests to Kubernetes apiserver") + flag.Float64Var(&cf.KubeApiBurst, "kube-api-burst", 10.0, "QPS burst limit when making requests to Kubernetes apiserver") + flag.StringVar(&cf.MetricsAddress, "address", ":8942", "The address to expose Prometheus metrics.") + flag.BoolVar(&cf.EnableProfiling, "profiling", false, "Is debug/pprof endpoint enabled") + flag.StringVar(&cf.VpaObjectNamespace, "vpa-object-namespace", apiv1.NamespaceAll, "Namespace to search for VPA objects. Empty means all namespaces will be used.") + flag.StringVar(&cf.IgnoredVpaObjectNamespaces, "ignored-vpa-object-namespaces", "", "Comma separated list of namespaces to ignore when searching for VPA objects. Empty means no namespaces will be ignored.") + flag.DurationVar(&cf.Interval, "interval", 1*time.Minute, "Interval for fetching metrics or running updater") + return cf +} + +// InitLoggingFlags initializes the logging flags +func InitLoggingFlags() { + flag.Lookup("v").Usage = "set the log level verbosity (default: 2)" + flag.Lookup("stderrthreshold").Usage = "set the log level threshold for writing to standard error (default: info)" + err := flag.Set("v", "2") + if err != nil { + klog.Fatalf("Unable to set log level verbosity: %v", err) + } + err = flag.Set("stderrthreshold", "0") + if err != nil { + klog.Fatalf("Unable to set log level threshold for writing to standard error: %v", err) + } +} diff --git a/vertical-pod-autoscaler/pkg/admission-controller/main.go b/vertical-pod-autoscaler/pkg/admission-controller/main.go index f9d4d824eb14..d512dc88ff5e 100644 --- a/vertical-pod-autoscaler/pkg/admission-controller/main.go +++ b/vertical-pod-autoscaler/pkg/admission-controller/main.go @@ -24,7 +24,6 @@ import ( "strings" "time" - apiv1 "k8s.io/api/core/v1" "k8s.io/client-go/informers" kube_client "k8s.io/client-go/kubernetes" kube_flag "k8s.io/component-base/cli/flag" @@ -66,41 +65,37 @@ var ( ciphers = flag.String("tls-ciphers", "", "A comma-separated or colon-separated list of ciphers to accept. Only works when min-tls-version is set to tls1_2.") minTlsVersion = flag.String("min-tls-version", "tls1_2", "The minimum TLS version to accept. Must be set to either tls1_2 (default) or tls1_3.") - port = flag.Int("port", 8000, "The port to listen on.") - address = flag.String("address", ":8944", "The address to expose Prometheus metrics.") - kubeconfig = flag.String("kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.") - kubeApiQps = flag.Float64("kube-api-qps", 5.0, `QPS limit when making requests to Kubernetes apiserver`) - kubeApiBurst = flag.Float64("kube-api-burst", 10.0, `QPS burst limit when making requests to Kubernetes apiserver`) - enableProfiling = flag.Bool("profiling", false, "Is debug/pprof endpoint enabled") - namespace = os.Getenv("NAMESPACE") - serviceName = flag.String("webhook-service", "vpa-webhook", "Kubernetes service under which webhook is registered. Used when registerByURL is set to false.") - webhookAddress = flag.String("webhook-address", "", "Address under which webhook is registered. Used when registerByURL is set to true.") - webhookPort = flag.String("webhook-port", "", "Server Port for Webhook") - webhookTimeout = flag.Int("webhook-timeout-seconds", 30, "Timeout in seconds that the API server should wait for this webhook to respond before failing.") - webHookFailurePolicy = flag.Bool("webhook-failure-policy-fail", false, "If set to true, will configure the admission webhook failurePolicy to \"Fail\". Use with caution.") - registerWebhook = flag.Bool("register-webhook", true, "If set to true, admission webhook object will be created on start up to register with the API server.") - registerByURL = flag.Bool("register-by-url", false, "If set to true, admission webhook will be registered by URL (webhookAddress:webhookPort) instead of by service name") - vpaObjectNamespace = flag.String("vpa-object-namespace", apiv1.NamespaceAll, "Namespace to search for VPA objects. Empty means all namespaces will be used. Must not be used if ignored-vpa-object-namespaces is set.") - ignoredVpaObjectNamespaces = flag.String("ignored-vpa-object-namespaces", "", "Comma separated list of namespaces to ignore. Must not be used if vpa-object-namespace is used.") + port = flag.Int("port", 8000, "The port to listen on.") + namespace = os.Getenv("NAMESPACE") + serviceName = flag.String("webhook-service", "vpa-webhook", "Kubernetes service under which webhook is registered. Used when registerByURL is set to false.") + webhookAddress = flag.String("webhook-address", "", "Address under which webhook is registered. Used when registerByURL is set to true.") + webhookPort = flag.String("webhook-port", "", "Server Port for Webhook") + webhookTimeout = flag.Int("webhook-timeout-seconds", 30, "Timeout in seconds that the API server should wait for this webhook to respond before failing.") + webHookFailurePolicy = flag.Bool("webhook-failure-policy-fail", false, "If set to true, will configure the admission webhook failurePolicy to \"Fail\". Use with caution.") + registerWebhook = flag.Bool("register-webhook", true, "If set to true, admission webhook object will be created on start up to register with the API server.") + registerByURL = flag.Bool("register-by-url", false, "If set to true, admission webhook will be registered by URL (webhookAddress:webhookPort) instead of by service name") ) func main() { + commonFlags := common.InitCommonFlags() klog.InitFlags(nil) + common.InitLoggingFlags() + flag.Parse() kube_flag.InitFlags() klog.V(1).Infof("Vertical Pod Autoscaler %s Admission Controller", common.VerticalPodAutoscalerVersion) - if len(*vpaObjectNamespace) > 0 && len(*ignoredVpaObjectNamespaces) > 0 { + if len(commonFlags.VpaObjectNamespace) > 0 && len(commonFlags.IgnoredVpaObjectNamespaces) > 0 { klog.Fatalf("--vpa-object-namespace and --ignored-vpa-object-namespaces are mutually exclusive and can't be set together.") } healthCheck := metrics.NewHealthCheck(time.Minute) metrics_admission.Register() - server.Initialize(enableProfiling, healthCheck, address) + server.Initialize(&commonFlags.EnableProfiling, healthCheck, &commonFlags.MetricsAddress) - config := common.CreateKubeConfigOrDie(*kubeconfig, float32(*kubeApiQps), int(*kubeApiBurst)) + config := common.CreateKubeConfigOrDie(commonFlags.KubeConfig, float32(commonFlags.KubeApiQps), int(commonFlags.KubeApiBurst)) vpaClient := vpa_clientset.NewForConfigOrDie(config) - vpaLister := vpa_api_util.NewVpasLister(vpaClient, make(chan struct{}), *vpaObjectNamespace) + vpaLister := vpa_api_util.NewVpasLister(vpaClient, make(chan struct{}), commonFlags.VpaObjectNamespace) kubeClient := kube_client.NewForConfigOrDie(config) factory := informers.NewSharedInformerFactory(kubeClient, defaultResyncPeriod) targetSelectorFetcher := target.NewVpaTargetSelectorFetcher(config, kubeClient, factory) @@ -146,10 +141,10 @@ func main() { TLSConfig: configTLS(*certsConfiguration, *minTlsVersion, *ciphers, stopCh), } url := fmt.Sprintf("%v:%v", *webhookAddress, *webhookPort) - ignoredNamespaces := strings.Split(*ignoredVpaObjectNamespaces, ",") + ignoredNamespaces := strings.Split(commonFlags.IgnoredVpaObjectNamespaces, ",") go func() { if *registerWebhook { - selfRegistration(kubeClient, readFile(*certsConfiguration.clientCaFile), webHookDelay, namespace, *serviceName, url, *registerByURL, int32(*webhookTimeout), *vpaObjectNamespace, ignoredNamespaces, *webHookFailurePolicy) + selfRegistration(kubeClient, readFile(*certsConfiguration.clientCaFile), webHookDelay, namespace, *serviceName, url, *registerByURL, int32(*webhookTimeout), commonFlags.VpaObjectNamespace, ignoredNamespaces, *webHookFailurePolicy) } // Start status updates after the webhook is initialized. statusUpdater.Run(stopCh) diff --git a/vertical-pod-autoscaler/pkg/recommender/main.go b/vertical-pod-autoscaler/pkg/recommender/main.go index 689a2874dfff..642184f117de 100644 --- a/vertical-pod-autoscaler/pkg/recommender/main.go +++ b/vertical-pod-autoscaler/pkg/recommender/main.go @@ -56,34 +56,26 @@ import ( ) var ( - recommenderName = flag.String("recommender-name", input.DefaultRecommenderName, "Set the recommender name. Recommender will generate recommendations for VPAs that configure the same recommender name. If the recommender name is left as default it will also generate recommendations that don't explicitly specify recommender. You shouldn't run two recommenders with the same name in a cluster.") - metricsFetcherInterval = flag.Duration("recommender-interval", 1*time.Minute, `How often metrics should be fetched`) - checkpointsGCInterval = flag.Duration("checkpoints-gc-interval", 10*time.Minute, `How often orphaned checkpoints should be garbage collected`) - prometheusAddress = flag.String("prometheus-address", "", `Where to reach for Prometheus metrics`) - prometheusJobName = flag.String("prometheus-cadvisor-job-name", "kubernetes-cadvisor", `Name of the prometheus job name which scrapes the cAdvisor metrics`) - address = flag.String("address", ":8942", "The address to expose Prometheus metrics.") - kubeconfig = flag.String("kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.") - kubeApiQps = flag.Float64("kube-api-qps", 5.0, `QPS limit when making requests to Kubernetes apiserver`) - kubeApiBurst = flag.Float64("kube-api-burst", 10.0, `QPS burst limit when making requests to Kubernetes apiserver`) - enableProfiling = flag.Bool("profiling", false, "Is debug/pprof endpoint enabled") + recommenderName = flag.String("recommender-name", input.DefaultRecommenderName, "Set the recommender name. Recommender will generate recommendations for VPAs that configure the same recommender name. If the recommender name is left as default it will also generate recommendations that don't explicitly specify recommender. You shouldn't run two recommenders with the same name in a cluster.") + checkpointsGCInterval = flag.Duration("checkpoints-gc-interval", 10*time.Minute, `How often orphaned checkpoints should be garbage collected`) + prometheusAddress = flag.String("prometheus-address", "http://prometheus.monitoring.svc", `Where to reach for Prometheus metrics`) + prometheusJobName = flag.String("prometheus-cadvisor-job-name", "kubernetes-cadvisor", `Name of the prometheus job name which scrapes the cAdvisor metrics`) storage = flag.String("storage", "", `Specifies storage mode. Supported values: prometheus, checkpoint (default)`) // prometheus history provider configs - historyLength = flag.String("history-length", "8d", `How much time back prometheus have to be queried to get historical metrics`) - historyResolution = flag.String("history-resolution", "1h", `Resolution at which Prometheus is queried for historical metrics`) - queryTimeout = flag.String("prometheus-query-timeout", "5m", `How long to wait before killing long queries`) - podLabelPrefix = flag.String("pod-label-prefix", "pod_label_", `Which prefix to look for pod labels in metrics`) - podLabelsMetricName = flag.String("metric-for-pod-labels", "up{job=\"kubernetes-pods\"}", `Which metric to look for pod labels in metrics`) - podNamespaceLabel = flag.String("pod-namespace-label", "kubernetes_namespace", `Label name to look for pod namespaces`) - podNameLabel = flag.String("pod-name-label", "kubernetes_pod_name", `Label name to look for pod names`) - ctrNamespaceLabel = flag.String("container-namespace-label", "namespace", `Label name to look for container namespaces`) - ctrPodNameLabel = flag.String("container-pod-name-label", "pod_name", `Label name to look for container pod names`) - ctrNameLabel = flag.String("container-name-label", "name", `Label name to look for container names`) - vpaObjectNamespace = flag.String("vpa-object-namespace", apiv1.NamespaceAll, "Namespace to search for VPA objects and pod stats. Empty means all namespaces will be used. Must not be used if ignored-vpa-object-namespaces is set.") - ignoredVpaObjectNamespaces = flag.String("ignored-vpa-object-namespaces", "", "Comma separated list of namespaces to ignore. Must not be used if vpa-object-namespace is used.") - username = flag.String("username", "", "The username used in the prometheus server basic auth") - password = flag.String("password", "", "The password used in the prometheus server basic auth") - memorySaver = flag.Bool("memory-saver", false, `If true, only track pods which have an associated VPA`) + historyLength = flag.String("history-length", "8d", `How much time back prometheus have to be queried to get historical metrics`) + historyResolution = flag.String("history-resolution", "1h", `Resolution at which Prometheus is queried for historical metrics`) + queryTimeout = flag.String("prometheus-query-timeout", "5m", `How long to wait before killing long queries`) + podLabelPrefix = flag.String("pod-label-prefix", "pod_label_", `Which prefix to look for pod labels in metrics`) + podLabelsMetricName = flag.String("metric-for-pod-labels", "up{job=\"kubernetes-pods\"}", `Which metric to look for pod labels in metrics`) + podNamespaceLabel = flag.String("pod-namespace-label", "kubernetes_namespace", `Label name to look for pod namespaces`) + podNameLabel = flag.String("pod-name-label", "kubernetes_pod_name", `Label name to look for pod names`) + ctrNamespaceLabel = flag.String("container-namespace-label", "namespace", `Label name to look for container namespaces`) + ctrPodNameLabel = flag.String("container-pod-name-label", "pod_name", `Label name to look for container pod names`) + ctrNameLabel = flag.String("container-name-label", "name", `Label name to look for container names`) + username = flag.String("username", "", "The username used in the prometheus server basic auth") + password = flag.String("password", "", "The password used in the prometheus server basic auth") + memorySaver = flag.Bool("memory-saver", false, `If true, only track pods which have an associated VPA`) // external metrics provider config useExternalMetrics = flag.Bool("use-external-metrics", false, "ALPHA. Use an external metrics provider instead of metrics_server.") externalCpuMetric = flag.String("external-metrics-cpu-metric", "", "ALPHA. Metric to use with external metrics provider for CPU usage.") @@ -117,7 +109,10 @@ const ( ) func main() { + commonFlags := common.InitCommonFlags() klog.InitFlags(nil) + common.InitLoggingFlags() + flag.Parse() leaderElection := defaultLeaderElectionConfiguration() componentbaseoptions.BindLeaderElectionFlags(&leaderElection, pflag.CommandLine) @@ -125,17 +120,17 @@ func main() { kube_flag.InitFlags() klog.V(1).Infof("Vertical Pod Autoscaler %s Recommender: %v", common.VerticalPodAutoscalerVersion, *recommenderName) - if len(*vpaObjectNamespace) > 0 && len(*ignoredVpaObjectNamespaces) > 0 { + if len(commonFlags.VpaObjectNamespace) > 0 && len(commonFlags.IgnoredVpaObjectNamespaces) > 0 { klog.Fatalf("--vpa-object-namespace and --ignored-vpa-object-namespaces are mutually exclusive and can't be set together.") } - healthCheck := metrics.NewHealthCheck(*metricsFetcherInterval * 5) + healthCheck := metrics.NewHealthCheck(commonFlags.Interval * 5) metrics_recommender.Register() metrics_quality.Register() - server.Initialize(enableProfiling, healthCheck, address) + server.Initialize(&commonFlags.EnableProfiling, healthCheck, &commonFlags.MetricsAddress) if !leaderElection.LeaderElect { - run(healthCheck) + run(healthCheck, commonFlags) } else { id, err := os.Hostname() if err != nil { @@ -143,7 +138,7 @@ func main() { } id = id + "_" + string(uuid.NewUUID()) - config := common.CreateKubeConfigOrDie(*kubeconfig, float32(*kubeApiQps), int(*kubeApiBurst)) + config := common.CreateKubeConfigOrDie(commonFlags.KubeConfig, float32(commonFlags.KubeApiQps), int(commonFlags.KubeApiBurst)) kubeClient := kube_client.NewForConfigOrDie(config) lock, err := resourcelock.New( @@ -168,7 +163,7 @@ func main() { ReleaseOnCancel: true, Callbacks: leaderelection.LeaderCallbacks{ OnStartedLeading: func(_ context.Context) { - run(healthCheck) + run(healthCheck, commonFlags) }, OnStoppedLeading: func() { klog.Fatal("lost master") @@ -196,13 +191,13 @@ func defaultLeaderElectionConfiguration() componentbaseconfig.LeaderElectionConf } } -func run(healthCheck *metrics.HealthCheck) { - config := common.CreateKubeConfigOrDie(*kubeconfig, float32(*kubeApiQps), int(*kubeApiBurst)) +func run(healthCheck *metrics.HealthCheck, commonFlag *common.CommonFlags) { + config := common.CreateKubeConfigOrDie(commonFlag.KubeConfig, float32(commonFlag.KubeApiQps), int(commonFlag.KubeApiBurst)) kubeClient := kube_client.NewForConfigOrDie(config) clusterState := model.NewClusterState(aggregateContainerStateGCInterval) - factory := informers.NewSharedInformerFactoryWithOptions(kubeClient, defaultResyncPeriod, informers.WithNamespace(*vpaObjectNamespace)) + factory := informers.NewSharedInformerFactoryWithOptions(kubeClient, defaultResyncPeriod, informers.WithNamespace(commonFlag.IgnoredVpaObjectNamespaces)) controllerFetcher := controllerfetcher.NewControllerFetcher(config, kubeClient, factory, scaleCacheEntryFreshnessTime, scaleCacheEntryLifetime, scaleCacheEntryJitterFactor) - podLister, oomObserver := input.NewPodListerAndOOMObserver(kubeClient, *vpaObjectNamespace) + podLister, oomObserver := input.NewPodListerAndOOMObserver(kubeClient, commonFlag.IgnoredVpaObjectNamespaces) model.InitializeAggregationsConfig(model.NewAggregationsConfig(*memoryAggregationInterval, *memoryAggregationIntervalCount, *memoryHistogramDecayHalfLife, *cpuHistogramDecayHalfLife, *oomBumpUpRatio, *oomMinBumpUp)) @@ -232,15 +227,15 @@ func run(healthCheck *metrics.HealthCheck) { source = input_metrics.NewPodMetricsesSource(resourceclient.NewForConfigOrDie(config)) } - ignoredNamespaces := strings.Split(*ignoredVpaObjectNamespaces, ",") + ignoredNamespaces := strings.Split(commonFlag.IgnoredVpaObjectNamespaces, ",") clusterStateFeeder := input.ClusterStateFeederFactory{ PodLister: podLister, OOMObserver: oomObserver, KubeClient: kubeClient, - MetricsClient: input_metrics.NewMetricsClient(source, *vpaObjectNamespace, "default-metrics-client"), + MetricsClient: input_metrics.NewMetricsClient(source, commonFlag.VpaObjectNamespace, "default-metrics-client"), VpaCheckpointClient: vpa_clientset.NewForConfigOrDie(config).AutoscalingV1(), - VpaLister: vpa_api_util.NewVpasLister(vpa_clientset.NewForConfigOrDie(config), make(chan struct{}), *vpaObjectNamespace), + VpaLister: vpa_api_util.NewVpasLister(vpa_clientset.NewForConfigOrDie(config), make(chan struct{}), commonFlag.VpaObjectNamespace), ClusterState: clusterState, SelectorFetcher: target.NewVpaTargetSelectorFetcher(config, kubeClient, factory), MemorySaveMode: *memorySaver, @@ -283,7 +278,7 @@ func run(healthCheck *metrics.HealthCheck) { CtrPodNameLabel: *ctrPodNameLabel, CtrNameLabel: *ctrNameLabel, CadvisorMetricsJobName: *prometheusJobName, - Namespace: *vpaObjectNamespace, + Namespace: commonFlag.VpaObjectNamespace, PrometheusBasicAuthTransport: history.PrometheusBasicAuthTransport{ Username: *username, Password: *password, @@ -299,7 +294,7 @@ func run(healthCheck *metrics.HealthCheck) { // Start updating health check endpoint. healthCheck.StartMonitoring() - ticker := time.Tick(*metricsFetcherInterval) + ticker := time.Tick(commonFlag.Interval) for range ticker { recommender.RunOnce() healthCheck.UpdateLastActivity() diff --git a/vertical-pod-autoscaler/pkg/updater/main.go b/vertical-pod-autoscaler/pkg/updater/main.go index 771ebd7e60fc..da569743920c 100644 --- a/vertical-pod-autoscaler/pkg/updater/main.go +++ b/vertical-pod-autoscaler/pkg/updater/main.go @@ -24,7 +24,6 @@ import ( "time" "github.com/spf13/pflag" - apiv1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/client-go/informers" @@ -51,9 +50,6 @@ import ( ) var ( - updaterInterval = flag.Duration("updater-interval", 1*time.Minute, - `How often updater should run`) - minReplicas = flag.Int("min-replicas", 2, `Minimum number of replicas to perform update`) @@ -66,18 +62,10 @@ var ( evictionRateBurst = flag.Int("eviction-rate-burst", 1, `Burst of pods that can be evicted.`) - address = flag.String("address", ":8943", "The address to expose Prometheus metrics.") - kubeconfig = flag.String("kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.") - kubeApiQps = flag.Float64("kube-api-qps", 5.0, `QPS limit when making requests to Kubernetes apiserver`) - kubeApiBurst = flag.Float64("kube-api-burst", 10.0, `QPS burst limit when making requests to Kubernetes apiserver`) - enableProfiling = flag.Bool("profiling", false, "Is debug/pprof endpoint enabled") - useAdmissionControllerStatus = flag.Bool("use-admission-controller-status", true, "If true, updater will only evict pods when admission controller status is valid.") - namespace = os.Getenv("NAMESPACE") - vpaObjectNamespace = flag.String("vpa-object-namespace", apiv1.NamespaceAll, "Namespace to search for VPA objects. Empty means all namespaces will be used. Must not be used if ignored-vpa-object-namespaces is set.") - ignoredVpaObjectNamespaces = flag.String("ignored-vpa-object-namespaces", "", "Comma separated list of namespaces to ignore. Must not be used if vpa-object-namespace is used.") + namespace = os.Getenv("NAMESPACE") ) const ( @@ -88,7 +76,10 @@ const ( ) func main() { + commonFlags := common.InitCommonFlags() klog.InitFlags(nil) + common.InitLoggingFlags() + flag.Parse() leaderElection := defaultLeaderElectionConfiguration() componentbaseoptions.BindLeaderElectionFlags(&leaderElection, pflag.CommandLine) @@ -96,17 +87,17 @@ func main() { kube_flag.InitFlags() klog.V(1).Infof("Vertical Pod Autoscaler %s Updater", common.VerticalPodAutoscalerVersion) - if len(*vpaObjectNamespace) > 0 && len(*ignoredVpaObjectNamespaces) > 0 { + if len(commonFlags.VpaObjectNamespace) > 0 && len(commonFlags.IgnoredVpaObjectNamespaces) > 0 { klog.Fatalf("--vpa-object-namespace and --ignored-vpa-object-namespaces are mutually exclusive and can't be set together.") } - healthCheck := metrics.NewHealthCheck(*updaterInterval * 5) - server.Initialize(enableProfiling, healthCheck, address) + healthCheck := metrics.NewHealthCheck(commonFlags.Interval) + server.Initialize(&commonFlags.EnableProfiling, healthCheck, &commonFlags.MetricsAddress) metrics_updater.Register() if !leaderElection.LeaderElect { - run(healthCheck) + run(healthCheck, commonFlags) } else { id, err := os.Hostname() if err != nil { @@ -114,7 +105,7 @@ func main() { } id = id + "_" + string(uuid.NewUUID()) - config := common.CreateKubeConfigOrDie(*kubeconfig, float32(*kubeApiQps), int(*kubeApiBurst)) + config := common.CreateKubeConfigOrDie(commonFlags.KubeConfig, float32(commonFlags.KubeApiQps), int(commonFlags.KubeApiBurst)) kubeClient := kube_client.NewForConfigOrDie(config) lock, err := resourcelock.New( @@ -139,7 +130,7 @@ func main() { ReleaseOnCancel: true, Callbacks: leaderelection.LeaderCallbacks{ OnStartedLeading: func(_ context.Context) { - run(healthCheck) + run(healthCheck, commonFlags) }, OnStoppedLeading: func() { klog.Fatal("lost master") @@ -167,8 +158,8 @@ func defaultLeaderElectionConfiguration() componentbaseconfig.LeaderElectionConf } } -func run(healthCheck *metrics.HealthCheck) { - config := common.CreateKubeConfigOrDie(*kubeconfig, float32(*kubeApiQps), int(*kubeApiBurst)) +func run(healthCheck *metrics.HealthCheck, commonFlag *common.CommonFlags) { + config := common.CreateKubeConfigOrDie(commonFlag.KubeConfig, float32(commonFlag.KubeApiQps), int(commonFlag.KubeApiBurst)) kubeClient := kube_client.NewForConfigOrDie(config) vpaClient := vpa_clientset.NewForConfigOrDie(config) factory := informers.NewSharedInformerFactory(kubeClient, defaultResyncPeriod) @@ -185,7 +176,7 @@ func run(healthCheck *metrics.HealthCheck) { admissionControllerStatusNamespace = namespace } - ignoredNamespaces := strings.Split(*ignoredVpaObjectNamespaces, ",") + ignoredNamespaces := strings.Split(commonFlag.IgnoredVpaObjectNamespaces, ",") // TODO: use SharedInformerFactory in updater updater, err := updater.NewUpdater( @@ -202,7 +193,7 @@ func run(healthCheck *metrics.HealthCheck) { targetSelectorFetcher, controllerFetcher, priority.NewProcessor(), - *vpaObjectNamespace, + commonFlag.VpaObjectNamespace, ignoredNamespaces, ) if err != nil { @@ -212,9 +203,9 @@ func run(healthCheck *metrics.HealthCheck) { // Start updating health check endpoint. healthCheck.StartMonitoring() - ticker := time.Tick(*updaterInterval) + ticker := time.Tick(commonFlag.Interval) for range ticker { - ctx, cancel := context.WithTimeout(context.Background(), *updaterInterval) + ctx, cancel := context.WithTimeout(context.Background(), commonFlag.Interval) updater.RunOnce(ctx) healthCheck.UpdateLastActivity() cancel()