Skip to content
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

feat: Use PartialObjectMetadata for Configmaps #2468

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mrueg
Copy link
Member

@mrueg mrueg commented Aug 6, 2024

What this PR does / why we need it:
This PR introduces a metadataonly client, which can be used to fetch sparse data for large objects like configmaps.

How does this change affect the cardinality of KSM: (increases, decreases or does not change cardinality)
None

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #2463

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Aug 6, 2024
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mrueg

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Aug 6, 2024
@mrueg mrueg force-pushed the metadataonlyclient branch 2 times, most recently from 1231b8b to 4d9ee4b Compare August 6, 2024 20:25
@mrueg mrueg changed the title WIP: feat: Use PartialObjectMetadata for Configmaps and Secrets WIP: feat: Use PartialObjectMetadata for Configmaps Aug 6, 2024
@mrueg
Copy link
Member Author

mrueg commented Aug 6, 2024

We can't use partialobjectmetadata for secrets unfortunately, since we have metrics for the secrets type that we expose.

@mrueg mrueg force-pushed the metadataonlyclient branch 2 times, most recently from d479370 to cd9a7c2 Compare August 7, 2024 13:33
@mrueg mrueg changed the title WIP: feat: Use PartialObjectMetadata for Configmaps feat: Use PartialObjectMetadata for Configmaps Aug 7, 2024
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 7, 2024
@mrueg mrueg force-pushed the metadataonlyclient branch 3 times, most recently from 151ede1 to a08c6b8 Compare August 7, 2024 14:05
@sftim
Copy link

sftim commented Aug 7, 2024

We can't use partialobjectmetadata for secrets unfortunately, since we have metrics for the secrets type that we expose.

Secret supports type as a field selector.

I wonder if we could make a sort of informer that does a metadata-only watch per known Secret type, plus one that watches for unknown types and doesn't use partial object metadata. Should be quite a bit more efficient overall, at the cost of turning one watch into n.

@dgrisonnet
Copy link
Member

/assign
/assign @richabanker
/triage accepted

@k8s-ci-robot k8s-ci-robot added triage/accepted Indicates an issue or PR is ready to be actively worked on. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Aug 8, 2024
@mrueg
Copy link
Member Author

mrueg commented Aug 8, 2024

I still lack seeing the hoped memory improvements with this PR.
My test looks like the following (creates 100x 1MB sized configmaps):

for i in $(seq 1 100); do
        base64 /dev/urandom | head -c 1000000 > file.txt
        kubectl create configmap morecm$i --from-file="file.txt"
done

Copy link
Member

@dgrisonnet dgrisonnet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few comments, but I am a fan of this change! :)

internal/store/builder.go Outdated Show resolved Hide resolved
@@ -541,6 +561,46 @@ func (b *Builder) buildStores(
return stores
}

func (b *Builder) buildMetadataOnlyStores(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something, but it seems you could call buildStores right away since this is an exact copy of its code.

Going even further, maybe we don't even need buildMetadataOnlyStores and could just call buildStores directly when building resource specific stores like:

-	return b.buildStoresFunc(configMapMetricFamilies(b.allowAnnotationsList["configmaps"], b.allowLabelsList["configmaps"]), &v1.ConfigMap{}, createConfigMapListWatch, b.useAPIServerCache)
+	return b.buildStoresFunc(configMapMetricFamilies(b.allowAnnotationsList["configmaps"], b.allowLabelsList["configmaps"]), &metav1.PartialObjectMetadata{}, createConfigMapListWatch, b.useAPIServerCache)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I created that is the different signature of the listWatchFunc (using metadata.Interface not clientset.Interface). Is there's a different way to do that, I'm all ears :)

}
}
config.UserAgent = fmt.Sprintf("%s/%s (%s/%s) kubernetes/%s", "kube-state-metrics (metadataonly)", version.Version, runtime.GOOS, runtime.GOARCH, version.Revision)
config.AcceptContentTypes = "application/vnd.kubernetes.protobuf;as=PartialObjectMetadataList;g=meta.k8s.io;v=v1,application/json;as=PartialObjectMetadataList;g=meta.k8s.io;v=v1,application/json,application/vnd.kubernetes.protobuf;as=PartialObjectMetadata;g=meta.k8s.io;v=v1,application/json;as=PartialObjectMetadata;g=meta.k8s.io;v=v1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to do that ourselves? The client seems to already set the Accept header accordingly: https://github.com/kubernetes/kubernetes/blob/0b3b733c8437a946b7300a346ac948fec2e0b3ff/staging/src/k8s.io/client-go/metadata/metadata.go#L222

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was mainly copying from the CreateKubeClient() func, I'm not sure if we need it here additionally.

Will metadata.List()/Watch() be called eventually or is that overwritten by ListWatchFunc?

@mrueg
Copy link
Member Author

mrueg commented Aug 16, 2024

Few comments, but I am a fan of this change! :)

Great to hear! I'm still looking for better ideas to verify that it saves network traffic and reduces memory consumption on ksm.

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 25, 2024
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use PartialObjectMetadata for ConfigMaps and Secrets
5 participants