kubectx
kubectx copied to clipboard
Proposal: write kubectx/kubens in Go
Most people don't realize kubectx and kubens are small bash scripts today.
Bash works fine and has brought us this far. Since we mostly shell out to kubectl for config processing and the project is minimalist enough, this has been working well.
Problems with using bash
However, for long-term maintenance, using bash scripting will be a problem:
-
Bash is not cross-platform, hence divides the community: Many users quote they can't use kubectx on windows. So some of them have gone on and wrote their "clones" of kubectx that work on Windows.
Some examples of fragmentation from the ecosystem:
- Kubectxwin: https://github.com/thomasliddledba/kubectxwin
- kubectx-rs (Rust): https://github.com/FGRibreau/kubectx-rs
- kubectl-ctx (Go, a kubectl plugin): https://github.com/postfinance/kubectl-ctx
- kubectx (poorly named, Node.js) https://github.com/FGRibreau/kubectx, another one in nodejs: https://github.com/WoLfulus/kubee
- someone emailed me yesterday asking if they can use "kubectx" name and publish a Go implementation
- Issue to support windows: #29
- kx (Go, related): https://github.com/kylie-a/kx
This is pointing to clear community interest for a kubectx that works on windows, despite bash-on-Windows and Windows Subsystem for Linux (WSL) are now widely available.
-
People don't want contribute to bash scripts: I like bash alright, most people don't want to code in bash. This is probably dramatically reducing the contributor and maintainer prospects pool drastically.
-
Hard to reason about code: Some parts of the kubectx code are about to get out of control, such as the flags parsing/handling.
Problems with switching to Go
-
Rewrite: We need to rewrite. Arguably the code would be longer, but more maintainable. We already have some integration/CLI tests effort happening in #2, which should help test post-rewrite.
-
Larger binary size: We're going from 5kb to ~5-10 mb in exchange for platform portability.
-
More difficult to support POSIX platforms: If you had bash, kubectx would work fine today. But if we rewrite in Go, supporting architectures like ppc or arm (<1% users) , would require making separate Go binary releases. Bash doesn't have this problem.
I'm 51% inclined to rewrite in Go (and release v1.0). I appreciate kubectx user community can chime in with their thoughts on this. ❤️
@ahmetb - I would definitely love to help on the go implementation.
Let me know if any help is needed.
I take it there's already an issue to add this functionality to kubectl (which seems the logical place for it), and that proposal has been rejected for some fairly sound reasons. Do you happen to know what they are?
@bitfield the question is a bit off-topic and basically asks "why is there even a kubectx" but here's the answer: https://github.com/kubernetes/kubernetes/issues/27308
I would most definitely like to see this in go, also maybe with some caching of objects when you switch context or namespace...
I would like to see this in kubectl if it was possible. The bash script is also ideal for quick access and runs on all platforms (arm included)
@bitfield the question is a bit off-topic and basically asks "why is there even a kubectx" but here's the answer: kubernetes/kubernetes#27308
Well, it's not quite so much 'why is there even a kubectx', but 'why was this functionality (which seems so obviously necessary and continually useful) not accepted into kubectl itself'? There are some hints about that on the linked issue, but nothing that seems conclusive to me (and, indeed, the issue remains open).
That being so, should the Go rewrite of kubectx/kubens (which I agree is an excellent idea) be a PR against Kubernetes instead of a standalone project? If not, why not? It seems like it would be a very good thing to make this functionality part of the core Kubernetes CLI tool. (If only because lots of Kubernetes users don't know about it, and are always delighted when I introduce them to it!)
@bitfield current stance of Kubernetes project towards adding new features is to do it through extension mechanisms like CRDs, custom controllers and plugins. How this applies to kubectl is through kubectl plugins.
Towards that goal, we developed krew, a package manager for kubectl plugins and there's talks/proposals to donate krew to kubectl to make it the official package manager.
Moving kubectx/kubens to Go would further make it easier to distribute on krew (since it would cut dependency to bash) and allow support for more platforms.
@ahmetb building separate binaries for different platforms may not be much of an issue, go cross-compiling seems pretty good. I really like being able to list and download single binaries from a project's releases page (example). You can have something like Travis or GitHub Actions build and publish the binaries when a new version is tagged.
You could also do completion using cobra (I see the library is used in krew), which I think can target zsh too. I imagine moving to go would increase the accessibility (overall?).
Moving kubectx/kubens to Go would further make it easier to distribute on krew (since it would cut dependency to bash) and allow support for more platforms.
Sounds great to me! I'm happy to help with this wherever I can; I've some experience writing Cobra apps.
@alexellis
I would like to see this in kubectl if it was possible
See the kubernetes/kubernetes issue link above for discussion.
I think going forward these community asks will be implemented as extensions/plugins instead of proposing features to the core. Coincidentally, I also happen to be the maintainer of a "kubectl plugin manager" (?) so we may start distributing it as a plugin after porting to Go.
Like it very much, also in combination with kubectl plugin (while it is not were it should be, its probably the way to go forward).
I can support as well.
Any plans for a hackathon weekend or something? :-)
I'm also interested in helping @ahmetb
- More difficult to support POSIX platforms: If you had bash, kubectx would work fine today. But if we rewrite in Go, supporting architectures like ppc or arm (<1% users) , would require making separate Go binary releases. Bash doesn't have this problem.
releases can be automated with https://goreleaser.com :)
@caarlos0 everyone loves goreleaser!
Out of curiosity: Have any decisions been made? I'd like a platform-independent go version ;) And would also collaborate on reaching this goal. The origin was, because I had one or two feature ideas and didn't even know this was just a bash script until I looked into the code. That makes it kind of.. ugly (although I understand, that it did perfectly fit for a head start).
Update: I have thought about it quite a bit and decided to keep this program in bash for now.
- It appears like increasing number of windows users are switching to WSL.
- For those who don't: According to my last count, there are about 35 kubectx clones out there written in node, rust, python etc. One should suit you.
- The performance issues of going through kubectl (as opposed to editing kubeconfig directly) aren't as notable (and are future-proof/safe)
- For example go-kubectx analyzes that kubectx has <100ms and kubens has <300ms latency (mainly because we do an API call during that) which is still acceptable.
- The codebase is very welcoming and easy for contributions this way, since both kubens and kubectx are easy to understand programs.
I intend to keep it in bash for the time being. That said, I see (currently) 47👍 votes on this issue. I hear you and I think this is something that's worth doing as part of 1.0 –but until then it seems like we have a pretty happy user-base and maintenance on this.
OK, I was kidding. I have good news for you all: I finally found some time during COVID-19 and have rewritten kubectx and kubens in Go.
- it supports Windows
- it’s 8-15x faster switching clusters
- preserves your kubeconfig YAML format
Please spread the news here: https://twitter.com/ahmetb/status/1255606209479995392 Please download the new binaries and give feedback: https://github.com/ahmetb/kubectx/releases/tag/v0.9.0
Yay! Thank you so much for that and your hard work ♥️
Why did you decide to implement in Go using yaml nodes instead of the existing tools in k8s.io/client-go? i.e https://github.com/postfinance/kubectl-ctx/blob/master/cmd/ctx.go
@ReallyLiri the main reason was to protect comments and field order of the file which kubectl doesn't.