mirror of
https://github.com/lukaszraczylo/kportal.git
synced 2026-07-07 06:25:43 +00:00
WIP - before the testing.
This commit is contained in:
@@ -0,0 +1,320 @@
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```yaml
|
||||
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
|
||||
```yaml
|
||||
- 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
|
||||
```yaml
|
||||
- resource: pod
|
||||
selector: app=nginx,env=prod
|
||||
port: 80
|
||||
localPort: 8080
|
||||
```
|
||||
Dynamically selects pods matching the label selector.
|
||||
|
||||
#### Service
|
||||
```yaml
|
||||
- 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
|
||||
|
||||
```bash
|
||||
# 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](https://github.com/lukaszraczylo/semver-generator) 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.
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```yaml
|
||||
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
|
||||
|
||||
```yaml
|
||||
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
|
||||
Reference in New Issue
Block a user