kubernetes / kubectl

Issue tracker and mirror of kubectl code
Apache License 2.0
2.88k stars 922 forks source link

Support for setting resourceVersion in kubectl get #965

Open lbernail opened 4 years ago

lbernail commented 4 years ago

What would you like to be added:

Support for --resource-version=X for kubectl get (or maybe or simpler flag to just force a read from cache by setting RV=0, such as --cache ?)

Why is this needed: Today, kubectl get only supporting LISTing with RV="" which on large clusters can be slow for users and impact the control plane and etcd in particular.

I did a few tests on large cluster with curl and the difference can be very significant:

time curl  -H "Accept: application/json;as=Table;v=v1beta1;g=meta.k8s.io, application/json" -H "Authorization: Bearer X" 'https://cluster.dog/api/v1/pods?labelSelector=app=A'
real    0m3.658s

time curl -H "Accept: application/json;as=Table;v=v1beta1;g=meta.k8s.io, application/json" -H "Authorization: Bearer X" 'https://cluster.dog/api/v1/pods?labelSelector=app=A&resourceVersion=0'
real    0m0.079s

Of course this is an extreme example:

I'd be more than happy to provide a PR but I'm not familiar with the codebase so any (even small) guidance would be appreciated. Here is what I think so far but it's very likely I am missing/misunderstanding more than a few things:

cc @wojtek-t because we discussed this on slack earlier this week

k8s-triage-robot commented 1 year ago

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:

You can:

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle rotten

k8s-triage-robot commented 1 year ago

The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.

This bot triages issues according to the following rules:

You can:

Please send feedback to sig-contributor-experience at kubernetes/community.

/close not-planned

k8s-ci-robot commented 1 year ago

@k8s-triage-robot: Closing this issue, marking it as "Not Planned".

In response to [this](https://github.com/kubernetes/kubectl/issues/965#issuecomment-1398674606): >The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs. > >This bot triages issues according to the following rules: >- After 90d of inactivity, `lifecycle/stale` is applied >- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied >- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed > >You can: >- Reopen this issue with `/reopen` >- Mark this issue as fresh with `/remove-lifecycle rotten` >- Offer to help out with [Issue Triage][1] > >Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community). > >/close not-planned > >[1]: https://www.kubernetes.dev/docs/guide/issue-triage/ Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md). If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
llhuii commented 1 year ago

/reopen

k8s-ci-robot commented 1 year ago

@llhuii: You can't reopen an issue/PR unless you authored it or you are a collaborator.

In response to [this](https://github.com/kubernetes/kubectl/issues/965#issuecomment-1451234702): >/reopen Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md). If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
llhuii commented 1 year ago

Helpful for large cluster.

Optional:

timeout 1 kubectl get mycrd -v=6
I0302 11:24:32.115470  121694 loader.go:372] Config loaded from file:  /root/.kube/config
I0302 11:24:32.661483  121694 round_trippers.go:454] GET https://10.10.10.10:6443/apis/demo.sample.com/v1alpha1/namespaces/default/mycrds?limit=500 200 OK in 422 milliseconds

kubectl  get --raw /apis/demo.sample.com/v1alpha1/namespaces/default/mycrds?resourceVersion=0
logicalhan commented 1 year ago

/reopen /remove-lifecycle rotten

k8s-ci-robot commented 1 year ago

@logicalhan: Reopened this issue.

In response to [this](https://github.com/kubernetes/kubectl/issues/965#issuecomment-1556226937): >/reopen >/remove-lifecycle rotten Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md). If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
aofekiko commented 1 year ago

I have a rudimentary implementation of the feature in kubectl.

Note that since kubectl applies a default limit=500 on every request, the default list behavior is "Exact".
using the --resource-version flag with the --chunk-size flag set to zero means that the behavior will be "Not older than" which means that the most recent resource versions will not be available.

Along the way I have encountered some problems.

For the feature to be able to get a specific RV of a specific resource, extended functionality for resourceVersion needs to be implemented when making a request for a single resources in the API server.

According to the get resourceVersion table setting a resourceVersion value other than 0 will result in "Not older than".
I believe that the functionality of resourceVersion=0 would fit most use-cases since both will provide the latest resource available in the cache, the only added functionality resourceVersion!=0 does is a validation step that could be done on the client side.

If we believe that the resourceVersion!=0 functionality has overlap with resourceVersion=0 and therefore not needed, I propose to change the functionality of resourceVersion!=0 to provide the oldest resourceVersion that is smaller than the specified resourceVersion as this is the same functionality as in etcd.

For example:

Say we have a resource at version 100.
We then edit it and it becomes version 200.
If we were to `get` the resource at resourceVersion 150, we'd get the resource at version 100.

If we believe that the resourceVersion!=0 functionality is still needed and to not break applications that rely on said functionality, I propose implementing a mechanism similar to list's resourceVersionMatch where an additional "NotYoungerThan" value will be added to have the same functionality as mentioned above.

lauchokyip commented 1 year ago

/assign @aofekiko

aofekiko commented 1 year ago

Thank you for entrusting me with this issue, but before I can complete the PR I'd like some guidance over how to approach the question of being able to get a specific RV of a specific resource. (kubectl get pod mypod --resource-version=10)

It should be exposed to kubectl get in general. It basically enables stale reads at exact timestamps, we'd likely want this for both list and individual object get operations.

Right now it is not possible due to how the API implements resourceVersion="{value other than 0}" as not older than.

/assign