diff --git a/docs/developer/cli-arguments.md b/docs/developer/cli-arguments.md index 33818c33a..3b5888891 100644 --- a/docs/developer/cli-arguments.md +++ b/docs/developer/cli-arguments.md @@ -4,7 +4,7 @@ kube-state-metrics can be configured through command line arguments. Those arguments can be passed during startup when running locally: -`kube-state-metrics --telemetry-port=8081 --kubeconfig= --apiserver= ...` + `kube-state-metrics --telemetry-port=8081 --kubeconfig= --apiserver= ...` Or configured in the `args` section of your deployment configuration in a Kubernetes / Openshift context: @@ -38,55 +38,57 @@ Available Commands: version Print version information. Flags: - --add_dir_header If true, adds the file directory to the header of the log messages - --alsologtostderr log to standard error as well as files (no effect when -logtostderr=true) - --apiserver string The URL of the apiserver to use as a master - --auth-filter If true, requires authentication and authorization through Kubernetes API to access metrics endpoints - --auto-gomemlimit Automatically set GOMEMLIMIT to match container or system memory limit. (experimental) - --auto-gomemlimit-ratio float The ratio of reserved GOMEMLIMIT memory to the detected maximum container or system memory. (experimental) (default 0.9) - --config string Path to the kube-state-metrics options config YAML file. If this flag is set, the flags defined in the file override the command line flags. - --custom-resource-state-config string Inline Custom Resource State Metrics config YAML (experimental) - --custom-resource-state-config-file string Path to a Custom Resource State Metrics config file (experimental) - --custom-resource-state-only Only provide Custom Resource State metrics (experimental) - --enable-gzip-encoding Gzip responses when requested by clients via 'Accept-Encoding: gzip' header. - -h, --help Print Help text - --host string Host to expose metrics on. (default "::") - --kubeconfig string Absolute path to the kubeconfig file - --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) - --log_dir string If non-empty, write log files in this directory (no effect when -logtostderr=true) - --log_file string If non-empty, use this log file (no effect when -logtostderr=true) - --log_file_max_size uint Defines the maximum size a log file can grow to (no effect when -logtostderr=true). Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) - --logtostderr log to standard error instead of files (default true) - --metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or *ECMAScript-based* regex patterns. The allowlist and denylist are mutually exclusive. - --metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the annotations metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]'). - --metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or *ECMAScript-based* regex patterns. The allowlist and denylist are mutually exclusive. - --metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the labels metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'. - --metric-opt-in-list string Comma-separated list of metrics which are opt-in and not enabled by default. This is in addition to the metric allow- and denylists - --namespaces string Comma-separated list of namespaces to be enabled. Defaults to "" - --namespaces-denylist string Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set, only namespaces that are excluded in namespaces-denylist will be used. - --node string Name of the node that contains the kube-state-metrics pod. Most likely it should be passed via the downward API. This is used for daemonset sharding. Only available for resources (pod metrics) that support spec.nodeName fieldSelector. This is experimental. - --object-limit int The total number of objects to list per resource from the API Server. (experimental) - --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level; no effect when -logtostderr=true) - --pod string Name of the pod that contains the kube-state-metrics container. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice. - --pod-namespace string Name of the namespace of the pod specified by --pod. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice. - --port int Port to expose metrics on. (default 8080) - --resources string Comma-separated list of Resources to be enabled. Defaults to "certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,leases,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments" - --server-idle-timeout duration The maximum amount of time to wait for the next request when keep-alives are enabled. Align with the idletimeout of your scrape clients. (default 5m0s) - --server-read-header-timeout duration The maximum duration for reading the header of requests. (default 5s) - --server-read-timeout duration The maximum duration for reading the entire request, including the body. Align with the scrape interval or timeout of scraping clients. (default 1m0s) - --server-write-timeout duration The maximum duration before timing out writes of the response. Align with the scrape interval or timeout of scraping clients.. (default 1m0s) - --shard int32 The instances shard nominal (zero indexed) within the total number of shards. (default 0) - --skip_headers If true, avoid header prefixes in the log messages - --skip_log_headers If true, avoid headers when opening log files (no effect when -logtostderr=true) - --stderrthreshold severity logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=true) (default 2) - --telemetry-host string Host to expose kube-state-metrics self metrics on. (default "::") - --telemetry-port int Port to expose kube-state-metrics self metrics on. (default 8081) - --tls-config string Path to the TLS configuration file - --total-shards int The total number of shards. Sharding is disabled when total shards is set to 1. (default 1) - --track-unscheduled-pods This configuration is used in conjunction with node configuration. When this configuration is true, node configuration is empty and the metric of unscheduled pods is fetched from the Kubernetes API Server. This is experimental. - --use-apiserver-cache Sets resourceVersion=0 for ListWatch requests, using cached resources from the apiserver instead of an etcd quorum read. - -v, --v Level number for the log level verbosity - --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging + --add_dir_header If true, adds the file directory to the header of the log messages + --alsologtostderr log to standard error as well as files (no effect when -logtostderr=true) + --apiserver string The URL of the apiserver to use as a master + --auth-filter If true, requires authentication and authorization through Kubernetes API to access metrics endpoints + --auto-gomemlimit Automatically set GOMEMLIMIT to match container or system memory limit. (experimental) + --auto-gomemlimit-ratio float The ratio of reserved GOMEMLIMIT memory to the detected maximum container or system memory. (experimental) (default 0.9) + --config string Path to the kube-state-metrics options config YAML file. If this flag is set, the flags defined in the file override the command line flags. + --continue-without-config If true, kube-state-metrics continues to run even if the config file specified by --config is not present. This is useful for scenarios where config file is not provided at startup but is provided later, for e.g., via configmap. Kube-state-metrics will not exit with an error if the config file is not found, instead watches and reloads when it is created. + --continue-without-custom-resource-state-config-file If true, Kube-state-metrics continues to run even if the config file specified by --custom-resource-state-config-file is not present. This is useful for scenarios where config file is not provided at startup but is provided later, for e.g., via configmap. Kube-state-metrics will not exit with an error if the custom-resource-state-config file is not found, instead watches and reloads when it is created. + --custom-resource-state-config string Inline Custom Resource State Metrics config YAML (experimental) + --custom-resource-state-config-file string Path to a Custom Resource State Metrics config file (experimental) + --custom-resource-state-only Only provide Custom Resource State metrics (experimental) + --enable-gzip-encoding Gzip responses when requested by clients via 'Accept-Encoding: gzip' header. + -h, --help Print Help text + --host string Host to expose metrics on. (default "::") + --kubeconfig string Absolute path to the kubeconfig file + --log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0) + --log_dir string If non-empty, write log files in this directory (no effect when -logtostderr=true) + --log_file string If non-empty, use this log file (no effect when -logtostderr=true) + --log_file_max_size uint Defines the maximum size a log file can grow to (no effect when -logtostderr=true). Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800) + --logtostderr log to standard error instead of files (default true) + --metric-allowlist string Comma-separated list of metrics to be exposed. This list comprises of exact metric names and/or *ECMAScript-based* regex patterns. The allowlist and denylist are mutually exclusive. + --metric-annotations-allowlist string Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the annotations metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]'). + --metric-denylist string Comma-separated list of metrics not to be enabled. This list comprises of exact metric names and/or *ECMAScript-based* regex patterns. The allowlist and denylist are mutually exclusive. + --metric-labels-allowlist string Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the labels metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'. + --metric-opt-in-list string Comma-separated list of metrics which are opt-in and not enabled by default. This is in addition to the metric allow- and denylists + --namespaces string Comma-separated list of namespaces to be enabled. Defaults to "" + --namespaces-denylist string Comma-separated list of namespaces not to be enabled. If namespaces and namespaces-denylist are both set, only namespaces that are excluded in namespaces-denylist will be used. + --node string Name of the node that contains the kube-state-metrics pod. Most likely it should be passed via the downward API. This is used for daemonset sharding. Only available for resources (pod metrics) that support spec.nodeName fieldSelector. This is experimental. + --object-limit int The total number of objects to list per resource from the API Server. (experimental) + --one_output If true, only write logs to their native severity level (vs also writing to each lower severity level; no effect when -logtostderr=true) + --pod string Name of the pod that contains the kube-state-metrics container. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice. + --pod-namespace string Name of the namespace of the pod specified by --pod. When set, it is expected that --pod and --pod-namespace are both set. Most likely this should be passed via the downward API. This is used for auto-detecting sharding. If set, this has preference over statically configured sharding. This is experimental, it may be removed without notice. + --port int Port to expose metrics on. (default 8080) + --resources string Comma-separated list of Resources to be enabled. Defaults to "certificatesigningrequests,configmaps,cronjobs,daemonsets,deployments,endpoints,horizontalpodautoscalers,ingresses,jobs,leases,limitranges,mutatingwebhookconfigurations,namespaces,networkpolicies,nodes,persistentvolumeclaims,persistentvolumes,poddisruptionbudgets,pods,replicasets,replicationcontrollers,resourcequotas,secrets,services,statefulsets,storageclasses,validatingwebhookconfigurations,volumeattachments" + --server-idle-timeout duration The maximum amount of time to wait for the next request when keep-alives are enabled. Align with the idletimeout of your scrape clients. (default 5m0s) + --server-read-header-timeout duration The maximum duration for reading the header of requests. (default 5s) + --server-read-timeout duration The maximum duration for reading the entire request, including the body. Align with the scrape interval or timeout of scraping clients. (default 1m0s) + --server-write-timeout duration The maximum duration before timing out writes of the response. Align with the scrape interval or timeout of scraping clients.. (default 1m0s) + --shard int32 The instances shard nominal (zero indexed) within the total number of shards. (default 0) + --skip_headers If true, avoid header prefixes in the log messages + --skip_log_headers If true, avoid headers when opening log files (no effect when -logtostderr=true) + --stderrthreshold severity logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=true) (default 2) + --telemetry-host string Host to expose kube-state-metrics self metrics on. (default "::") + --telemetry-port int Port to expose kube-state-metrics self metrics on. (default 8081) + --tls-config string Path to the TLS configuration file + --total-shards int The total number of shards. Sharding is disabled when total shards is set to 1. (default 1) + --track-unscheduled-pods This configuration is used in conjunction with node configuration. When this configuration is true, node configuration is empty and the metric of unscheduled pods is fetched from the Kubernetes API Server. This is experimental. + --use-apiserver-cache Sets resourceVersion=0 for ListWatch requests, using cached resources from the apiserver instead of an etcd quorum read. + -v, --v Level number for the log level verbosity + --vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging Use "kube-state-metrics [command] --help" for more information about a command. ``` diff --git a/internal/wrapper.go b/internal/wrapper.go index ce9b1047c..4a1024b2e 100644 --- a/internal/wrapper.go +++ b/internal/wrapper.go @@ -43,17 +43,25 @@ func RunKubeStateMetricsWrapper(opts *options.Options) { } ctx, cancel := context.WithCancel(context.Background()) + if file := options.GetConfigFile(*opts); file != "" { cfgViper := viper.New() cfgViper.SetConfigType("yaml") cfgViper.SetConfigFile(file) - if err := cfgViper.ReadInConfig(); err != nil { - if errors.Is(err, viper.ConfigFileNotFoundError{}) { - klog.ErrorS(err, "Options configuration file not found", "file", file) + var cfgViperReadInConfigErr error + if cfgViperReadInConfigErr = cfgViper.ReadInConfig(); cfgViperReadInConfigErr != nil { + if errors.Is(cfgViperReadInConfigErr, viper.ConfigFileNotFoundError{}) { + klog.ErrorS(cfgViperReadInConfigErr, "Options configuration file not found at startup", "file", file) + } else if _, isNotExisterr := os.Stat(filepath.Clean(file)); isNotExisterr != nil { + // TODO: Remove this check once viper.ConfigFileNotFoundError is working as expected, see this issue - + // https://github.com/spf13/viper/issues/1783 + klog.ErrorS(isNotExisterr, "Options configuration file not found at startup", "file", file) } else { - klog.ErrorS(err, "Error reading options configuration file", "file", file) + klog.ErrorS(cfgViperReadInConfigErr, "Error reading options configuration file", "file", file) + } + if !opts.ContinueWithoutConfig { + klog.FlushAndExit(klog.ExitFlushTimeout, 1) } - klog.FlushAndExit(klog.ExitFlushTimeout, 1) } cfgViper.OnConfigChange(func(e fsnotify.Event) { klog.InfoS("Changes detected", "name", e.Name) @@ -65,25 +73,33 @@ func RunKubeStateMetricsWrapper(opts *options.Options) { }) cfgViper.WatchConfig() - // Merge configFile values with opts so we get the CustomResourceConfigFile from config as well - configFile, err := os.ReadFile(filepath.Clean(file)) - if err != nil { - klog.ErrorS(err, "failed to read options configuration file", "file", file) - } + if cfgViperReadInConfigErr == nil { + // Merge configFile values with opts so we get the CustomResourceConfigFile from config as well + configFile, err := os.ReadFile(filepath.Clean(file)) + if err != nil { + klog.ErrorS(err, "failed to read options configuration file", "file", file) + } - yaml.Unmarshal(configFile, opts) + yaml.Unmarshal(configFile, opts) + } } if opts.CustomResourceConfigFile != "" { crcViper := viper.New() crcViper.SetConfigType("yaml") crcViper.SetConfigFile(opts.CustomResourceConfigFile) - if err := crcViper.ReadInConfig(); err != nil { - if errors.Is(err, viper.ConfigFileNotFoundError{}) { - klog.ErrorS(err, "Custom resource configuration file not found", "file", opts.CustomResourceConfigFile) + if cfgViperReadInConfigErr := crcViper.ReadInConfig(); cfgViperReadInConfigErr != nil { + if errors.Is(cfgViperReadInConfigErr, viper.ConfigFileNotFoundError{}) { + klog.ErrorS(cfgViperReadInConfigErr, "Custom resource configuration file not found at startup", "file", opts.CustomResourceConfigFile) + } else if _, isNotExisterr := os.Stat(filepath.Clean(opts.CustomResourceConfigFile)); isNotExisterr != nil { + // Adding this check in addition to the above since viper.ConfigFileNotFoundError is not working as expected due to this issue - + // https://github.com/spf13/viper/issues/1783 + klog.ErrorS(isNotExisterr, "Custom resource configuration file not found at startup", "file", opts.CustomResourceConfigFile) } else { - klog.ErrorS(err, "Error reading Custom resource configuration file", "file", opts.CustomResourceConfigFile) + klog.ErrorS(cfgViperReadInConfigErr, "Error reading Custom resource configuration file", "file", opts.CustomResourceConfigFile) + } + if !opts.ContinueWithoutCustomResourceConfigFile { + klog.FlushAndExit(klog.ExitFlushTimeout, 1) } - klog.FlushAndExit(klog.ExitFlushTimeout, 1) } crcViper.OnConfigChange(func(e fsnotify.Event) { klog.InfoS("Changes detected", "name", e.Name) diff --git a/pkg/app/server.go b/pkg/app/server.go index 54ec61a4b..e8955d7d8 100644 --- a/pkg/app/server.go +++ b/pkg/app/server.go @@ -125,31 +125,36 @@ func RunKubeStateMetrics(ctx context.Context, opts *options.Options) error { }) storeBuilder := store.NewBuilder() storeBuilder.WithMetrics(ksmMetricsRegistry) - got := options.GetConfigFile(*opts) if got != "" { - configFile, err := os.ReadFile(filepath.Clean(got)) - if err != nil { - return fmt.Errorf("failed to read opts config file: %v", err) - } - // NOTE: Config value will override default values of intersecting options. - err = yaml.Unmarshal(configFile, opts) - if err != nil { - // DO NOT end the process. - // We want to allow the user to still be able to fix the misconfigured config (redeploy or edit the configmaps) and reload KSM automatically once that's done. - klog.ErrorS(err, "failed to unmarshal opts config file") - // Wait for the next reload. - klog.InfoS("misconfigured config detected, KSM will automatically reload on next write to the config") - klog.InfoS("waiting for config to be fixed") - configSuccess.WithLabelValues("config", filepath.Clean(got)).Set(0) - <-ctx.Done() + if _, err := os.Stat(filepath.Clean(got)); err != nil { + klog.ErrorS(err, "encountered error while processing the file", "file", got) } else { - configSuccess.WithLabelValues("config", filepath.Clean(got)).Set(1) - configSuccessTime.WithLabelValues("config", filepath.Clean(got)).SetToCurrentTime() - hash := md5HashAsMetricValue(configFile) - configHash.WithLabelValues("config", filepath.Clean(got)).Set(hash) + configFile, err := os.ReadFile(filepath.Clean(got)) + if err != nil { + return fmt.Errorf("failed to read opts config file: %v", err) + } + // NOTE: Config value will override default values of intersecting options. + err = yaml.Unmarshal(configFile, opts) + + if err != nil { + // DO NOT end the process. + // We want to allow the user to still be able to fix the misconfigured config (redeploy or edit the configmaps) and reload KSM automatically once that's done. + klog.ErrorS(err, "failed to unmarshal opts config file") + // Wait for the next reload. + klog.InfoS("misconfigured config detected, KSM will automatically reload on next write to the config") + klog.InfoS("waiting for config to be fixed") + configSuccess.WithLabelValues("config", filepath.Clean(got)).Set(0) + <-ctx.Done() + } else { + configSuccess.WithLabelValues("config", filepath.Clean(got)).Set(1) + configSuccessTime.WithLabelValues("config", filepath.Clean(got)).SetToCurrentTime() + hash := md5HashAsMetricValue(configFile) + configHash.WithLabelValues("config", filepath.Clean(got)).Set(hash) + } + opts = configureResourcesAndMetrics(opts, configFile) + klog.InfoS("Using config file", "file", got) } - opts = configureResourcesAndMetrics(opts, configFile) } if opts.AutoGoMemlimit { @@ -178,15 +183,18 @@ func RunKubeStateMetrics(ctx context.Context, opts *options.Options) error { } if opts.CustomResourceConfigFile != "" { - crcFile, err := os.ReadFile(filepath.Clean(opts.CustomResourceConfigFile)) - if err != nil { - return fmt.Errorf("failed to read custom resource config file: %v", err) + if _, err := os.Stat(filepath.Clean(opts.CustomResourceConfigFile)); err != nil { + klog.ErrorS(err, "encountered error while processing the file", "file", opts.CustomResourceConfigFile) + } else { + crcFile, err := os.ReadFile(filepath.Clean(opts.CustomResourceConfigFile)) + if err != nil { + return fmt.Errorf("failed to read custom resource config file: %v", err) + } + configSuccess.WithLabelValues("customresourceconfig", filepath.Clean(opts.CustomResourceConfigFile)).Set(1) + configSuccessTime.WithLabelValues("customresourceconfig", filepath.Clean(opts.CustomResourceConfigFile)).SetToCurrentTime() + hash := md5HashAsMetricValue(crcFile) + configHash.WithLabelValues("customresourceconfig", filepath.Clean(opts.CustomResourceConfigFile)).Set(hash) } - configSuccess.WithLabelValues("customresourceconfig", filepath.Clean(opts.CustomResourceConfigFile)).Set(1) - configSuccessTime.WithLabelValues("customresourceconfig", filepath.Clean(opts.CustomResourceConfigFile)).SetToCurrentTime() - hash := md5HashAsMetricValue(crcFile) - configHash.WithLabelValues("customresourceconfig", filepath.Clean(opts.CustomResourceConfigFile)).Set(hash) - } resources := []string{} @@ -596,11 +604,17 @@ func resolveCustomResourceConfig(opts *options.Options) (customresourcestate.Con return yaml.NewDecoder(strings.NewReader(s)), nil } if file := opts.CustomResourceConfigFile; file != "" { - f, err := os.Open(filepath.Clean(file)) - if err != nil { - return nil, fmt.Errorf("unable to open Custom Resource State Metrics file: %v", err) + if opts.ContinueWithoutCustomResourceConfigFile { + if _, err := os.Stat(filepath.Clean(file)); err != nil { + klog.ErrorS(err, "failed to open Custom Resource State Metrics file, ignoring", "file", file) + } + } else { + f, err := os.Open(filepath.Clean(file)) + if err != nil { + return nil, fmt.Errorf("unable to open Custom Resource State Metrics file: %v", err) + } + return yaml.NewDecoder(f), nil } - return yaml.NewDecoder(f), nil } return nil, nil } diff --git a/pkg/options/options.go b/pkg/options/options.go index f652ac9f1..580cef6c7 100644 --- a/pkg/options/options.go +++ b/pkg/options/options.go @@ -47,19 +47,21 @@ type Options struct { MetricOptInList MetricSet `yaml:"metric_opt_in_list"` Resources ResourceSet `yaml:"resources"` - cmd *cobra.Command - Apiserver string `yaml:"apiserver"` - CustomResourceConfig string `yaml:"custom_resource_config"` - CustomResourceConfigFile string `yaml:"custom_resource_config_file"` - Host string `yaml:"host"` - Kubeconfig string `yaml:"kubeconfig"` - Namespace string `yaml:"namespace"` - Node NodeType `yaml:"node"` - Pod string `yaml:"pod"` - TLSConfig string `yaml:"tls_config"` - TelemetryHost string `yaml:"telemetry_host"` - - Config string + cmd *cobra.Command + Apiserver string `yaml:"apiserver"` + CustomResourceConfig string `yaml:"custom_resource_config"` + CustomResourceConfigFile string `yaml:"custom_resource_state_config_file"` + ContinueWithoutCustomResourceConfigFile bool `yaml:"continue_without_custom_resource_state_config_file"` + Host string `yaml:"host"` + Kubeconfig string `yaml:"kubeconfig"` + Namespace string `yaml:"namespace"` + Node NodeType `yaml:"node"` + Pod string `yaml:"pod"` + TLSConfig string `yaml:"tls_config"` + TelemetryHost string `yaml:"telemetry_host"` + + Config string + ContinueWithoutConfig bool `yaml:"continue_without_config"` Namespaces NamespaceList `yaml:"namespaces"` NamespacesDenylist NamespaceList `yaml:"namespaces_denylist"` @@ -156,6 +158,7 @@ func (o *Options) AddFlags(cmd *cobra.Command) { o.cmd.Flags().Float64Var(&o.AutoGoMemlimitRatio, "auto-gomemlimit-ratio", float64(0.9), "The ratio of reserved GOMEMLIMIT memory to the detected maximum container or system memory. (experimental)") o.cmd.Flags().StringVar(&o.CustomResourceConfig, "custom-resource-state-config", "", "Inline Custom Resource State Metrics config YAML (experimental)") o.cmd.Flags().StringVar(&o.CustomResourceConfigFile, "custom-resource-state-config-file", "", "Path to a Custom Resource State Metrics config file (experimental)") + o.cmd.Flags().BoolVar(&o.ContinueWithoutCustomResourceConfigFile, "continue-without-custom-resource-state-config-file", false, "If true, Kube-state-metrics continues to run even if the config file specified by --custom-resource-state-config-file is not present. This is useful for scenarios where config file is not provided at startup but is provided later, for e.g., via configmap. Kube-state-metrics will not exit with an error if the custom-resource-state-config file is not found, instead watches and reloads when it is created.") o.cmd.Flags().StringVar(&o.Host, "host", "::", `Host to expose metrics on.`) o.cmd.Flags().StringVar(&o.Kubeconfig, "kubeconfig", "", "Absolute path to the kubeconfig file") o.cmd.Flags().StringVar(&o.Namespace, "pod-namespace", "", "Name of the namespace of the pod specified by --pod. "+autoshardingNotice) @@ -163,6 +166,7 @@ func (o *Options) AddFlags(cmd *cobra.Command) { o.cmd.Flags().StringVar(&o.TLSConfig, "tls-config", "", "Path to the TLS configuration file") o.cmd.Flags().StringVar(&o.TelemetryHost, "telemetry-host", "::", `Host to expose kube-state-metrics self metrics on.`) o.cmd.Flags().StringVar(&o.Config, "config", "", "Path to the kube-state-metrics options config YAML file. If this flag is set, the flags defined in the file override the command line flags.") + o.cmd.Flags().BoolVar(&o.ContinueWithoutConfig, "continue-without-config", false, "If true, kube-state-metrics continues to run even if the config file specified by --config is not present. This is useful for scenarios where config file is not provided at startup but is provided later, for e.g., via configmap. Kube-state-metrics will not exit with an error if the config file is not found, instead watches and reloads when it is created.") o.cmd.Flags().StringVar((*string)(&o.Node), "node", "", "Name of the node that contains the kube-state-metrics pod. Most likely it should be passed via the downward API. This is used for daemonset sharding. Only available for resources (pod metrics) that support spec.nodeName fieldSelector. This is experimental.") o.cmd.Flags().Var(&o.AnnotationsAllowList, "metric-annotations-allowlist", "Comma-separated list of Kubernetes annotations keys that will be used in the resource' labels metric. By default the annotations metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. A single '*' can be provided per resource instead to allow any annotations, but that has severe performance implications (Example: '=pods=[*]').") o.cmd.Flags().Var(&o.LabelsAllowList, "metric-labels-allowlist", "Comma-separated list of additional Kubernetes label keys that will be used in the resource' labels metric. By default the labels metrics are not exposed. To include them, provide a list of resource names in their plural form and Kubernetes label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. A single '*' can be provided per resource instead to allow any labels, but that has severe performance implications (Example: '=pods=[*]'). Additionally, an asterisk (*) can be provided as a key, which will resolve to all resources, i.e., assuming '--resources=deployments,pods', '=*=[*]' will resolve to '=deployments=[*],pods=[*]'.")