Getting started
Introduction
kubens is a Kubernetes namespace switching tool that provides a faster alternative to kubectl config set-context --current --namespace. Part of the kubectx repository by Ahmet Alp Balkan.
Installation
Homebrew (macOS/Linux)
brew install kubectx
# Includes both kubectx and kubens
Krew (kubectl plugin)
kubectl krew install ns
# Available as: kubectl ns
Linux Package Managers
# Debian/Ubuntu
sudo apt install kubectx
# Arch Linux
sudo pacman -S kubectx
# MacPorts (macOS)
sudo port install kubectx
Windows
# Chocolatey
choco install kubens
# Scoop
scoop install main/kubens
# winget
winget install --id ahmetb.kubens
Quick Example
# List all namespaces
kubens
# Switch to namespace
kubens kube-system
# Switch back to previous
kubens -
# Show current namespace
kubens --current
Core Commands
List Namespaces
kubens
# List all namespaces in current context
Opens interactive fuzzy-search menu if fzf is installed, otherwise prints list.
Switch Namespace
kubens <NAME>
# Switch to namespace
Example:
kubens kube-system
# Context "test" set.
# Active namespace is "kube-system".
Switch to Previous
kubens -
# Switch back to previous namespace
Similar to cd - in shell.
Show Current Namespace
kubens --current
kubens -c
# Show current namespace
Force Set Namespace
kubens <NAME> --force
kubens <NAME> -f
# Set namespace even if it doesn't exist
Example:
kubens not-found-namespace --force
# Context "test" set.
# Active namespace is "not-found-namespace".
Use case: Set namespace before creating it
Interactive Mode
With fzf
Requires fzf installed in PATH.
Behavior:
- Running
kubenswithout arguments opens fuzzy-searchable menu - Type to filter namespaces
- Use arrow keys to navigate
- Press Enter to select
Install fzf
# macOS
brew install fzf
# Debian/Ubuntu
sudo apt install fzf
# Arch Linux
sudo pacman -S fzf
Opt-out of Interactive Mode
export KUBECTX_IGNORE_FZF=1
# Disable fzf integration
Or force non-interactive:
kubens | cat
# Pipe to disable fzf
Comparison with kubectl
| Task | kubectl | kubens |
|---|---|---|
| List namespaces | kubectl get namespaces |
kubens |
| Switch namespace | kubectl config set-context --current --namespace=NAME |
kubens NAME |
| Current namespace | kubectl config view --minify | grep namespace |
kubens --current |
| Previous namespace | (not available) | kubens - |
| Set non-existent ns | kubectl config set-context --current --namespace=NAME |
kubens NAME --force |
| Interactive select | (not available) | kubens (with fzf) |
Shell Completion
bash
# Via bash-completion (Homebrew automatic)
# Manual setup:
source /path/to/kubectx/completion/kubens.bash
Add to ~/.bashrc:
if [ -f /path/to/kubectx/completion/kubens.bash ]; then
source /path/to/kubectx/completion/kubens.bash
fi
zsh
# oh-my-zsh: Automatic with Homebrew
# Manual setup:
fpath=(/path/to/kubectx/completion $fpath)
autoload -U compinit && compinit
Add to ~/.zshrc:
fpath=(~/.kubectx/completion $fpath)
fish
cp /path/to/kubectx/completion/kubens.fish ~/.config/fish/completions/
Note: Krew installation does NOT include shell completions. Install via Homebrew/apt for automatic setup.
kubectl Plugin Integration
Via Krew
kubectl ns
# Available as kubectl plugin
kubectl ns kube-system
# Switch namespace
kubectl ns --current
# Show current namespace
Via Homebrew/apt
kubens
# Standalone command
kubens kube-system
# Switch namespace
Both methods modify the same kubeconfig.
Use Cases
Switch Between Namespaces
# Development namespace
kubens dev
# Staging namespace
kubens staging
# Production namespace
kubens production
# Back to previous
kubens -
Set Namespace Before Creation
# Set namespace (doesn't exist yet)
kubens my-new-namespace --force
# Create namespace
kubectl create namespace my-new-namespace
# Now use it
kubectl get pods
Quick Namespace Check
# Show current namespace
kubens --current
# Or with kubectl
kubectl config view --minify | grep namespace
Work Across Namespaces
# List resources in different namespaces
kubens kube-system
kubectl get pods
kubens default
kubectl get pods
kubens - # Back to kube-system
Combine with kubectx
# Switch context and namespace together
kubectx prod-cluster
kubens production
# Or use kubectl plugin style
kubectl ctx prod-cluster
kubectl ns production
Shell Prompt Integration
Using kube-ps1
Install:
brew install kube-ps1
Configure (~/.bashrc or ~/.zshrc):
source "/usr/local/opt/kube-ps1/share/kube-ps1.sh"
PS1='$(kube_ps1)'$PS1
Result: Prompt shows current context and namespace
(minikube:kube-system) user@host:~$
Updates automatically after kubens commands.
Custom Prompt
bash:
get_k8s_ns() {
kubectl config view --minify --output 'jsonpath={..namespace}' 2>/dev/null || echo "default"
}
PS1='[\u@\h \W $(get_k8s_ns)]\$ '
zsh:
get_k8s_ns() {
kubectl config view --minify --output 'jsonpath={..namespace}' 2>/dev/null || echo "default"
}
PROMPT='%n@%m %1~ $(get_k8s_ns) %# '
Behavior Notes
Context Modification
- kubens modifies the active context's namespace setting
- Changes persist in kubeconfig file
- Affects all terminals using the same kubeconfig
RBAC Awareness
- Lists only namespaces the user has access to
- Requires
listpermission on namespaces resource - If no permissions, kubens will fail with error
Default Namespace
- If context has no namespace set, defaults to "default"
- This is standard kubectl behavior
Global Switching
Warning: Switching in one terminal updates config for all terminals using the same kubeconfig.
Troubleshooting
Namespace Not Found
Error: Namespace doesn't appear in list
Diagnosis:
# Verify namespace exists
kubectl get namespaces
# Check RBAC permissions
kubectl auth can-i list namespaces
# Try to access namespace
kubectl get pods -n NAMESPACE_NAME
Solution:
- If namespace exists but not visible: Request RBAC permissions
- If namespace doesn't exist: Create it first or use
--force - If need to set before creation: Use
kubens NAMESPACE --force
Permission Denied Listing Namespaces
Error: Cannot list namespaces
Cause: User lacks RBAC permission to list namespaces at cluster level
Check permissions:
kubectl auth can-i list namespaces
Example ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-reader
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
Workaround: If you know namespace name:
kubens NAMESPACE --force
Context Without Namespace
Issue: Context has no namespace configured
Check:
kubectl config view --minify | grep namespace
Set namespace:
kubens my-namespace
Defaults to "default" if none exists.
fzf Not Found
Error: Interactive mode doesn't work
Check if fzf is installed:
which fzf
Solution: Install fzf or set KUBECTX_IGNORE_FZF=1
brew install fzf # macOS
sudo apt install fzf # Debian/Ubuntu
Shell Completion Not Working
Cause: Installed via Krew (doesn't include completions)
Solution: Install via Homebrew or manually source completion files
# Homebrew
brew install kubectx
# Manual (bash)
source /opt/kubectx/completion/kubens.bash
Best Practices
Verify Namespace Before Operations
# Always check current namespace before destructive operations
kubens --current
# Or use shell prompt (kube-ps1) for constant visibility
Warning: Always verify namespace before running destructive operations like kubectl delete.
Use Short Namespace Names
# Good: dev, staging, prod, monitoring, logging
kubens dev
# Avoid: very-long-namespace-name-that-is-hard-to-type
Combine with kubectx
# Create workflow scripts
#!/bin/bash
# switch-to-prod.sh
kubectx prod-cluster
kubens production
echo "Now operating in production!"
Default to Safe Namespaces
# After working in production, switch back to dev
kubens dev
# Or use a safe "default" namespace
kubens sandbox
Use Aliases for Speed
alias kns='kubens'
alias kctx='kubectx'
alias k='kubectl'
Add to ~/.bashrc or ~/.zshrc.
Quirks & Gotchas
Previous Namespace Only Remembers One
kubens -only remembers the last namespace- Cannot go back multiple steps
- Use
kubens(list) to see all available namespaces
Namespace Switching is Global
- Affects all terminals using the same kubeconfig
- Switching in one terminal updates config for all
- Be careful when working with multiple namespaces simultaneously
Krew Installation Lacks Completions
kubectl krew install nsdoesn't include shell completions- Install via Homebrew/apt for automatic completion setup
- Or manually source completion files
Force Flag Doesn't Create Namespace
--forceonly sets the namespace in kubeconfig- Does NOT create the namespace in Kubernetes
- You must still run
kubectl create namespace NAME
RBAC Can Hide Namespaces
- If you lack permissions, namespaces won't appear in list
- You can still switch to them with
kubens NAME --forceif you know the name - Useful in restricted RBAC environments
Default Namespace Behavior
- If no namespace set in context, kubectl defaults to "default"
- kubens shows "default" as current namespace
- This is kubectl behavior, not a kubens quirk
Useful Workflows
Fresh System Setup
# Install kubectx (includes kubens)
brew install kubectx
# Install fzf for interactive mode
brew install fzf
# Install kube-ps1 for prompt integration
brew install kube-ps1
# Configure shell prompt
echo 'source "/usr/local/opt/kube-ps1/share/kube-ps1.sh"' >> ~/.zshrc
echo 'PS1='"'"'$(kube_ps1)'"'"'$PS1' >> ~/.zshrc
# Add aliases
echo "alias kns='kubens'" >> ~/.zshrc
echo "alias kctx='kubectx'" >> ~/.zshrc
source ~/.zshrc
Multi-Environment Workflow
#!/bin/bash
# Deploy to all environments
# Dev
kubectx dev-cluster
kubens dev
kubectl apply -f deployment.yaml
# Staging
kubectx staging-cluster
kubens staging
kubectl apply -f deployment.yaml
# Production (with confirmation)
kubectx prod-cluster
kubens production
read -p "Deploy to PRODUCTION? (yes/no) " confirm
[[ "$confirm" == "yes" ]] && kubectl apply -f deployment.yaml
Namespace Audit
# List all namespaces
kubens
# Check resources in each namespace
for ns in $(kubens | grep -v "^$"); do
echo "=== Namespace: $ns ==="
kubectl get pods -n $ns
done
Safe Context/Namespace Switcher
#!/bin/bash
# switch-env.sh - Safe environment switcher
ENV=$1
if [ -z "$ENV" ]; then
echo "Usage: switch-env.sh [dev|staging|prod]"
exit 1
fi
case $ENV in
dev)
kubectx dev-cluster
kubens development
;;
staging)
kubectx staging-cluster
kubens staging
;;
prod)
kubectx prod-cluster
kubens production
echo "⚠️ WARNING: You are now in PRODUCTION"
;;
*)
echo "Unknown environment: $ENV"
exit 1
;;
esac
echo "Current context: $(kubectx --current)"
echo "Current namespace: $(kubens --current)"
Common Aliases
# Add to ~/.bashrc or ~/.zshrc
alias kns='kubens'
alias kctx='kubectx'
alias k='kubectl'
# Quick namespace switcher
alias kns-dev='kubens development'
alias kns-stg='kubens staging'
alias kns-prod='kubens production'
# Show current context and namespace
alias kns-current='echo "Context: $(kubectx --current), Namespace: $(kubens --current)"'
Also see
- kubectx GitHub Repository - Official repository (includes kubens)
- kube-ps1 GitHub Repository - Shell prompt integration
- kubectl cheatsheet - kubectl command reference
- kubectx cheatsheet - Context switching companion tool
- fzf GitHub Repository - Fuzzy finder for interactive mode