Kubernetes
Installs kubectl, kubeseal, k9s, and Helm (with the helm-diff plugin), and configures 25+ shell aliases and functions.
Demo

What it does
- Auto-installs and updates kubectl to the latest GitHub release
- Installs kubeseal (Bitnami Sealed Secrets CLI)
- Installs k9s (terminal UI for Kubernetes)
- Installs Helm and keeps the helm-diff plugin up to date
- Bash tab completion for kubectl
- Creates
~/.kube/configs/directory for per-cluster kubeconfigs - Optionally writes a kubeseal client config to
~/.config/kubeseal/kubeseal.yaml - Keeps cluster and namespace selection per-shell (
KUBECONFIG,KUBECTL_NAMESPACE,HELM_NAMESPACE) so terminals never collide, see Per-shell isolation - Shell aliases and functions for common Kubernetes operations
Variables
| Variable | Default | Description |
|---|---|---|
kubernetes_kubeseal_tmp_path | /tmp/kubeseal/ | Temporary directory for kubeseal download |
kubernetes_k9s_tmp_path | /tmp/k9s/ | Temporary directory for k9s download |
kubernetes_helm_tmp_path | /tmp/helm/ | Temporary directory for the Helm download |
kubernetes_helm_plugins | (empty) | Extra helm plugins to install, each a mapping with name, url, and optional version; installed when missing and updated on --upgrade |
kubernetes_kubeseal_config | {} | Merged into kubernetes_kubeseal_config_path (skipped when empty) |
kubernetes_kubeseal_config_path | ~/.config/kubeseal/kubeseal.yaml | Destination the kubeseal config is written to; write-through if it is a symlink |
Functions
| Function | Description |
|---|---|
kube-config | Show current cluster info or switch to a named kubeconfig from ~/.kube/configs/ |
kube-namespace | Set the active namespace (injected into all kubectl calls via the kubectl wrapper); validates the namespace exists on the cluster and errors with Namespace not found rather than exporting a name nothing matches |
kubectl | Wrapper that automatically injects --namespace when KUBECTL_NAMESPACE is set |
kube-configs | List available kubeconfigs in ~/.kube/configs/ |
kubectl is a wrapper that injects --namespace
When KUBECTL_NAMESPACE is set (via kube-namespace), the kubectl function appends --namespace to every call that doesn't already pass -n/--namespace, so commands target that namespace rather than the kubeconfig's default.
Per-shell isolation
Cluster and namespace selection lives in environment variables scoped to the current shell, never in the kubeconfig's stored current-context or namespace. kube-config sets KUBECONFIG to a per-cluster file under ~/.kube/configs/, and kube-namespace exports both KUBECTL_NAMESPACE (injected by the kubectl wrapper) and HELM_NAMESPACE (read natively by Helm).
Because nothing is written to a shared config file, every terminal holds its own cluster and namespace and kubectl, helm, and k9s in that shell all agree on it.
That is what lets you run several sessions at once, one terminal on staging payments, another on production default, a coding agent like Claude Code on a third cluster, with no kubectl config use-context race between them. The starship prompt reads the same KUBECONFIG and KUBECTL_NAMESPACE and shows the cluster and namespace (☸ <context> (<namespace>)), so each shell visibly shows the cluster it is on. This is the per-shell context isolation concept applied to Kubernetes.
# terminal 1
$ kube-config staging && kube-namespace payments
$ pods # staging / payments
$ helm list # staging / payments, same shell, no -n needed
# terminal 2, simultaneously and unaffected
$ kube-config production && kube-namespace default
$ pods # production / defaultAliases
| Alias | Command | Description |
|---|---|---|
| Kubeconfig | ||
kubeconfig | kube-config | Switch to a named kubeconfig |
kubernetes | kube-config | Alias for kube-config |
kube-contexts | kubectl config get-contexts | List contexts |
kube-clusters | kubectl config get-clusters | List clusters |
| Namespaces | ||
namespace | kube-namespace | Bare: list namespaces; namespace <name>: switch the active namespace (name completion) |
kube-namespaces | kubectl get namespaces | List namespaces |
| Nodes | ||
nodes | kubectl get nodes | List nodes |
kube-nodes | kubectl get nodes | List nodes |
nodesw | nodes --watch | Watch nodes |
nodestopcpu | kubectl top node --sort-by='cpu' | Top nodes by CPU |
nodestopmemory | kubectl top node --sort-by='memory' | Top nodes by memory |
| Pods | ||
pods | kubectl get pods | List pods |
podsw | pods --watch | Watch pods |
podsclean | Delete all failed pods across namespaces | Remove failed pods |
podstopcpu | kubectl top pod --sort-by='cpu' | Top pods by CPU |
podstopmemory | kubectl top pod --sort-by='memory' | Top pods by memory |
| Resources | ||
deployments | kubectl get deployments | List deployments |
services | kubectl get services | List services |
secrets | kubectl get secrets | List secrets |
configs | kubectl get configmaps | List ConfigMaps |
ingresses | kubectl get ingresses | List ingresses |
| Events & Logs | ||
events | kubectl get events --sort-by='.lastTimestamp' | List events by time |
eventsw | events --watch | Watch events |
logs | kubectl logs | Tail pod logs |
logsf | logs --follow | Follow pod logs |
| Shorthand | ||
kube | kubectl | Kubectl alias |
Helm plugins are managed for you
Helm and the helm-diff plugin are installed and updated automatically by this role. No manual helm plugin install step is needed. Add your own to kubernetes_helm_plugins:
kubernetes_helm_plugins:
- name: secrets
url: https://github.com/jkroepke/helm-secrets
- name: s3
url: https://github.com/hypnoglow/helm-s3.git
version: v0.16.0Troubleshooting
A command targeted an unexpected namespace
The kubectl function injects --namespace whenever KUBECTL_NAMESPACE is set (via kube-namespace), so a stale value sends commands to the wrong namespace. Check the current value with echo $KUBECTL_NAMESPACE and clear it with unset KUBECTL_NAMESPACE, or call the binary directly with command kubectl … to bypass the wrapper for a single call.