NexusCS

kubens

Kubernetes
Fast Kubernetes namespace switching tool. Switch namespaces with interactive fuzzy search, previous namespace toggle, and force-set for non-existent namespaces.
kubernetes
kubectl
namespace
cli

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 kubens without 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 list permission 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 ns doesn't include shell completions
  • Install via Homebrew/apt for automatic completion setup
  • Or manually source completion files

Force Flag Doesn't Create Namespace

  • --force only 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 --force if 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