kubectx icon indicating copy to clipboard operation
kubectx copied to clipboard

kubens is very slow with large list of namespace

Open nhat opened this issue 4 years ago • 5 comments
trafficstars

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?

nhat avatar Aug 11 '21 20:08 nhat

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.

ahmetb avatar Aug 12 '21 17:08 ahmetb

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 avatar Aug 14 '21 10:08 Nitive

@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)"
}

Nitive avatar Aug 14 '21 10:08 Nitive

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
}

nhat avatar Aug 14 '21 17:08 nhat