2025-11-23 15:24:51 +00:00
2025-11-23 15:03:25 +00:00
2025-11-23 15:24:51 +00:00
2025-11-23 15:24:51 +00:00
2025-11-23 15:24:51 +00:00
2025-11-23 15:24:51 +00:00
2025-11-23 15:24:51 +00:00
2025-11-23 15:24:51 +00:00

kportal

A robust Kubernetes port-forwarding tool that manages multiple concurrent port-forwards across different contexts, namespaces, and resources with automatic reconnection and failure recovery.

Features

  • Multi-Context Support: Forward ports from multiple Kubernetes contexts simultaneously
  • Automatic Pod Restart Handling: Detects and reconnects to pods when they restart
  • Label Selector Support: Dynamically target pods using label selectors
  • Prefix Matching: Automatically find and reconnect to pods with name prefixes
  • Hot-Reload: Configuration file changes are automatically detected and applied
  • Resilient Connections: Infinite retry with exponential backoff (max 10s)
  • Port Conflict Detection: Validates port availability before starting
  • Multiple Ports Per Resource: Forward multiple ports from the same pod/service

Installation

# Install development tools (including semver-gen for version management)
make install-tools

# Build from source (version automatically generated from git history)
make build

# Install to user bin directory
make install

# Install system-wide (requires sudo)
sudo make install-system

# Or build manually
go build -o kportal ./cmd/kportal

Usage

Basic Usage

# Use default config file (.kportal.yaml)
./kportal

# Use custom config file
./kportal -c myconfig.yaml

# Enable verbose logging
./kportal -v

# Validate configuration without starting
./kportal --check

Configuration File

Create a .kportal.yaml file in your current directory:

contexts:
  - name: production
    namespaces:
      - name: default
        forwards:
          # Pod with prefix matching (auto-handles restarts)
          - resource: pod/my-app
            protocol: tcp
            port: 8080
            localPort: 8080

          # Service forwarding
          - resource: service/postgres
            protocol: tcp
            port: 5432
            localPort: 5432

      - name: monitoring
        forwards:
          # Pod with label selector
          - resource: pod
            selector: app=prometheus
            protocol: tcp
            port: 9090
            localPort: 9090

  - name: staging
    namespaces:
      - name: default
        forwards:
          # Multiple ports from same pod
          - resource: pod/test-app
            port: 8080
            localPort: 8081

          - resource: pod/test-app
            port: 9090
            localPort: 9091

Resource Types

Pod with Prefix Matching

- resource: pod/my-app    # Matches my-app-xyz789, my-app-abc123, etc.
  port: 8080
  localPort: 8080

Automatically reconnects to new pods when they restart.

Pod with Label Selector

- resource: pod
  selector: app=nginx,env=prod
  port: 80
  localPort: 8080

Dynamically selects pods matching the label selector.

Service

- resource: service/postgres
  port: 5432
  localPort: 5432

Most stable option - forwards to service endpoints.

How It Works

Pod Restart Handling

When a pod restarts:

  1. The port-forward connection breaks
  2. kportal immediately attempts to re-resolve the resource
  3. For prefix matches: finds the newest pod with that prefix
  4. For selectors: re-queries pods with matching labels
  5. Reconnects to the new pod
  6. Logs the switch: Switched to new pod: old-pod → new-pod

Retry Strategy

Backoff intervals: 1s → 2s → 4s → 8s → 10s (max)

  • Connection failures trigger immediate resource re-resolution
  • Retries continue indefinitely until successful
  • Each forward has independent retry logic

Hot-Reload

The config file is watched for changes:

  1. File change detected
  2. New config loaded and validated
  3. Changes diff'd against current state
  4. New forwards started, removed forwards stopped
  5. Unchanged forwards continue running

If validation fails, the previous configuration remains active.

Development

Build Commands

# Build binary
make build

# Check current version (from semver-gen)
make version

# Run all checks (fmt, vet, staticcheck, test, build)
make all

# Run tests with race detection
make test

# Run code quality checks
make vet
make staticcheck
make fmt

# Install development tools (staticcheck, mockery, semver-gen)
make install-tools

# Generate test coverage report
make coverage

Semantic Versioning

This project uses semver-gen for automatic semantic version generation based on git commit messages.

Version Keywords:

  • Patch (0.0.X): fix, bugfix, hotfix, patch, docs, test, refactor
  • Minor (0.X.0): feat, feature, add, enhance, update, improve
  • Major (X.0.0): breaking, major, BREAKING CHANGE

The version is automatically calculated from your git history and embedded in the binary at build time.

# Check current version
make version

# Build with auto-generated version
make build

# Verify version in binary
./kportal --version

Configuration is managed in semver.yaml. To manually install semver-gen:

# Automatically installed via make install-tools
# Or install manually from https://github.com/lukaszraczylo/semver-generator

Project Structure

kportal/
├── cmd/kportal/          # CLI entry point
├── internal/
│   ├── config/           # Configuration parsing and validation
│   ├── forward/          # Port-forward workers and manager
│   ├── k8s/             # Kubernetes client, resolver, port-forward wrapper
│   └── retry/           # Exponential backoff logic
├── test/
│   ├── integration/     # Integration tests
│   ├── fixtures/        # Test configurations
│   └── helpers/         # Test utilities
├── .kportal.yaml        # Example configuration
├── semver.yaml          # Semantic version configuration
├── Makefile             # Build automation
└── CLAUDE.md            # Development guide

Signal Handling

  • CTRL+C / SIGTERM: Graceful shutdown (closes all forwards)
  • SIGHUP: Reload configuration file

Port Conflict Detection

kportal validates ports at multiple stages:

  1. Config Parse Time: Detects duplicate local ports in configuration
  2. Startup Time: Checks if ports are available on the system
  3. Hot-Reload Time: Validates new ports before applying changes

Errors show which process is using conflicting ports (with PID).

Examples

Forward Multiple Services from Production

contexts:
  - name: production
    namespaces:
      - name: default
        forwards:
          - resource: service/api
            port: 8080
            localPort: 8080
          - resource: service/postgres
            port: 5432
            localPort: 5432
          - resource: service/redis
            port: 6379
            localPort: 6379

Monitor Multiple Environments

contexts:
  - name: production
    namespaces:
      - name: monitoring
        forwards:
          - resource: service/prometheus
            port: 9090
            localPort: 9090

  - name: staging
    namespaces:
      - name: monitoring
        forwards:
          - resource: service/prometheus
            port: 9090
            localPort: 9091  # Different local port

Debug Specific Pods

contexts:
  - name: production
    namespaces:
      - name: default
        forwards:
          # Forward app HTTP and debug ports
          - resource: pod
            selector: app=myapp,version=v2
            port: 8080
            localPort: 8080

          - resource: pod
            selector: app=myapp,version=v2
            port: 6060  # pprof
            localPort: 6060

License

MIT

Contributing

Contributions welcome! Please ensure:

  • Code passes make check (fmt, vet, staticcheck)
  • Tests pass with make test
  • New features include tests
S
Description
Languages
Go 98.3%
Shell 0.8%
Makefile 0.7%
Ruby 0.2%