kubert: Isolated Kubernetes Contexts
kubert gives you per-shell Kubernetes context isolation, protection, and multi-cluster execution.
If you work with multiple Kubernetes clusters, you likely know the pain. You switch contexts with kubectx, run a command in another terminal, and realize you just targeted the wrong cluster because KUBECONFIG is global. Or you find yourself manually setting environment variables to ensure each terminal targets the correct cluster.
This is why I built kubert. Check it out on GitHub: https://github.com/idebeijer/kubert.
Inspired by kubie (more on that later), kubert is an alternative to kubectx and kubens combined, but with a key difference: isolation.
How It Works
Instead of modifying your global kubeconfig file, kubert manages a separate, temporary kubeconfig for each shell session.
It uses the context name as a unique identifier (so duplicates are not allowed). When you select a context, kubert looks up the corresponding cluster and user from your source kubeconfig, even if that file contains dozens of other clusters. It then “cherry-picks” just that specific combination to craft a new, minimal kubeconfig file.
This new file is written to a temporary location, and kubert spawns a new subshell with the KUBECONFIG environment variable pointing exclusively to it.
This means you can have multiple terminals open, each pointing to a different cluster and namespace, without them ever interfering with each other. Values are set for that session only; when you exit, the temporary config is gone.
By default, kubertsearches for contexts in ~/.kube/config, ~/.kube/*.yml, and ~/.kube/*.yaml.
Key Features
Context Isolation
Switching contexts or namespaces only affects the current shell. This is the core value regarding safety and sanity. You can have one terminal in prod and another in staging, and they will never collide.
kubert ctx prod
kubert ns backend
Multi-Context Execution
I often check pods/nodes, run scripts or verify config across multiple clusters. kubert exec lets you fan out commands to multiple contexts using globs or regex patterns.
# Check nodes on all production clusters using glob
kubert exec "prod-*" -- kubectl get nodes
# Check pods in both dev and qa using regex
kubert exec --regex "^(dev|qa)-.*" -- kubectl get pods
Shell Hooks
A nice to have: Shell Hooks. You can run commands before and after the isolated shell is spawned.
This is perfect for setting your terminal tab title to the current context name, so you can easily distinguish between your prod and staging terminals at a glance.
hooks:
preShell: 'echo "\033]0;k8s: $KUBERT_CONTEXT\007"'
postShell: 'echo "\033]0;\007"'
Context Protection
To enable this, you must use the
kubert kubectlwrapper (perfect for an alias likek=kubert kubectl).
To help prevent accidents, kubert gives you the option to define “protected” contexts (like anything matching prod-*). When you try to run destructive commands (like delete or apply) in a protected context, kubert blocks them or demands explicit confirmation.
You can also manage protection on the fly:
kubert protection lift 5m # momentarily lift protection
kubert protection protect # lock down the current context
kubert protection unprotect # manually unprotect the current context
Other Features
For a complete reference of all commands, see the documentation.
Getting Started
Installation
You can install kubert via Homebrew or Go.
Homebrew
brew install idebeijer/tap/kubert --cask
If you have Homebrew Shell Completion configured,
kubertcompletions will be installed automatically.
Go
go install github.com/idebeijer/kubert@latest
Basic Usage
View available contexts (works best with fzf installed for interactive selection):
kubert ctx
Jump into a context:
kubert ctx my-cluster
Switch namespaces without leaving your isolated shell:
kubert ns kube-system
Configuration
kubert reads from ~/.config/kubert/config.yaml by default.
For discovery, you can point it to where your Kubeconfigs live using globs:
# ~/.config/kubert/config.yaml
kubeconfigs:
include:
# Add your custom paths here
- "~/.kube/clusters/*/kubeconfig"
- "~/projects/my-client/kubeconfig"
# Or include entire .kube directory
- "~/.kube/**"
protection:
regex: "(prd|prod)" # protect contexts matching this pattern
commands:
- delete
- apply
- scale
prompt: true # ask for confirmation (false = exit immediately)
hooks:
preShell: 'echo "\033]0;k8s: $KUBERT_CONTEXT\007"' # set tab title
Environment Variables
All configuration settings can be overridden using environment variables prefixed with KUBERT_.
protection.regex→KUBERT_PROTECTION_REGEXfzf.opts→KUBERT_FZF_OPTS
If you are looking for a tool to manage your contexts with isolation, check out kubert.
Honorable Mention: kubie
I have previously used and took inspiration from kubie (written in Rust) to solve this issue. It is a fantastic tool that I have used myself for quite some time, and can recommend.
So why did I build kubert?
- Fun: I simply wanted to write it myself in Go.
- Features: I had ideas for new capabilities that kubie didn’t have, like protected contexts and fetching kubeconfigs from a 1Password vault or keeping them encrypted at rest instead of plain text in
.kube. - Ecosystem: Go is generally the language of choice for cloud-native/Kubernetes, which lowers the barrier for others to contribute compared to Rust.