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

kubens is very slow with large list of namespace #313

Open
nhat opened this issue Aug 11, 2021 · 4 comments
Open

kubens is very slow with large list of namespace #313

nhat opened this issue Aug 11, 2021 · 4 comments

Comments

@nhat
Copy link

nhat commented Aug 11, 2021

In my company we have about 22k namespaces. Switching ns with kubens is painfully slow and can take up to 10-15sec.

Do you have any plans to cache the ns list or are there any workarounds I can use for now?

@ahmetb
Copy link
Owner

ahmetb commented Aug 12, 2021

That's definitely an outlier case. :) As a result I can't promise any fixes.

First and foremost, the bash based implementation likely can't fix this, so we might try to improve this in the Go implementation.

Next, caching would only work if the Kubernetes API provides an Etag like header and supports passing the value back to the next "list namespaces request" in the If-None-Match header. (Otherwise, if we implement our own cache, we'd be showing you a potentially outdated result, which would make other users unhappy.)

I need someone to research if Kubernetes API supports cache control via Etag and If-None-Match. My current suspicion is that it doesn't. Then, we need to figure out a way to use this in the client-go (I don't think the Go K8s API client supports this either). If client-go doesn't have a way of configuring so that it understand these headers, then the only way is to make HTTP requests to Kubernetes API manually (it might be doable, but would be a maintenance cost to "do it right", which is what client-go does for us) which I very much like to stay away from.

@Nitive
Copy link

Nitive commented Aug 14, 2021

Kubernetes API Server doesn't support cache control via Etag and If-None-Match (expect for OpenAPI schemas). Caching is disabled on purpose for security reasons — generaly we don't want to cache authz/authn protected content or proxy servers and end users machines.

However, it doesn't mean we can't make our own cache implementation and I think we should. I suggest to use “stale while revalidate” approach: show user results from cache and fetch updated results for namespaces.

By the way, we have maximum of 120 namespaces in cluster but my internet connection is not very good (good enough for video call through) so kubens takes about 900ms to execute which is not critical but frustrating.

I'm ready to create a PR with caching if you like my “stale while revalidate” idea

@Nitive
Copy link

Nitive commented Aug 14, 2021

@nhat

Workaround: use this two bash functions: kns to choose namespace from cache and kns-update-cache to manually update cache

function kns() {
  cat "$HOME/.local/share/kubectx-cache/$(kubectx -c)" | fzf | xargs kubens
}

function kns-update-cache() {
  mkdir -p "$HOME/.local/share/kubectx-cache"
  kubectl get ns -o json | jq -r .items[].metadata.name > "$HOME/.local/share/kubectx-cache/$(kubectx -c)"
}

@nhat
Copy link
Author

nhat commented Aug 14, 2021

That's a good workaround, thanks @Nitive. I also like your caching idea!

I have been using the small function below so far, because kubens <namespace> is also very slow with a huge number of namespaces. I might just combine this into your workaround.

function kns() {
  kubectl get namespace $1 && kubectl config set-context --current --namespace=$1
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants