-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reload CustomResourceState Config File on Change #1928
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ import ( | |
"os" | ||
"path/filepath" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"gopkg.in/yaml.v3" | ||
|
@@ -47,6 +48,7 @@ import ( | |
"k8s.io/kube-state-metrics/v2/internal/store" | ||
"k8s.io/kube-state-metrics/v2/pkg/allowdenylist" | ||
"k8s.io/kube-state-metrics/v2/pkg/customresource" | ||
"k8s.io/kube-state-metrics/v2/pkg/customresourcestate" | ||
generator "k8s.io/kube-state-metrics/v2/pkg/metric_generator" | ||
"k8s.io/kube-state-metrics/v2/pkg/metricshandler" | ||
"k8s.io/kube-state-metrics/v2/pkg/optin" | ||
|
@@ -73,8 +75,8 @@ func (pl promLogger) Log(v ...interface{}) error { | |
} | ||
|
||
// RunKubeStateMetricsWrapper runs KSM with context cancellation. | ||
func RunKubeStateMetricsWrapper(ctx context.Context, opts *options.Options, factories ...customresource.RegistryFactory) error { | ||
err := RunKubeStateMetrics(ctx, opts, factories...) | ||
func RunKubeStateMetricsWrapper(ctx context.Context, opts *options.Options) error { | ||
err := RunKubeStateMetrics(ctx, opts) | ||
if ctx.Err() == context.Canceled { | ||
klog.Infoln("Restarting: kube-state-metrics, metrics will be reset") | ||
return nil | ||
|
@@ -85,11 +87,10 @@ func RunKubeStateMetricsWrapper(ctx context.Context, opts *options.Options, fact | |
// RunKubeStateMetrics will build and run the kube-state-metrics. | ||
// Any out-of-tree custom resource metrics could be registered by newing a registry factory | ||
// which implements customresource.RegistryFactory and pass all factories into this function. | ||
func RunKubeStateMetrics(ctx context.Context, opts *options.Options, factories ...customresource.RegistryFactory) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @mrueg, I found that this parameter As #1644 shows, this parameter is for some repository which does not use custom resource config file and wants to add their own metrics collecting logic in their codes. So a user could construct a new repository and vendor KSM as a dependency in So do you have any ideas about this scenario? |
||
func RunKubeStateMetrics(ctx context.Context, opts *options.Options) error { | ||
promLogger := promLogger{} | ||
|
||
storeBuilder := store.NewBuilder() | ||
storeBuilder.WithCustomResourceStoreFactories(factories...) | ||
|
||
ksmMetricsRegistry := prometheus.NewRegistry() | ||
ksmMetricsRegistry.MustRegister(version.NewCollector("kube_state_metrics")) | ||
|
@@ -144,6 +145,22 @@ func RunKubeStateMetrics(ctx context.Context, opts *options.Options, factories . | |
} | ||
} | ||
|
||
// Loading custom resource state configuration from cli argument or config file | ||
config, err := resolveCustomResourceConfig(opts) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var factories []customresource.RegistryFactory | ||
|
||
if config != nil { | ||
factories, err = customresourcestate.FromConfig(config) | ||
if err != nil { | ||
return fmt.Errorf("Parsing from Custom Resource State Metrics file failed: %v", err) | ||
} | ||
} | ||
storeBuilder.WithCustomResourceStoreFactories(factories...) | ||
|
||
if opts.CustomResourceConfigFile != "" { | ||
crcFile, err := os.ReadFile(filepath.Clean(opts.CustomResourceConfigFile)) | ||
if err != nil { | ||
|
@@ -156,24 +173,22 @@ func RunKubeStateMetrics(ctx context.Context, opts *options.Options, factories . | |
|
||
} | ||
|
||
var resources []string | ||
resources := make([]string, len(factories)) | ||
|
||
for i, factory := range factories { | ||
resources[i] = factory.Name() | ||
} | ||
|
||
switch { | ||
case len(opts.Resources) == 0 && !opts.CustomResourcesOnly: | ||
resources = append(resources, options.DefaultResources.AsSlice()...) | ||
klog.InfoS("Used default resources") | ||
resources = options.DefaultResources.AsSlice() | ||
// enable custom resource | ||
for _, factory := range factories { | ||
resources = append(resources, factory.Name()) | ||
} | ||
case opts.CustomResourcesOnly: | ||
// enable custom resource only | ||
for _, factory := range factories { | ||
resources = append(resources, factory.Name()) | ||
} | ||
klog.InfoS("Used CRD resources only", "resources", resources) | ||
default: | ||
klog.InfoS("Used resources", "resources", opts.Resources.String()) | ||
resources = opts.Resources.AsSlice() | ||
resources = append(resources, opts.Resources.AsSlice()...) | ||
mrueg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
klog.InfoS("Used resources", "resources", resources) | ||
} | ||
|
||
if err := storeBuilder.WithEnabledResources(resources); err != nil { | ||
|
@@ -419,3 +434,17 @@ func md5HashAsMetricValue(data []byte) float64 { | |
copy(bytes, smallSum) | ||
return float64(binary.LittleEndian.Uint64(bytes)) | ||
} | ||
|
||
func resolveCustomResourceConfig(opts *options.Options) (customresourcestate.ConfigDecoder, error) { | ||
if s := opts.CustomResourceConfig; s != "" { | ||
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("Custom Resource State Metrics file could not be opened: %v", err) | ||
} | ||
return yaml.NewDecoder(f), nil | ||
} | ||
return nil, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we do not need the entire config to be unmarshaled, could we perhaps grab only the CustomResourceConfigFile value with something like:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this would require further logic (as it could also be set via command line), so merging seemed easier (to use the same logic that we have in
kube-state-metrics/pkg/app/server.go
Line 129 in b7a7070
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good 👍