util

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2024 License: MIT Imports: 2 Imported by: 0

README ΒΆ

Terraster

MIT License

A high-performance, feature-rich Layer 7 (L7) load balancer with a robust and user-friendly admin API.

[!WARNING]
This project is currently in its early development stages. While the core functionality is in place and working as intended, further improvements and features are actively being developed. Expect updates as the project evolves.

πŸš€ Key Features

  • Multiple load balancing methods including Round Robin, Weighted Round Robin, and IP Hash
  • TLS termination with certificate management
  • Path rewriting and service-to-service redirection
  • Dynamic configuration via comprehensive Admin API
  • Multiple host support on the same port
  • HTTP compression
  • Certificate expiration notifications via email

🎯 Feature Status

Load Balancing Algorithms
  • βœ… Round Robin
  • βœ… Weighted Round Robin
  • βœ… Least Connections
  • βœ… Weighted Least Connections
  • βœ… Response Time Based
  • βœ… IP Hash
  • βœ… Consistent Hashing
  • βœ… Adaptive Load Balancing
Advanced Features
  • ⏳ WebSocket Support (WIP)
  • βœ… SSL/TLS Support
  • ⏳ Automatic Certificate Management (WIP)
  • βœ… Connection Pooling
  • βœ… Circuit Breaker
  • βœ… Rate Limiting
  • βœ… Compression
  • ❌ Custom Request Headers
  • βœ… Dynamic Middleware Plug-in
  • βœ… Configurable Request Logging
Core Features
  • βœ… Health Checking
  • βœ… Dynamic Configuration via Admin API
  • βœ… Graceful Shutdown

🚦 Quick Start

Building from Source
go build -o terraster cmd/main.go

βš™οΈ Configuration Guide

Configuration Methods

Terraster offers three ways to manage your configuration:

  1. Single Config File

    • Create a config file anywhere and use the -config flag
    • Example: ./terraster -config /path/to/config.yaml
  2. Default Config

    • Place config.yaml in the root directory
    • Terraster will load it automatically at startup
  3. Multiple Services

    • Create a directory containing multiple service configs
    • Use the -services flag to point to the directory
    • Example: ./terraster -services /path/to/services/
Basic Configuration

The minimal configuration requires only three fields:

port: 8080
host: "lb.domain.com"
backends:
  - url: http://localhost:8081
  - url: http://localhost:8082
Basic Configuration with Middleware and TLS

This configuration demonstrates TLS termination and basic middleware setup:

port: 8080
algorithm: round-robin
host: "lb.domain.com"
backends:
  - url: http://localhost:8081
  - url: http://localhost:8082

# Middleware Configuration
middleware:
  - rate_limit:
      requests_per_second: 100
      burst: 30
  - security:
      hsts: true
      frame_options: DENY
      xss_protection: true

# TLS Configuration (optional)
tls:
  enabled: true
  cert_file: "./certificates/my_cert.pem"
  key_file: "./certificates/my_cert_privatekey.key"
Advanced Configuration

This example demonstrates a comprehensive setup with multiple services, health checks, and advanced features:

### GLOBAL CONFIG ###
port: 443

# Global Health Check Configuration
health_check:
  interval: 10s
  timeout: 2s
  path: /health

# Global Middleware Configuration
middleware:
  - rate_limit:
      requests_per_second: 100
      burst: 150
  - security:
      hsts: true
      hsts_max_age: 31536000
      frame_options: DENY
      content_type_options: true
      xss_protection: true
  - circuit_breaker:
      threshold: 5
      timeout: 60s

# Global Connection Pool Settings
connection_pool:
  max_idle: 100
  max_open: 1000
  idle_timeout: 90s

### SERVICES CONFIGURATION ###
services:
  # Backend API Service
  - name: backend-api
    host: internal-api1.local.com
    port: 8455
    log_name: backend-api  # Maps to logger configuration
    
    # Service-specific TLS
    tls:
      cert_file: "/path/to/api-cert.pem"
      key_file: "/path/to/api-key.pem"
    
    # Service-specific middleware (overrides global)
    middleware:
      - rate_limit:
          requests_per_second: 2500
          burst: 500
    
    # Service-specific health check
    health_check:
      type: "http"
      path: "/"
      interval: "5s"
      timeout: "3s"
      thresholds:
        healthy: 2
        unhealthy: 3
    
    # Path-based routing
    locations:
      - path: "/api/"
        lb_policy: round-robin
        redirect: "/"
        backends:
          - url: http://internal-api1.local.com:8455
            weight: 5
            max_connections: 1000
            # Backend-specific health check
            health_check:
              type: "http"
              path: "/api_health"
              interval: "4s"
              timeout: "3s"
              thresholds:
                healthy: 1
                unhealthy: 2
          - url: http://internal-api2.local.com:8455
            weight: 3
            max_connections: 800

  # Frontend Service
  - name: frontend
    host: frontend.local.com
    port: 443
    locations:
      - path: "/"
        lb_policy: least_connections
        rewrite: "/frontend/"
        backends:
          - url: http://frontend-1.local.com:3000
            weight: 5
            max_connections: 1000
          - url: http://frontend-2.local.com:3000
            weight: 3
            max_connections: 800

  # HTTP to HTTPS Redirect Service
  - name: frontend_redirect
    host: frontend.local.com
    port: 80
    http_redirect: true
    redirect_port: 443

  # Custom Port Redirect Service
  - name: backend_api_redirect
    host: internal-api1.local.com
    port: 80
    http_redirect: true
    redirect_port: 8455

πŸ“ Logging Configuration

Terraster provides a flexible logging system with three main approaches:

1. Default Logger

If no custom logging configuration is provided, Terraster will use the default logger configuration from log.config.json. Your services will use the service_default logger automatically.

{
  "loggers": {
    "terraster": {
      "level": "debug",
      "outputPaths": ["terraster.log"],
      "errorOutputPaths": ["stderr"],
      "development": false,
      "logToConsole": true
    },
    "service_default": {
      "level": "info",
      "outputPaths": ["service_default.log"],
      "errorOutputPaths": ["service_default_error.log"],
      "development": false,
      "logToConsole": false
    }
  }
}
2. Single Custom Logger Configuration

Create one custom logging configuration file for all services. Each service can reference a specific logger by name in its configuration.

{
  "loggers": {
    "api-services": {
      "level": "info",
      "outputPaths": ["api-services.log"],
      "errorOutputPaths": ["api-errors.log"],
      "development": false,
      "logToConsole": false,
      "logRotation": {
        "enabled": true,
        "maxSizeMB": 50,
        "maxBackups": 10,
        "maxAgeDays": 30,
        "compress": true
      }
    },
    "frontend-services": {
      "level": "debug",
      "outputPaths": ["frontend.log"],
      "errorOutputPaths": ["frontend-errors.log"],
      "development": true,
      "logToConsole": true
    }
  }
}

Use in service configuration:

services:
  - name: backend-api
    log_name: api-services  # References logger name from config
    # ... rest of service config

  - name: frontend
    log_name: frontend-services  # References logger name from config
    # ... rest of service config
3. Separate Logger Configuration Per Service

Create individual log configuration files for each service. Each file must start with the loggers key.

backend-api.log.json:

{
  "loggers": {
    "backend-api": {
      "level": "info",
      "outputPaths": ["backend-api.log"],
      "errorOutputPaths": ["backend-api-error.log"],
      "development": false,
      "logToConsole": false
    }
  }
}

frontend.log.json:

{
  "loggers": {
    "frontend": {
      "level": "debug",
      "outputPaths": ["frontend.log"],
      "errorOutputPaths": ["frontend-error.log"],
      "development": true,
      "logToConsole": true
    }
  }
}
Running Terraster with Different Logging Configurations
# Using default logger
./terraster --config config.yaml

# Using single custom log config
./terraster --config config.yaml --log_configs custom.log.json

# Using separate log configs for each service
./terraster --config config.yaml --log_configs backend-api.log.json,frontend.log.json

# Using default logger and appending additional loggers
./terraster --config config.yaml --log_configs additional.log.json
Important Notes:
  • All log config files must start with the loggers key
  • When using multiple config files, make sure logger names are unique
  • If no log_name is specified in service configuration, the service will use the service_default logger
  • You can append additional loggers to the default configuration by providing them via --log_configs

πŸ› οΈ Admin API Setup

Database Configuration
  1. Create or use the provided API configuration file:
api:
  enabled: true
  host: lb-api.domain.com
  port: 8081
  tls:
    cert_file: "./certs/admin.pem"
    key_file: "./certs/admin_key.key"

database:
  path: "./api.db"

auth:
  jwt_secret: "YourSecretKey"
  token_cleanup_interval: "7h"
  password_expiry_days: 3
  1. Create an admin user:
go run scripts/database/api_util.go --config ./api.config.yaml \
  -username "lb_admin" \
  -password "SecurePassword123" \
  -role "admin"
API Examples
Get Backend Status
curl http://localhost:8081/api/backends \
    -H "Authorization: Bearer ${JWT_TOKEN}" \
    -H "Content-Type: application/json"
Add Backend
curl -X POST http://localhost:8081/api/backends?service_name=backend-api \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${JWT_TOKEN}" \
  -d '{
    "url": "http://newbackend:8080",
    "weight": 5
  }'

🐳 Docker Deployment

Dockerfile
FROM golang:1.21-alpine AS builder

WORKDIR /app
COPY . .
RUN go mod download
RUN go build -o terraster cmd/main.go

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/terraster .
COPY config.yaml .

EXPOSE 8080 8081 9090
CMD ["./terraster", "--config", "config.yaml"]
Docker Compose
version: '3.8'

services:
  terraster:
    build: .
    ports:
      - "8080:8080"
      - "8081:8081"
      - "9090:9090"
    volumes:
      - ./config.yaml:/root/config.yaml
      - ./certs:/etc/certs
    restart: unless-stopped

πŸ“Š Benchmarking

A benchmarking tool is included in the tools/benchmark directory. Run it with:

go run tools/benchmark/main.go -url http://localhost:8080 -c 10 -n 1000

Available flags:

  • -url: Target URL (default: "http://localhost:8080")
  • -c: Number of concurrent requests (default: 10)
  • -n: Total number of requests (default: 1000)
  • -d: Duration of the test (e.g., "30s", "5m")

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

View Source
const (
	RetryKey contextKey = iota
	BackendKey
)

Variables ΒΆ

This section is empty.

Functions ΒΆ

func GetBackendFromContext ΒΆ

func GetBackendFromContext(r *http.Request) string

func GetRetryFromContext ΒΆ

func GetRetryFromContext(r *http.Request) int

func SetBackendInContext ΒΆ

func SetBackendInContext(r *http.Request, backend string) *http.Request

func SetRetryInContext ΒΆ

func SetRetryInContext(r *http.Request) *http.Request

Types ΒΆ

This section is empty.

Directories ΒΆ

Path Synopsis
internal
auth/validation
auth/validation/password.go
auth/validation/password.go
pkg
scripts
database command
tools
benchmark command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL