Files
motovaultpro/K8S-PHASE-1.md
Eric Gullickson 4391cf11ed Architecture Docs
2025-07-28 08:43:00 -05:00

11 KiB

Phase 1: Core Kubernetes Readiness (Weeks 1-4)

This phase focuses on making the application compatible with Kubernetes deployment patterns while maintaining existing functionality.

Overview

The primary goal of Phase 1 is to transform MotoVaultPro from a traditional self-hosted application into a Kubernetes-ready application. This involves removing state dependencies, externalizing configuration, implementing health checks, and modernizing the database architecture.

Key Objectives

  • Configuration Externalization: Move all configuration from files to Kubernetes-native management
  • Database Modernization: Eliminate LiteDB dependency and optimize PostgreSQL usage
  • Health Check Implementation: Add Kubernetes-compatible health check endpoints
  • Logging Enhancement: Implement structured logging for centralized log aggregation

1.1 Configuration Externalization

Objective: Move all configuration from files to Kubernetes-native configuration management.

Current State:

  • Configuration stored in appsettings.json and environment variables
  • Database connection strings in configuration files
  • Feature flags and application settings mixed with deployment configuration

Target State:

  • All configuration externalized to ConfigMaps and Secrets
  • Environment-specific configuration separated from application code
  • Sensitive data (passwords, API keys) managed through Kubernetes Secrets

Implementation Tasks

1. Create ConfigMap templates for non-sensitive configuration

apiVersion: v1
kind: ConfigMap
metadata:
  name: motovault-config
data:
  APP_NAME: "MotoVaultPro"
  LOG_LEVEL: "Information"
  ENABLE_FEATURES: "OpenIDConnect,EmailNotifications"
  CACHE_EXPIRY_MINUTES: "30"

2. Create Secret templates for sensitive configuration

apiVersion: v1
kind: Secret
metadata:
  name: motovault-secrets
type: Opaque
data:
  POSTGRES_CONNECTION: <base64-encoded-connection-string>
  MINIO_ACCESS_KEY: <base64-encoded-access-key>
  MINIO_SECRET_KEY: <base64-encoded-secret-key>
  JWT_SECRET: <base64-encoded-jwt-secret>

3. Modify application startup to read from environment variables

  • Update Program.cs to prioritize environment variables over file configuration
  • Remove dependencies on appsettings.json for runtime configuration
  • Implement configuration validation at startup

4. Remove file-based configuration dependencies

  • Update all services to use IConfiguration instead of direct file access
  • Ensure all configuration is injectable through dependency injection

5. Implement configuration validation at startup

  • Add startup checks to ensure all required configuration is present
  • Fail fast if critical configuration is missing

1.2 Database Architecture Modernization

Objective: Eliminate LiteDB dependency and optimize PostgreSQL usage for Kubernetes.

Current State:

  • Dual database support with LiteDB as default
  • Single PostgreSQL connection for external database mode
  • No connection pooling optimization for multiple instances

Target State:

  • PostgreSQL-only configuration with high availability
  • Optimized connection pooling for horizontal scaling
  • Database migration strategy for existing LiteDB installations

Implementation Tasks

1. Remove LiteDB implementation and dependencies

// Remove all LiteDB-related code from:
// - External/Implementations/LiteDB/
// - Remove LiteDB package references
// - Update dependency injection to only register PostgreSQL implementations

2. Implement PostgreSQL HA configuration

services.AddDbContext<MotoVaultContext>(options =>
{
    options.UseNpgsql(connectionString, npgsqlOptions =>
    {
        npgsqlOptions.EnableRetryOnFailure(
            maxRetryCount: 3,
            maxRetryDelay: TimeSpan.FromSeconds(5),
            errorCodesToAdd: null);
    });
});

3. Add connection pooling configuration

// Configure connection pooling for multiple instances
services.Configure<NpgsqlConnectionStringBuilder>(options =>
{
    options.MaxPoolSize = 100;
    options.MinPoolSize = 10;
    options.ConnectionLifetime = 300; // 5 minutes
});

4. Create data migration tools for LiteDB to PostgreSQL conversion

  • Develop utility to export data from LiteDB format
  • Create import scripts for PostgreSQL
  • Ensure data integrity during migration

5. Implement database health checks for Kubernetes probes

public class DatabaseHealthCheck : IHealthCheck
{
    private readonly IDbContextFactory<MotoVaultContext> _contextFactory;
    
    public async Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, 
        CancellationToken cancellationToken = default)
    {
        try
        {
            using var dbContext = _contextFactory.CreateDbContext();
            await dbContext.Database.CanConnectAsync(cancellationToken);
            return HealthCheckResult.Healthy("Database connection successful");
        }
        catch (Exception ex)
        {
            return HealthCheckResult.Unhealthy("Database connection failed", ex);
        }
    }
}

1.3 Health Check Implementation

Objective: Add Kubernetes-compatible health check endpoints for proper orchestration.

Current State:

  • No dedicated health check endpoints
  • Application startup/shutdown not optimized for Kubernetes

Target State:

  • Comprehensive health checks for all dependencies
  • Proper readiness and liveness probe endpoints
  • Graceful shutdown handling for pod termination

Implementation Tasks

1. Add health check middleware

// Program.cs
builder.Services.AddHealthChecks()
    .AddNpgSql(connectionString, name: "database")
    .AddRedis(redisConnectionString, name: "cache")
    .AddCheck<MinIOHealthCheck>("minio");

app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
    Predicate = check => check.Tags.Contains("ready"),
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});

app.MapHealthChecks("/health/live", new HealthCheckOptions
{
    Predicate = _ => false // Only check if the app is responsive
});

2. Implement custom health checks

public class MinIOHealthCheck : IHealthCheck
{
    private readonly IMinioClient _minioClient;
    
    public async Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context, 
        CancellationToken cancellationToken = default)
    {
        try
        {
            await _minioClient.ListBucketsAsync(cancellationToken);
            return HealthCheckResult.Healthy("MinIO is accessible");
        }
        catch (Exception ex)
        {
            return HealthCheckResult.Unhealthy("MinIO is not accessible", ex);
        }
    }
}

3. Add graceful shutdown handling

builder.Services.Configure<HostOptions>(options =>
{
    options.ShutdownTimeout = TimeSpan.FromSeconds(30);
});

1.4 Logging Enhancement

Objective: Implement structured logging suitable for centralized log aggregation.

Current State:

  • Basic logging with simple string messages
  • No correlation IDs for distributed tracing
  • Log levels not optimized for production monitoring

Target State:

  • JSON-structured logging with correlation IDs
  • Centralized log aggregation compatibility
  • Performance and error metrics embedded in logs

Implementation Tasks

1. Configure structured logging

builder.Services.AddLogging(loggingBuilder =>
{
    loggingBuilder.ClearProviders();
    loggingBuilder.AddJsonConsole(options =>
    {
        options.IncludeScopes = true;
        options.TimestampFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
        options.JsonWriterOptions = new JsonWriterOptions
        {
            Indented = false
        };
    });
});

2. Add correlation ID middleware

public class CorrelationIdMiddleware
{
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        var correlationId = context.Request.Headers["X-Correlation-ID"]
            .FirstOrDefault() ?? Guid.NewGuid().ToString();
        
        using var scope = _logger.BeginScope(new Dictionary<string, object>
        {
            ["CorrelationId"] = correlationId,
            ["UserId"] = context.User?.Identity?.Name
        });
        
        context.Response.Headers.Add("X-Correlation-ID", correlationId);
        await next(context);
    }
}

3. Implement performance logging for critical operations

  • Add timing information to database operations
  • Log request/response metrics
  • Include user context in all log entries

Week-by-Week Breakdown

Week 1: Environment Setup and Configuration

  • Days 1-2: Set up development Kubernetes environment
  • Days 3-4: Create ConfigMap and Secret templates
  • Days 5-7: Modify application to read from environment variables

Week 2: Database Migration

  • Days 1-3: Remove LiteDB dependencies
  • Days 4-5: Implement PostgreSQL connection pooling
  • Days 6-7: Create data migration utilities

Week 3: Health Checks and Monitoring

  • Days 1-3: Implement health check endpoints
  • Days 4-5: Add custom health checks for dependencies
  • Days 6-7: Test health check functionality

Week 4: Logging and Documentation

  • Days 1-3: Implement structured logging
  • Days 4-5: Add correlation ID middleware
  • Days 6-7: Document changes and prepare for Phase 2

Success Criteria

  • Application starts successfully using only environment variables
  • All LiteDB dependencies removed
  • PostgreSQL connection pooling configured and tested
  • Health check endpoints return appropriate status
  • Structured JSON logging implemented
  • Data migration tool successfully converts LiteDB to PostgreSQL
  • Application can be deployed to Kubernetes without file dependencies

Testing Requirements

Unit Tests

  • Configuration validation logic
  • Health check implementations
  • Database connection handling

Integration Tests

  • End-to-end application startup with external configuration
  • Database connectivity and migration
  • Health check endpoint responses

Manual Testing

  • Deploy to development Kubernetes cluster
  • Verify all functionality works without local file dependencies
  • Test health check endpoints with kubectl

Deliverables

  1. Updated Application Code

    • Removed LiteDB dependencies
    • Externalized configuration
    • Added health checks
    • Implemented structured logging
  2. Kubernetes Manifests

    • ConfigMap templates
    • Secret templates
    • Basic deployment configuration for testing
  3. Migration Tools

    • LiteDB to PostgreSQL data migration utility
    • Configuration migration scripts
  4. Documentation

    • Updated deployment instructions
    • Configuration reference
    • Health check endpoint documentation

Dependencies

  • Kubernetes cluster (development environment)
  • PostgreSQL instance for testing
  • Docker registry for container images

Risks and Mitigations

Risk: Data Loss During Migration

Mitigation: Comprehensive backup strategy and thorough testing of migration tools

Risk: Configuration Errors

Mitigation: Configuration validation at startup and extensive testing

Risk: Performance Degradation

Mitigation: Performance testing and gradual rollout with monitoring


Next Phase: Phase 2: High Availability Infrastructure