Skip to content

hemzaz/kubetab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kubetab

Per-terminal-tab kubeconfig isolation for interactive Kubernetes work.

Overview

kubetab provides isolated kubeconfig files for each terminal tab, automatically synced from a single base kubeconfig (~/.kube/config). Each tab can switch contexts and namespaces independently without affecting other tabs.

Key Features:

  • 🔒 Per-tab isolation - Each terminal tab gets its own private kubeconfig
  • 🔄 Auto-sync - Changes to base kubeconfig automatically propagate to all tabs
  • 💾 Preserve local state - Tab-specific namespace and context selections persist across syncs
  • 🎯 Zero shell complexity - Single line in .zshrc, no background jobs or shell scripts
  • 🚀 Fast and reliable - Built in Go with fsnotify + polling fallback
  • 🍎 macOS native - Designed for iTerm2 + zsh (works on other terminals too)

Installation

Prerequisites

  • Go 1.21 or later
  • macOS (primary target), Linux compatible

Build and Install

git clone https://github.com/eladnoor/kubetab.git
cd kubetab
make install

This installs kubetab to ~/.local/bin/kubetab. Ensure ~/.local/bin is in your PATH.

Quick Start

Add this single line to your ~/.zshrc:

[[ -o interactive && -n "$ITERM_SESSION_ID" ]] && eval "$(kubetab init --shell zsh --preserve ns)"

Optional but recommended - add an alias for kubecm:

alias kc='kubecm --config "$KUBECONFIG"'

Restart your shell or run source ~/.zshrc.

How It Works

  1. Initialization: When you open a terminal tab, kubetab init creates a private kubeconfig file for that tab
  2. Watching: A background watcher process monitors your base kubeconfig for changes
  3. Syncing: When base config changes, the watcher updates your tab's config while preserving tab-local settings
  4. Isolation: Each tab's KUBECONFIG environment variable points to its own file

File Layout

~/.kube/
├── config                                    # Base kubeconfig (source of truth)
└── sessions/
    ├── kubeconfig.w0t0p0.yaml               # Tab-specific kubeconfig
    ├── kubetab.w0t0p0.pid                   # Watcher PID
    ├── kubetab.w0t0p0.log                   # Watcher log
    └── kubetab.w0t0p0.base.sig              # Base config signature cache

Usage

Basic Commands

init

Initialize kubetab for the current terminal tab:

kubetab init [flags]

Common flags:

  • --shell {zsh|bash|fish|posix} - Shell output format (default: zsh)
  • --base <path> - Base kubeconfig path (default: ~/.kube/config)
  • --preserve {ns|all} - What to preserve across syncs (default: ns)
    • ns - Preserve namespace changes only
    • all - Preserve namespace, cluster, and user overrides
  • --watch {auto|fsnotify|poll|off} - Watch mode (default: auto)
  • --poll-interval <duration> - Polling interval (default: 2s)

status

Show status of current tab:

kubetab status

Example output:

Kubetab Status
==============

Session ID:     w0t0p0_645B9C4C-5F71-4DD5-B4C1-5E6AC4317ED1
Base config:    /Users/you/.kube/config
Tab config:     /Users/you/.kube/sessions/kubeconfig.w0t0p0_645B9C4C-5F71-4DD5-B4C1-5E6AC4317ED1.yaml
Log file:       /Users/you/.kube/sessions/kubetab.w0t0p0_645B9C4C-5F71-4DD5-B4C1-5E6AC4317ED1.log

Tab config:     exists (size: 2847 bytes, modified: 2025-12-14T10:30:45-08:00)
Watcher:        running (PID: 12345)
Log file:       exists (size: 1523 bytes, modified: 2025-12-14T10:30:45-08:00)

cleanup

Remove stale session files from closed tabs:

kubetab cleanup [--dry-run]

watch

Run the watcher daemon (usually started automatically by init):

kubetab watch --base <path> --out <path> --id <id> [flags]

You typically don't run this manually.

Preservation Modes

ns mode (default)

Preserves only namespace changes for each context:

  • You switch to context prod in Tab 1, set namespace to app-ns
  • Base config is updated with a new context staging
  • Tab 1 keeps context prod with namespace app-ns
  • Tab 2 can independently work with staging context

all mode

Preserves namespace, cluster, and user overrides:

  • Useful if you temporarily modify cluster endpoints or auth info per-tab
  • More complex, usually not needed for typical usage

Watch Modes

auto (recommended)

  • Uses fsnotify to watch base kubeconfig directory
  • Runs concurrent polling every 2s as fallback
  • Best reliability across different scenarios (symlinks, atomic writes, etc.)

fsnotify

  • Pure fsnotify watching
  • Faster event detection but may miss some edge cases

poll

  • Pure polling
  • Most compatible but slightly higher latency

off

  • No watching, only initial sync
  • You must manually re-run kubetab init to refresh

Examples

Standard iTerm2 + zsh

# ~/.zshrc
[[ -o interactive && -n "$ITERM_SESSION_ID" ]] && eval "$(kubetab init --shell zsh)"
alias kc='kubecm --config "$KUBECONFIG"'

Different base config location

eval "$(kubetab init --base ~/my-kube/config --shell zsh)"

Preserve all overrides, not just namespaces

eval "$(kubetab init --preserve all --shell zsh)"

Disable watching (manual refresh only)

eval "$(kubetab init --watch off --shell zsh)"

Workflow Example

Tab 1 - Production work:

$ kc switch prod
$ kc ns production-app
$ kubectl get pods
# Working in prod context, production-app namespace

Tab 2 - Staging work (independent):

$ kc switch staging
$ kc ns staging-app
$ kubectl get pods
# Working in staging context, staging-app namespace

Tab 3 - Development:

$ kc switch dev
$ kubectl get pods
# Working in dev context, default namespace

Meanwhile, if your base kubeconfig gets updated (e.g., cloud auth refresh, new context added), all tabs automatically see the update without losing their tab-local context/namespace settings.

Troubleshooting

Check watcher status

kubetab status

View watcher logs

tail -f ~/.kube/sessions/kubetab.*.log

Clean up stale files

kubetab cleanup

Manually restart watcher

# Find and kill old watcher
kubetab cleanup

# Reinitialize (starts new watcher)
eval "$(kubetab init)"

Tab isolation not working

Ensure ITERM_SESSION_ID is set:

echo $ITERM_SESSION_ID

If empty, you're not in iTerm2 or it's not exporting the session ID.

Technical Details

Tab Identity

  • Primary: ITERM_SESSION_ID environment variable
  • Fallback: TERM_SESSION_ID or random UUID
  • Sanitized to be filesystem-safe

Atomic Operations

  • All kubeconfig writes are atomic (write to temp file, then rename)
  • Prevents corruption from concurrent access

Change Detection

  • SHA-256 hash of base kubeconfig content
  • Efficient no-op when base hasn't changed
  • Works correctly with symlinks and atomic replacements

Security

  • All files created with 0600 permissions (user read/write only)
  • Sessions directory created with 0700 permissions
  • No sensitive data in logs (only metadata)

Compatibility

  • Primary: macOS + iTerm2 + zsh
  • Also works: macOS Terminal, Linux terminals, bash, fish
  • Not tested: Windows (WSL might work)

Contributing

Contributions welcome! Please open issues or PRs on GitHub.

License

MIT License - see LICENSE file for details

Acknowledgments

Inspired by the need for better kubectl context management in multi-environment workflows.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors