diff --git a/docs/index.html b/docs/index.html index fcf8134..6dbaddd 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,789 +1,195 @@ - - - - - kportal - Kubernetes Port-Forward Manager - - - - - - - - - - - - - +* { box-sizing: border-box; } +html { scroll-behavior: smooth; } +body { + margin: 0; + background: var(--bg); + color: var(--fg); + font: 16px/1.55 var(--sans); + overflow-wrap: break-word; +} +a { color: var(--accent); } +a:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +img { max-width: 100%; height: auto; } - -
-
-
-
-
+.wrap { max-width: 56rem; margin: 0 auto; padding: 0 1rem; } -
-
-
- kportal logo - -
-

- Kubernetes Port-Forward
Manager -

-

- Terminal interface for managing multiple Kubernetes port-forwards with auto-reconnect, hot-reload, health monitoring, and mDNS hostnames. -

- -
- Version - License - Go Report -
-
-
-
- kportal terminal interface -
-
-
-
-
+header { border-bottom: 1px solid var(--line); } +header .wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1.25rem; padding-top: 0.75rem; padding-bottom: 0.75rem; } +header img { height: 2rem; width: auto; display: block; } +nav { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; flex: 1; } +nav a { color: var(--muted); text-decoration: none; padding: 0.25rem 0; } +nav a:hover { color: var(--fg); text-decoration: underline; } +#theme { font: inherit; background: none; color: var(--muted); border: 1px solid var(--line); padding: 0.25rem 0.6rem; cursor: pointer; } +#theme:hover { color: var(--fg); } - -
-
-
-

Features

-

Everything you need for production-grade port-forwarding

-
-
-
-
-
- -
-
-

Interactive TUI

-

Beautiful terminal interface with real-time updates and keyboard navigation

-
-
-
-
-
-
- -
-
-

Live Management

-

Add, edit, delete, and toggle port-forwards without restarting

-
-
-
-
-
-
- -
-
-

Auto-Reconnect

-

Exponential backoff retry with infinite retries on connection failures

-
-
-
-
-
-
- -
-
-

Hot-Reload

-

Configuration changes applied automatically without restart

-
-
-
-
-
-
- -
-
-

Health Monitoring

-

Multiple check methods with stale connection detection

-
-
-
-
-
-
- -
-
-

mDNS Hostnames

-

Access forwards via .local hostnames without /etc/hosts

-
-
-
-
-
-
- -
-
-

Multi-Context

-

Manage forwards across multiple clusters and namespaces

-
-
-
-
-
-
- -
-
-

Pod Restart Handling

-

Automatic reconnection when pods restart or reschedule

-
-
-
-
-
-
- -
-
-

Port Conflict Detection

-

Validates port availability with process ID information

-
-
-
-
-
-
- -
-
-

HTTP Traffic Logging

-

Real-time HTTP logging with detail view, JSON highlighting, gzip decompression, and clipboard copy

-
-
-
-
-
-
- -
-
-

Connection Benchmarking

-

Built-in HTTP benchmarking with latency percentiles

-
-
-
-
-
-
- -
-
-

Headless Mode

-

Background operation for scripting and automation, logs to stderr

-
-
-
-
-
-
- -
-
-

Bulk Generate

-

kportal generate discovers cluster services and bulk-adds forwards with consecutive ports

-
-
-
-
-
-
- -
-
-

Sensitive Header Redaction

-

HTTP log header values for Authorization, Cookie, tokens and similar are redacted automatically

-
-
-
-
-
-
- -
-
-

Verified Installer

-

SHA-256 checksum verification on every install, with optional cosign signature check

-
-
-
-
-
-
+.logo-dark { display: none; } +@media (prefers-color-scheme: dark) { .logo-light { display: none; } .logo-dark { display: block; } } +:root[data-theme="light"] .logo-light { display: block; } +:root[data-theme="light"] .logo-dark { display: none; } +:root[data-theme="dark"] .logo-light { display: none; } +:root[data-theme="dark"] .logo-dark { display: block; } - -
-
-
-

Comparison

-

How kportal compares to other Kubernetes port-forwarding tools

-
+h1 { font-size: clamp(1.75rem, 5vw, 2.5rem); line-height: 1.15; margin: 2.5rem 0 1rem; max-width: 22ch; } +h2 { font-size: 1.4rem; margin: 0 0 1rem; padding-top: 0.5rem; border-top: 1px solid var(--line); } +h3 { font-size: 1.05rem; margin: 1.5rem 0 0.5rem; } +section { padding: 2rem 0 0.5rem; } +p { margin: 0 0 1rem; max-width: 42rem; } +.lead { font-size: 1.1rem; color: var(--muted); } +ul, ol { margin: 0 0 1rem; padding-left: 1.25rem; max-width: 42rem; } - -
- -
-
-
- K -
-
-

kportal

-

Terminal TUI | Single binary

-
-
-
-
✓Persistent Config
-
✓Auto-reconnect
-
✓Hot-reload
-
✓Health Checks
-
✓Stale Detection
-
✓HTTP Logging
-
✓Benchmarking
-
✓mDNS Hostnames
-
✓Label Selectors
-
✓Headless Mode
-
✗System Tray
-
✗UDP Support
-
-
+code, pre, kbd { font-family: var(--mono); font-size: 0.9em; } +code, kbd { background: var(--code-bg); border: 1px solid var(--line); padding: 0.05em 0.35em; } +pre { + background: var(--code-bg); + border: 1px solid var(--line); + padding: 0.75rem 1rem; + margin: 0 0 1rem; + overflow-x: auto; + line-height: 1.45; +} +pre code { background: none; border: 0; padding: 0; font-size: 1em; } +.cmd { position: relative; } +.cmd button { position: absolute; top: 0.4rem; right: 0.4rem; font: 0.8rem var(--sans); background: var(--bg); color: var(--muted); border: 1px solid var(--line); padding: 0.15rem 0.5rem; cursor: pointer; } +.cmd pre { padding-right: 4.5rem; } - -
-
-
- k9 -
-
- k9s -

Terminal TUI | Single binary

-
-
-
-
✗Persistent Config
-
✗Auto-reconnect
-
✗Hot-reload
-
✗Health Checks
-
✗Stale Detection
-
✗HTTP Logging
-
✓Benchmarking
-
✗mDNS Hostnames
-
✓Label Selectors
-
✗Headless Mode
-
✗System Tray
-
✗UDP Support
-
-
+.tablewrap { overflow-x: auto; margin: 0 0 1rem; border: 1px solid var(--line); } +table { border-collapse: collapse; width: 100%; font-size: 0.95rem; } +th, td { text-align: left; vertical-align: top; padding: 0.45rem 0.75rem; border-bottom: 1px solid var(--line); } +tr:last-child td { border-bottom: 0; } +th { font-weight: 600; background: var(--code-bg); white-space: nowrap; } +td:first-child { white-space: nowrap; } +.tablewrap.wrapfirst td:first-child { white-space: normal; } - -
-
-
- KF -
-
- Kube Forwarder -

Desktop GUI | Electron

-
-
-
-
✓Persistent Config
-
✓Auto-reconnect
-
✗Hot-reload
-
✗Health Checks
-
✗Stale Detection
-
✗HTTP Logging
-
✗Benchmarking
-
✗mDNS Hostnames
-
✗Label Selectors
-
✗Headless Mode
-
✗System Tray
-
✗UDP Support
-
-
+.shot { margin: 1.5rem 0 0; border: 1px solid var(--line); display: block; } +.cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 2rem; } +@media (min-width: 48rem) { .cols { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } } - -
-
-
- kft -
-
- kftray -

Desktop + TUI | Tauri

-
-
-
-
✓Persistent Config
-
✓Auto-reconnect
-
✗Hot-reload
-
✗Health Checks
-
✗Stale Detection
-
✓HTTP Logging
-
✗Benchmarking
-
✗mDNS Hostnames
-
✓Label Selectors
-
✗Headless Mode
-
✓System Tray
-
✓UDP Support
-
-
-
+footer { margin-top: 3rem; border-top: 1px solid var(--line); padding: 1.25rem 0 2rem; color: var(--muted); font-size: 0.9rem; } +footer .wrap { display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; } +.badges { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1.5rem; } +.badges img { height: 20px; width: auto; } +@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } } + + + + +
+ +
- - -
-
+
+

Run Kubernetes port-forwards from one YAML file

+

kportal starts every forward listed in .kportal.yaml, shows their status in a terminal UI, reconnects dropped forwards and reloads the file when it changes. It also runs without the UI.

- -
-
-
-

Installation

-

Get started in seconds

-
-
-
-
- -
-

Homebrew

-

macOS

-
-
-
- brew install --cask lukaszraczylo/taps/kportal -
-
-
-
-
- -
-

Quick Install

-

All platforms

-
-
-
- curl -fsSL https://raw.githubusercontent.com/lukaszraczylo/kportal/main/install.sh | bash -
-
-

Verifies SHA-256 against the release checksums file. If cosign is on PATH, the keyless cosign signature is verified too. Set DRY_RUN=1 to preview, SKIP_COSIGN=1 to bypass cosign.

-
-
-
- -
-

Manual Download

-

Linux, macOS, Windows (amd64 & arm64)

-
-
- - Download from GitHub Releases - -
-
-
-
+
brew install --cask lukaszraczylo/taps/kportal
- -
-
-
-

Usage

-

Simple commands, powerful results

-
-
-
-

Interactive Mode

-
- kportal -
-
-

Launch the interactive TUI with real-time status updates and keyboard controls.

-
-
-

Verbose Mode

-
- kportal -v -
-
-

Run with detailed logging for debugging and automation.

-
-
-

Validate Config

-
- kportal --check -
-
-

Validate configuration without starting any forwards.

-
-
-

Custom Config

-
- kportal -c /path/to/config.yaml -
-
-

Use a custom configuration file instead of .kportal.yaml

-
-
-

Select Contexts

-
- kportal --context development-team-a -
-
-

Forward only the contexts you name instead of all of them. Repeatable and comma-separated. Contexts never selected together can reuse the same local ports.

-
-
-

Headless Mode

-
- kportal -headless -v 2>kportal.log & -
-
-

Run without TUI for scripting; logs are emitted on stderr.

-
-
-

Bulk Generate

-
- kportal generate --context=my-cluster -
-
-

Discover services in a cluster and bulk-add forwards with consecutive local ports. Add --dry-run to preview.

-
-
+
+ Release + License + Go Report Card +
- -
-

Keyboard Shortcuts

-
-
- ↑↓ - Navigate -
-
- Space - Toggle -
-
- n - Add -
-
- e - Edit -
-
- d - Delete -
-
- j/k - Vim nav -
-
- b - Benchmark -
-
- l - HTTP logs -
-
-
+ kportal terminal UI listing port-forwards with their status - -
-

Status Indicators

-
-
- ● - Active -
-
- ○ - Starting -
-
- ◐ - Reconnecting -
-
- ✗ - Error -
-
- ○ - Disabled -
-
-
-
-
+
+

Features

+
+ + + + + + + + + + + + + + + + + + + + +
Forwardsservice/<name>, pod/<name> (exact name or prefix), or pod with a label selector. TCP only.
Terminal UIAdd, edit, delete and toggle forwards without a restart. The add wizard writes the config file.
Table columnstui.columns sets which columns the forwards table shows, their order and width. It applies to the UI and the -verbose table.
Add wizardIf the cluster does not allow listing namespaces, the wizard asks you to type the namespace.
ReconnectExponential backoff: 1s, 2s, 4s, 8s, then 10s, with 10% jitter. It does not stop retrying.
Pod restartsForwards by pod prefix or selector connect to the new pod.
Health checkstcp-dial or data-transfer, every 3s by default. Stale connections are reconnected by age and idle time.
Hot reloadFile watcher and SIGHUP. An invalid config is rejected and the previous one stays active.
ContextsSeveral contexts and namespaces in one file. --context selects which contexts run.
Port conflictsStartup and reload checks report a busy local port and the process that holds it.
mDNSWith mdns.enabled: true, each forward is reachable as <alias>.local.
HTTP logPer-forward request log with details, filter, search, JSON formatting, gzip decoding and body copy. Sensitive header values are redacted.
BenchmarkHTTP requests through a forward. Reports min, max and average latency, P50, P95, P99, requests per second and status codes.
Generatekportal generate lists cluster services and appends the ones you pick, with consecutive local ports.
Headless-headless runs without the UI and logs to stderr. -log-format json switches the log format.
Import--convert turns a kftray JSON file into kportal YAML.
Shell completionkportal completion prints or installs bash, zsh and fish completions.
+
+
- -
-
-
-

Configuration

-

Simple YAML configuration with powerful options

-
+
+

Install

+

Homebrew (macOS)

+
brew install --cask lukaszraczylo/taps/kportal
+

Install script

+
curl -fsSL https://raw.githubusercontent.com/lukaszraczylo/kportal/main/install.sh | bash
+

The script verifies the archive SHA-256 against the release checksums file. If cosign is on PATH, it also verifies the keyless signature. Set DRY_RUN=1 to download and verify without installing. Set SKIP_COSIGN=1 to skip the cosign check.

+

Manual download

+

The releases page has archives for Linux, macOS and Windows on amd64 and arm64.

+

Build from source

+
git clone https://github.com/lukaszraczylo/kportal.git
+cd kportal
+make build && make install
+

The build needs Go 1.26 or later.

+
-
- -
-
-
-
-
- - Basic Configuration -
- -
-
contexts:
+  
+

Usage

+

Quick start

+

Create .kportal.yaml, then run kportal.

+
contexts:
   - name: production
     namespaces:
       - name: backend
@@ -794,34 +200,122 @@
             localPort: 5432
             alias: prod-db
 
-          - resource: pod/nginx
+          - resource: service/api
             protocol: tcp
-            port: 80
+            port: 8080
             localPort: 8080
-            httpLog: true   # log HTTP traffic
-
-
+ alias: api + httpLog: true - -
-
-
-
-
- - With mDNS & Health Checks -
- -
-
mdns:
-  enabled: true
+    

Commands and flags

+
+ + + + + + + + + + + + + + + + +
Command or flagEffect
kportalStart the terminal UI.
-c <file>Config file. Default .kportal.yaml.
-vVerbose logging.
-headlessNo UI. Logs go to stderr.
-checkValidate the config and exit.
-context <name>Forward only the named contexts. Repeatable, or comma-separated.
-log-format text|jsonLog format. Default text.
-convert <file>Convert a kftray JSON file. -convert-output sets the output, default .kportal.yaml.
-updateCheck for updates and exit.
-versionPrint the version and exit.
kportal generateAdd forwards from a cluster. Needs --context. --config picks the file and --dry-run only prints.
kportal completionPrint a completion script. --shell bash|zsh|fish, --install, --uninstall.
+
-healthCheck: +

Examples

+
kportal -check
+kportal -c /path/to/config.yaml
+kportal --context development-team-a
+kportal -headless -v 2>kportal.log &
+kportal generate --context=my-cluster --dry-run
+kportal completion --shell zsh --install
+

With --context, contexts you never select together can reuse a localPort. Without it, a duplicate local port is an error.

+
+ +
+

Keys

+
+
+

Forwards list

+
+ + + + + + + + + + + + +
Up Down / j kMove
PgUp PgDnMove by 10 rows
Space / EnterToggle forward
nAdd forward
eEdit forward
dDelete forward
bBenchmark
lHTTP log
qQuit
+
+

In the add and edit wizard, h on the confirmation step toggles httpLog.

+
+
+

Status

+
+ + + + + + + + +
● ActiveConnection healthy
○ StartingFirst connection. Failed checks show Starting for 10s.
◐ ReconnectingReconnecting after a failure
✗ ErrorConnection failed
○ DisabledTurned off in the UI
+
+
+
+
+ +
+

Configuration

+

Forward fields

+
+ + + + + + + + + + + +
FieldRequiredDescription
resourceYesservice/<name>, pod/<name>, or pod with selector
protocolNotcp. No other value is accepted.
portYesRemote port
localPortYesLocal port
aliasNoDisplay name and mDNS hostname
selectorWith bare podLabel selector, for example app=nginx. Not allowed with pod/<name>.
httpLogNotrue, or a map of options
+
+ +
+
+

Health checks and reliability

+
healthCheck:
   interval: "3s"
+  timeout: "2s"
   method: "data-transfer"
   maxConnectionAge: "25m"
+  maxIdleTime: "10m"
+
+reliability:
+  tcpKeepalive: "30s"
+  dialTimeout: "30s"
+  retryOnStale: true
+  watchdogPeriod: "30s"
+

These are the defaults. method is tcp-dial or data-transfer. A connection past maxConnectionAge reconnects only when it is also idle.

+
+
+

mDNS

+
mdns:
+  enabled: true
 
 contexts:
   - name: production
@@ -831,281 +325,93 @@ contexts:
           - resource: service/postgres
             port: 5432
             localPort: 5432
-            alias: db  # db.local
-
-
- + alias: db # db.local
+

Without an alias, service/redis publishes redis.local.

+ + - -
-
-

Resource Types

-
    -
  • service/name Service
  • -
  • pod/name Pod by name
  • -
  • pod/prefix Pod by prefix
  • -
  • deployment/name Deployment
  • -
-
-
-

Label Selectors

-
    -
  • resource: pod
  • -
  • selector: app=nginx
  • -
  • Dynamically resolves to running pods
  • -
-
-
-

Forward Options

-
    -
  • resource - Target resource
  • -
  • port - Remote port
  • -
  • localPort - Local port
  • -
  • alias - Display name & mDNS
  • -
  • selector - Label selector
  • -
-
-
- -
+

Table columns

+
tui:
+  columns:
+    - name: alias
+      width: 30      # optional, 1-200
+    - name: resource
+    - name: local
+    - name: status
+

Valid names: context, namespace, alias, type, resource, remote, local, status. List order is render order and unlisted columns are hidden. Without tui, the table keeps its default columns. The setting applies to the UI and the -verbose table.

- -
-
-
-

Advanced Features

-

Production-ready capabilities

-
+

Reload

+

kportal reloads when the file changes. To reload by hand, run kill -HUP $(pgrep kportal).

+
-
- -
-

Health Checks

-

Advanced health monitoring prevents stale connections during long operations.

-
-
tcp-dialFast connection test
-
data-transferVerifies tunnel
-
maxConnectionAgeAuto reconnect
-
maxIdleTimeDetect idle
-
-
+
+

HTTP log and benchmark

+

Press l on a forward that has httpLog set. The list shows TIME, METHOD, STATUS, LATENCY and PATH.

+
httpLog:
+  enabled: true
+  includeHeaders: true   # sensitive values are redacted
+  maxBodySize: 65536     # bytes, 0 = unlimited
+  filterPath: "/api/"    # log only paths containing this text
+  logFile: "api.log"     # also append entries to this file
+
+
+

List view

+
    +
  • Enter opens details
  • +
  • g / G jump to top or bottom
  • +
  • a toggles auto-scroll
  • +
  • f cycles the filter: All, Non-2xx, Errors
  • +
  • / searches path or method
  • +
  • c clears filters, q closes
  • +
+
+
+

Detail view

+
    +
  • Headers, bodies and timing
  • +
  • JSON is pretty-printed, gzip and deflate are decoded
  • +
  • c copies the response body
  • +
  • Esc, q or Enter returns to the list
  • +
+
+
+

With includeHeaders: true, values of Authorization, Cookie, Set-Cookie, X-Api-Key, X-Auth-Token, X-Csrf-Token, Proxy-Authorization, X-Access-Token and any header whose name contains token, secret, password or apikey become [REDACTED]. This cannot be turned off.

+

Benchmark

+

Press b on a forward. Set the URL path (default /), method, concurrency and request count.

+
- -
-

mDNS Hostnames

-

Access forwards via .local hostnames without editing /etc/hosts.

-
-
- alias: prod-db - → - prod-db.local -
-
- service/redis - → - redis.local -
-

Works on macOS & Linux

-
-
+
+

More

+

The README covers troubleshooting, kftray import and telemetry opt-out. Release history is in the changelog.

+
+
- -
-

Hot Reload

-

Configuration changes are applied automatically without restarting.

- -
+ - -
-

Retry Strategy

-

Exponential backoff with infinite retries ensures reliability.

-
- 1s - → - 2s - → - 4s - → - 10s max -
-
- - -
-

HTTP Traffic Logging

-

Press l to view real-time HTTP traffic.

-
-
- List view: Time, Method, Status, Path -
-
- Enter - Details - f - Filter - / - Search -
-
- Detail view: Headers, body, timing -
-
- c - Copy body - Esc - Back -
-
- JSON highlighting, gzip decompression, binary detection -
-
- Sensitive header values (auth, cookies, tokens) redacted automatically -
-
- Press h in the add/edit wizard to toggle httpLog -
-
-
- - -
-

Benchmarking

-

Press b to benchmark connections.

-
-
ConcurrencyParallel workers
-
RequestsTotal count
-
LatencyP50/P95/P99
-
ThroughputReq/s
-
-
- - - - - - - - - + +