Skip to main content

A terminal utility with a better UX for kubectl port-forward

Project description

kpf - A better way to port-forward with kubectl

This is a Python utility that (attempts to) dramatically improve the experience of port-forwarding with kubectl.

It is essentially a wrapper around kubectl port-forward that adds an interactive service selection with automatic reconnect when the pods are restarted or your network connection is interrupted (computer goes to sleep, etc).

Features

  • 🔄 Automatic Restart: Monitors endpoint changes and restarts port-forward automatically
  • 🎯 Interactive Selection: Choose services with a colorful, intuitive interface
  • 🌈 Color-coded Status: Green for services with endpoints, red for those without
  • 🔍 Multi-resource Support: Services, pods, deployments, etc.
  • 🔐 Smart Port Handling: Automatically detects privileged port issues (< 1024) and suggests alternatives

Installation

Note: The oh-my-zsh kubectl plugin will conflict with this kpf command. You must unalias kpf before using this tool.

echo "unalias kpf" >> ~/.zshrc

Homebrew (Recommended)

brew tap jessegoodier/kpf
brew install kpf

Or install directly:

brew install jessegoodier/kpf/kpf

Using pipx

pipx install kpf

Using uv

If you have uv installed, you can install kpf with:

uv tool install kpf

from source:

uv tool install .

Usage

Interactive Mode (Recommended)

Warm Tip: You can use the interactive mode to find the service you want, and it will output the command to connect to that service directly next time.

Note: You might think that "warm tip" is something that AI wrote, but that's not the case. It really is just a little bit cooler than a hot tip.

screenshot1 screenshot2 screenshot3

Select services interactively:

Interactive selection in current namespace:

kpf

Interactive selection in specific namespace:

kpf -n production

Interactive selection with namespace prompt:

kpf -p

Show all services across all namespaces:

kpf --all

Include pods and deployments with ports defined:

kpf --all-ports

Combine a few options (interactive mode, all services, and endpoint status checking, debug mode):

kpf -pAdl

Check Mode

Add endpoint status checking to service selection (slower but shows endpoint health):

# Interactive selection with endpoint status
kpf --check

# Show all services with endpoint status
kpf --all --check

# Include pods and deployments with status
kpf --all-ports --check

Legacy Mode

Direct port-forward (maintain expected behavior):

# Traditional kubectl port-forward syntax
kpf svc/frontend 8080:8080 -n production
kpf pod/my-pod 3000:3000

Command Options

Example usage:
  kpf                                           # Interactive mode
  kpf svc/frontend 8080:8080 -n production      # Direct port-forward (maintain expected behavior)
  kpf -n production                             # Interactive selection in specific namespace
  kpf --all (or -A)                             # Show all services across all namespaces
  kpf --all-ports (or -l)                       # Show all services with their ports
  kpf --check -n production                     # Interactive selection with endpoint status
  kpf --prompt-namespace (or -p)                # Interactive namespace selection
  kpf -z                                        # Listen on 0.0.0.0 (all interfaces)

Examples

Interactive Service Selection

Fast mode (without endpoint checking):

$ kpf -n kube-system

Services in namespace: kube-system

#    Type     Name                    Ports
1    SERVICE  kube-dns               53, 9153
2    SERVICE  metrics-server         443
3    SERVICE  kubernetes-dashboard   443

Select a service [1]: 1
Local port (press Enter for 53): 5353

With endpoint status checking:

$ kpf --check -n kube-system

Services in namespace: kube-system

#    Type     Name                    Ports           Status
1    SERVICE  kube-dns               53, 9153         2    SERVICE  metrics-server         443              3    SERVICE  kubernetes-dashboard   443              ✗

✓ = Has endpoints   = No endpoints

Select a service [1]: 1
Local port (press Enter for 53): 5353

Cross-Namespace Discovery

$ kpf --all

Services across all namespaces

#    Namespace    Type     Name           Ports        Status
1    default      SERVICE  kubernetes     443          2    kube-system  SERVICE  kube-dns      53, 9153     3    production   SERVICE  frontend      80, 443      4    production   SERVICE  backend       8080         

Smart Low Port Handling

When you try to use privileged ports (< 1024), kpf will detect the permission issue and offer to use a higher port automatically:

$ kpf -n monitoring svc/grafana 80:80

Error: Port 80 requires elevated privileges (root/sudo)
Low ports (< 1024) require administrator permissions on most systems

Suggested alternative: Use port 1080 instead?
This would forward: localhost:1080 -> service:80

Use suggested port? [Y/n]: y
Updated port mapping to 1080:80

Direct command: kpf svc/grafana 1080:80 -n monitoring

http://localhost:1080

🚀 port-forward started 🚀

This feature prevents confusing "port already in use" errors when the real issue is insufficient permissions.

How It Works

  1. Port-Forward Thread: Runs kubectl port-forward in a separate thread
  2. Endpoint Watcher: Monitors endpoint changes using kubectl get ep -w
  3. Automatic Restart: When endpoints change, gracefully restarts the port-forward
  4. Service Discovery: Uses kubectl to discover services and their endpoint status

Requirements

  • kubectl configured with cluster access

Configuration

kpf can be configured via ~/.config/kpf/kpf.json (follows XDG Base Directory Specification).

All settings are optional with sensible defaults:

{
    "autoSelectFreePort": true,
    "showDirectCommand": true,
    "showDirectCommandIncludeContext": true,
    "directCommandMultiLine": true,
    "autoReconnect": true,
    "reconnectAttempts": 30,
    "reconnectDelaySeconds": 5,
    "captureUsageDetails": false,
    "usageDetailFolder": "${HOME}/.config/kpf/usage-details"
}

Configuration Options

Option Type Default Description
autoSelectFreePort boolean true When requested port is busy, automatically try next ports (9091, 9092, etc.)
showDirectCommand boolean true Show the direct kpf command for future use
showDirectCommandIncludeContext boolean true Include kubectl context in the command display
directCommandMultiLine boolean true Format direct command across multiple lines for readability
autoReconnect boolean true Automatically reconnect when connection drops
reconnectAttempts integer 30 Number of reconnection attempts before giving up
reconnectDelaySeconds integer 5 Delay in seconds between reconnection attempts
captureUsageDetails boolean false Capture usage details locally for debugging (not sent anywhere)
usageDetailFolder string ${HOME}/.config/kpf/usage-details Where to store usage detail logs

Notes:

  • All settings are optional - kpf will use defaults if the config file doesn't exist
  • Environment variables like ${HOME} are expanded automatically
  • The config file location respects the XDG_CONFIG_HOME environment variable
  • Invalid JSON or unknown keys will show warnings but won't prevent kpf from running
  • CLI arguments override config file values when provided

Example: Minimal Configuration

If you only want to change specific settings:

{
    "showDirectCommand": false,
    "reconnectAttempts": 10
}

Development

Setup Development Environment

# Clone the repository
git clone https://github.com/jessegoodier/kpf.git
cd kpf

# Install with development dependencies
uv venv
uv pip install -e ".[dev]"
source .venv/bin/activate

Code Quality Tools

# Format and lint code
uvx ruff check . --fix
uvx ruff format .

# Sort imports
uvx isort .

# Run tests
uv run pytest

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests and linting
  5. Submit a pull request

Shell Completion

Shell completions can be generated using the --completions flag.

Homebrew

If you installed via Homebrew (and the formula is updated), completions should be installed automatically. You may need to follow Homebrew's shell completion instructions to ensure it's loaded.

Manual Installation

Bash

# User-local installation (recommended)
kpf --completions bash > ~/.local/share/bash-completion/completions/kpf

# Or system-wide
kpf --completions bash | sudo tee /etc/bash_completion.d/kpf > /dev/null

Zsh

# Add to a directory in your fpath
kpf --completions zsh > /usr/share/zsh/site-functions/_kpf

# Or for oh-my-zsh users
kpf --completions zsh > ~/.oh-my-zsh/completions/_kpf

Then reload your shell: exec $SHELL

License

MIT License - see LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kpf-0.7.0.tar.gz (38.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kpf-0.7.0-py3-none-any.whl (43.2 kB view details)

Uploaded Python 3

File details

Details for the file kpf-0.7.0.tar.gz.

File metadata

  • Download URL: kpf-0.7.0.tar.gz
  • Upload date:
  • Size: 38.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for kpf-0.7.0.tar.gz
Algorithm Hash digest
SHA256 6a955ab624fc920d5f69fd57199a8f00b0d3f23e5519d640e6f4f3d5d2b50310
MD5 71c09ab5c36a1f461721f99b7520734a
BLAKE2b-256 3e7ca09a984d228a8f15b7c140acc61890f8b02a71ae2828a6a9ff156dca65f6

See more details on using hashes here.

File details

Details for the file kpf-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: kpf-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 43.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for kpf-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 447ef31255f28d00faaf2a089d46b93ef04cb3ff36f6069a7e2acbd9098fdfd8
MD5 eec5bb449e8dd3c493223b8c388d3ac1
BLAKE2b-256 ffbf87ce31aa39a60a635bed14da77e5925f9c4485e1f1ca5105a1dba48aa389

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page